From 14a0822095adf2c497479a84d6dad7b6e633b511 Mon Sep 17 00:00:00 2001 From: kadami Date: Fri, 26 Apr 2024 15:58:48 +0700 Subject: [PATCH 001/278] add endpoint for pdf cover page generation --- desci-media-isolated/src/config/index.ts | 2 + .../src/controllers/pdf/createCover.ts | 55 +++++++++++++++++++ desci-media-isolated/src/routes/v1/pdf.ts | 8 +++ 3 files changed, 65 insertions(+) create mode 100644 desci-media-isolated/src/controllers/pdf/createCover.ts create mode 100644 desci-media-isolated/src/routes/v1/pdf.ts diff --git a/desci-media-isolated/src/config/index.ts b/desci-media-isolated/src/config/index.ts index 46ac0834..7263d356 100644 --- a/desci-media-isolated/src/config/index.ts +++ b/desci-media-isolated/src/config/index.ts @@ -1,4 +1,6 @@ export const IPFS_GATEWAY = process.env.IPFS_GATEWAY; export const TEMP_DIR = '.temp'; export const THUMBNAIL_FILES_DIR = `/files`; +export const PDF_FILES_DIR = `/files/pdf`; export const THUMBNAIL_OUTPUT_DIR = `/thumbnails`; +export const PDF_OUTPUT_DIR = `/thumbnails`; diff --git a/desci-media-isolated/src/controllers/pdf/createCover.ts b/desci-media-isolated/src/controllers/pdf/createCover.ts new file mode 100644 index 00000000..515f7b92 --- /dev/null +++ b/desci-media-isolated/src/controllers/pdf/createCover.ts @@ -0,0 +1,55 @@ +import type { Request, Response } from 'express'; +import path from 'path'; +import { fileURLToPath } from 'url'; +import fs from 'fs'; +import { PDF_OUTPUT_DIR, TEMP_DIR } from '../../config/index.js'; +import { BadRequestError, NotFoundError } from '../../utils/customErrors.js'; +import { PdfManipulationService } from '../../services/pdf.js'; + +export type GeneratePdfCoverRequestBody = { + cid: string; + doi: string; + title: string; + dpid?: string; +}; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const BASE_TEMP_DIR = path.resolve(__dirname, '../../..', TEMP_DIR); + +/** + * Generates a cover page inserting a DOI and a DPID link for a PDF file provided via its CID + */ +export const generatePdfCover = async ( + req: Request, + res: Response, +) => { + const { cid, doi, dpid, title } = req.body; + const { header = true, headerAllPages = false } = req.query; + if (!cid) throw new BadRequestError('Missing cid in request body'); + if (!doi) throw new BadRequestError('Missing doi in request body'); + if (!doi) throw new BadRequestError('Missing title in request body'); + + const generationTaskId = crypto.randomUUID(); + + try { + const pdfPath = await PdfManipulationService.addPdfCover({ taskId: generationTaskId, cid, doi, dpid, title }); + const fullPdfPath = path.join(BASE_TEMP_DIR, PDF_OUTPUT_DIR, pdfPath); + + // Check if the file exists before attempting to stream it + fs.access(fullPdfPath, fs.constants.F_OK, (err) => { + if (err) { + throw new NotFoundError(`PDF not found for file with path: ${cid}`); + } + + res.setHeader('Content-Type', 'application/pdf'); + const readStream = fs.createReadStream(fullPdfPath); + + readStream.pipe(res); + }); + + return res.status(200); + } catch (err: any) { + return res.status(500).json({ message: err.message }); + } +}; diff --git a/desci-media-isolated/src/routes/v1/pdf.ts b/desci-media-isolated/src/routes/v1/pdf.ts new file mode 100644 index 00000000..c01e903a --- /dev/null +++ b/desci-media-isolated/src/routes/v1/pdf.ts @@ -0,0 +1,8 @@ +import { Router } from 'express'; +import { generatePdfCover } from '../../controllers/pdf/createCover.js'; + +const router = Router(); + +router.post('/addCover', generatePdfCover); + +export default router; From 608934eca66d229dab2d76570de3b91eda82e6a7 Mon Sep 17 00:00:00 2001 From: kadami Date: Fri, 26 Apr 2024 15:59:21 +0700 Subject: [PATCH 002/278] add pdf manipulation service, WIP cover page generation functionality --- desci-media-isolated/package-lock.json | 38 +++++++++++ desci-media-isolated/package.json | 1 + desci-media-isolated/src/services/pdf.ts | 80 ++++++++++++++++++++++++ desci-media-isolated/src/utils/utils.ts | 6 ++ 4 files changed, 125 insertions(+) create mode 100644 desci-media-isolated/src/services/pdf.ts create mode 100644 desci-media-isolated/src/utils/utils.ts diff --git a/desci-media-isolated/package-lock.json b/desci-media-isolated/package-lock.json index 551d9f75..13596caa 100644 --- a/desci-media-isolated/package-lock.json +++ b/desci-media-isolated/package-lock.json @@ -13,6 +13,7 @@ "express": "^4.18.2", "filepreview_ts": "^1.0.0", "helmet": "^7.1.0", + "pdf-lib": "^1.17.1", "tsx": "^4.7.1" }, "devDependencies": { @@ -267,6 +268,22 @@ "node": ">= 8" } }, + "node_modules/@pdf-lib/standard-fonts": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@pdf-lib/standard-fonts/-/standard-fonts-1.0.0.tgz", + "integrity": "sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA==", + "dependencies": { + "pako": "^1.0.6" + } + }, + "node_modules/@pdf-lib/upng": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@pdf-lib/upng/-/upng-1.0.1.tgz", + "integrity": "sha512-dQK2FUMQtowVP00mtIksrlZhdFXQZPC+taih1q4CvPZ5vqdxR/LKBaFg0oAfzd1GlHZXXSPdQfzQnt+ViGvEIQ==", + "dependencies": { + "pako": "^1.0.10" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -2325,6 +2342,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -2392,6 +2414,17 @@ "node": ">=8" } }, + "node_modules/pdf-lib": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/pdf-lib/-/pdf-lib-1.17.1.tgz", + "integrity": "sha512-V/mpyJAoTsN4cnP31vc0wfNA1+p20evqqnap0KLoRUN0Yk/p3wN52DOEsL4oBFcLdb76hlpKPtzJIgo67j/XLw==", + "dependencies": { + "@pdf-lib/standard-fonts": "^1.0.0", + "@pdf-lib/upng": "^1.0.1", + "pako": "^1.0.11", + "tslib": "^1.11.1" + } + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -2952,6 +2985,11 @@ "strip-json-comments": "^2.0.0" } }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, "node_modules/tsx": { "version": "4.7.1", "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.1.tgz", diff --git a/desci-media-isolated/package.json b/desci-media-isolated/package.json index 75d956db..1da04348 100644 --- a/desci-media-isolated/package.json +++ b/desci-media-isolated/package.json @@ -17,6 +17,7 @@ "express": "^4.18.2", "filepreview_ts": "^1.0.0", "helmet": "^7.1.0", + "pdf-lib": "^1.17.1", "tsx": "^4.7.1" }, "devDependencies": { diff --git a/desci-media-isolated/src/services/pdf.ts b/desci-media-isolated/src/services/pdf.ts new file mode 100644 index 00000000..85000348 --- /dev/null +++ b/desci-media-isolated/src/services/pdf.ts @@ -0,0 +1,80 @@ +import { PDF_FILES_DIR, PDF_OUTPUT_DIR, TEMP_DIR } from '../config/index.js'; +import { IpfsService } from './ipfs.js'; +import { UnhandledError } from '../utils/customErrors.js'; +import path from 'path'; +import fs from 'fs'; +import * as fsp from 'fs/promises'; +import { fileURLToPath } from 'url'; +import { PDFDocument, StandardFonts } from 'pdf-lib'; +import { readFileToBuffer } from '../utils/utils.js'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const BASE_TEMP_DIR = path.resolve(__dirname, '../..', TEMP_DIR); + +export enum PDF_JOB_TYPE { + ADD_COVER = 'cover', +} + +export interface AddPdfCoverParams { + taskId: string; + cid: string; + title: string; + doi: string; + dpid?: string; +} + +export class PdfManipulationService { + static async addPdfCover({ taskId, cid, title, doi, dpid }: AddPdfCoverParams) { + const tempFilePath = path.join(BASE_TEMP_DIR, PDF_FILES_DIR, `${taskId}.pdf`); // Saved pdf to manipulate + const outputPdfFileName = this.getPdfPath(PDF_JOB_TYPE.ADD_COVER, cid); + const outputFullPath = path.join(BASE_TEMP_DIR, PDF_OUTPUT_DIR, outputPdfFileName); + // debugger; + await IpfsService.saveFile(cid, tempFilePath); + try { + // Proccess the pdf file to add the cover page + const pdfBytes = await readFileToBuffer(tempFilePath); + const pdfDoc = await PDFDocument.load(pdfBytes); + const helveticaFont = await pdfDoc.embedFont(StandardFonts.Helvetica); + + const newPage = pdfDoc.insertPage(0); + const { width, height } = newPage.getSize(); + + const topHeader = `DOI ${doi} all code and data is available here`; + + newPage.drawText(topHeader, { + x: 10, + y: 5, + size: 12, + }); + + const pdfBytesMod = await pdfDoc.save(); + await fsp.writeFile(outputFullPath, pdfBytesMod); + + console.log('Cover page generated successfully:', outputFullPath); + return outputPdfFileName; + } catch (e) { + console.error(e); + throw new UnhandledError( + `Failed generating cover page for file with cid: ${cid}, with temp file path: ${tempFilePath}`, + ); + } finally { + // The initially saved file is removed, however the generated pdf remains. Further cleanup can be done for the generated pdf result. + try { + await fs.unlink(tempFilePath, (err) => { + if (err) { + console.error(err, `Failed to cleanup temporary file: ${tempFilePath}`); + return; + } + console.log(`Temporary file ${tempFilePath} deleted successfully.`); + }); + } catch (cleanupError) { + console.error(`Failed to delete temporary file ${tempFilePath}:`, cleanupError); + } + } + } + + static getPdfPath(jobType: PDF_JOB_TYPE, generationTaskId: string) { + return `${jobType}-${generationTaskId}.pdf`; + } +} diff --git a/desci-media-isolated/src/utils/utils.ts b/desci-media-isolated/src/utils/utils.ts new file mode 100644 index 00000000..37e9ede8 --- /dev/null +++ b/desci-media-isolated/src/utils/utils.ts @@ -0,0 +1,6 @@ +import fs from 'fs/promises'; + +export async function readFileToBuffer(filePath: string) { + const fileBuffer = await fs.readFile(filePath); + return fileBuffer; +} From 4c1172859afb23223246e1ec1668b043507da53d Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Mon, 6 May 2024 09:54:03 +0000 Subject: [PATCH 003/278] modify script to always install packages incase of changes --- desci-media-isolated/scripts/containerInitDev.sh | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/desci-media-isolated/scripts/containerInitDev.sh b/desci-media-isolated/scripts/containerInitDev.sh index 904d8662..237ad751 100755 --- a/desci-media-isolated/scripts/containerInitDev.sh +++ b/desci-media-isolated/scripts/containerInitDev.sh @@ -9,12 +9,10 @@ fi mkdir -p /usr/src/app/.temp/files /usr/src/app/.temp/thumbnails -# Check if node_modules directory doesn't exist and run npm install if necessary -if [ ! -d "/usr/src/app/node_modules" ]; then - echo "node_modules not found, running npm install..." - cd /usr/src/app - npm install -fi +echo "Running npm install to install any package changes..." +cd /usr/src/app +npm install + # Execute the main container command exec "$@" From ba9d077012763b8c742cb71674dfa41fd4ee75c7 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Mon, 6 May 2024 10:22:38 +0000 Subject: [PATCH 004/278] clear up bugs, fix body check handling --- .../src/controllers/pdf/createCover.ts | 11 ++++++----- desci-media-isolated/src/routes/v1/index.ts | 2 ++ desci-media-isolated/src/services/pdf.ts | 5 +++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/desci-media-isolated/src/controllers/pdf/createCover.ts b/desci-media-isolated/src/controllers/pdf/createCover.ts index 515f7b92..5aab49e2 100644 --- a/desci-media-isolated/src/controllers/pdf/createCover.ts +++ b/desci-media-isolated/src/controllers/pdf/createCover.ts @@ -26,13 +26,14 @@ export const generatePdfCover = async ( ) => { const { cid, doi, dpid, title } = req.body; const { header = true, headerAllPages = false } = req.query; - if (!cid) throw new BadRequestError('Missing cid in request body'); - if (!doi) throw new BadRequestError('Missing doi in request body'); - if (!doi) throw new BadRequestError('Missing title in request body'); + debugger; + try { + if (!cid) throw new BadRequestError('Missing cid in request body'); + if (!doi) throw new BadRequestError('Missing doi in request body'); + if (!title) throw new BadRequestError('Missing title in request body'); - const generationTaskId = crypto.randomUUID(); + const generationTaskId = crypto.randomUUID(); - try { const pdfPath = await PdfManipulationService.addPdfCover({ taskId: generationTaskId, cid, doi, dpid, title }); const fullPdfPath = path.join(BASE_TEMP_DIR, PDF_OUTPUT_DIR, pdfPath); diff --git a/desci-media-isolated/src/routes/v1/index.ts b/desci-media-isolated/src/routes/v1/index.ts index f07481a4..07615e19 100644 --- a/desci-media-isolated/src/routes/v1/index.ts +++ b/desci-media-isolated/src/routes/v1/index.ts @@ -1,8 +1,10 @@ import { Router } from 'express'; import thumbnails from './thumbnails.js'; +import pdf from './pdf.js'; const router = Router(); router.use('/thumbnails', thumbnails); +router.use('/pdf', pdf); export default router; diff --git a/desci-media-isolated/src/services/pdf.ts b/desci-media-isolated/src/services/pdf.ts index 85000348..4aebd85f 100644 --- a/desci-media-isolated/src/services/pdf.ts +++ b/desci-media-isolated/src/services/pdf.ts @@ -29,8 +29,9 @@ export class PdfManipulationService { const tempFilePath = path.join(BASE_TEMP_DIR, PDF_FILES_DIR, `${taskId}.pdf`); // Saved pdf to manipulate const outputPdfFileName = this.getPdfPath(PDF_JOB_TYPE.ADD_COVER, cid); const outputFullPath = path.join(BASE_TEMP_DIR, PDF_OUTPUT_DIR, outputPdfFileName); - // debugger; - await IpfsService.saveFile(cid, tempFilePath); + debugger; + await IpfsService.saveFile(cid, tempFilePath); //failing + debugger; try { // Proccess the pdf file to add the cover page const pdfBytes = await readFileToBuffer(tempFilePath); From 6178d5ff0c2701b614def93651258e6b8bb61323 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Mon, 6 May 2024 15:51:25 +0000 Subject: [PATCH 005/278] configuration fixes, pdf cover generation debugged and functional --- desci-media-isolated/Dockerfile | 1 + desci-media-isolated/scripts/containerInitDev.sh | 2 +- desci-media-isolated/src/config/index.ts | 2 +- desci-media-isolated/src/controllers/pdf/createCover.ts | 1 - desci-media-isolated/src/services/ipfs.ts | 7 +++---- docker-compose.dev.yml | 5 ++++- 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/desci-media-isolated/Dockerfile b/desci-media-isolated/Dockerfile index 49d31968..35779547 100644 --- a/desci-media-isolated/Dockerfile +++ b/desci-media-isolated/Dockerfile @@ -25,6 +25,7 @@ RUN --mount=type=cache,target=/usr/src/app/.npm \ COPY . . + # Expose debugger port EXPOSE 9777 diff --git a/desci-media-isolated/scripts/containerInitDev.sh b/desci-media-isolated/scripts/containerInitDev.sh index 237ad751..6703e7da 100755 --- a/desci-media-isolated/scripts/containerInitDev.sh +++ b/desci-media-isolated/scripts/containerInitDev.sh @@ -6,7 +6,7 @@ if [ ! -f /usr/src/app/.env ]; then fi # Ensure temp directories exist -mkdir -p /usr/src/app/.temp/files /usr/src/app/.temp/thumbnails +mkdir -p /usr/src/app/.temp/files /usr/src/app/.temp/thumbnails /usr/src/app/.temp/files/pdf /usr/src/app/.temp/pdf echo "Running npm install to install any package changes..." diff --git a/desci-media-isolated/src/config/index.ts b/desci-media-isolated/src/config/index.ts index 7263d356..818e0552 100644 --- a/desci-media-isolated/src/config/index.ts +++ b/desci-media-isolated/src/config/index.ts @@ -3,4 +3,4 @@ export const TEMP_DIR = '.temp'; export const THUMBNAIL_FILES_DIR = `/files`; export const PDF_FILES_DIR = `/files/pdf`; export const THUMBNAIL_OUTPUT_DIR = `/thumbnails`; -export const PDF_OUTPUT_DIR = `/thumbnails`; +export const PDF_OUTPUT_DIR = `/pdf`; diff --git a/desci-media-isolated/src/controllers/pdf/createCover.ts b/desci-media-isolated/src/controllers/pdf/createCover.ts index 5aab49e2..9ba04a69 100644 --- a/desci-media-isolated/src/controllers/pdf/createCover.ts +++ b/desci-media-isolated/src/controllers/pdf/createCover.ts @@ -26,7 +26,6 @@ export const generatePdfCover = async ( ) => { const { cid, doi, dpid, title } = req.body; const { header = true, headerAllPages = false } = req.query; - debugger; try { if (!cid) throw new BadRequestError('Missing cid in request body'); if (!doi) throw new BadRequestError('Missing doi in request body'); diff --git a/desci-media-isolated/src/services/ipfs.ts b/desci-media-isolated/src/services/ipfs.ts index e8ee8a96..fcc0eeec 100644 --- a/desci-media-isolated/src/services/ipfs.ts +++ b/desci-media-isolated/src/services/ipfs.ts @@ -1,7 +1,7 @@ import axios from 'axios'; import fs from 'fs'; import { pipeline } from 'stream/promises'; -import { IpfsConfigurationError } from '../utils/customErrors.js'; +import { IpfsConfigurationError, IpfsFetchError } from '../utils/customErrors.js'; const IPFS_GATEWAY = process.env.IPFS_GATEWAY; export class IpfsService { @@ -10,9 +10,8 @@ export class IpfsService { console.log('IPFS_GATEWAY:', process.env.IPFS_GATEWAY); throw new IpfsConfigurationError('process.env.IPFS_GATEWAY is not defined in environment variables'); } - // debugger; const url = `${IPFS_GATEWAY}/${cid}`; - + debugger; try { const response = await axios({ method: 'get', @@ -26,7 +25,7 @@ export class IpfsService { console.log(`File downloaded and saved to ${outputPath}`); } catch (error) { console.error('Error downloading or saving the file:', error); - throw error; + throw new IpfsFetchError(`Error downloading or saving the file: ${cid}`); } } } diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index a3d5e176..064418bd 100755 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -203,11 +203,14 @@ services: context: ./desci-media-isolated target: dev container_name: "media_isolated" + extra_hosts: + - host.docker.internal:host-gateway volumes: - ./desci-media-isolated:/usr/src/app ports: - "9777:9777" # debugger - # - "7771:7771" # Uncomment if you want to test the media server from the host machine + - "7771:7771" # Uncomment if you want to test the media server from the host machine + # desci_nodes_backend_test: # container_name: 'be_test_boilerplate' From bc60eb945485c207e78e0b21da04dc7c38165333 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Mon, 6 May 2024 19:22:34 +0000 Subject: [PATCH 006/278] layout sketch, added helper for centered multiline text --- desci-media-isolated/src/services/pdf.ts | 72 ++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 5 deletions(-) diff --git a/desci-media-isolated/src/services/pdf.ts b/desci-media-isolated/src/services/pdf.ts index 4aebd85f..b67ecc7b 100644 --- a/desci-media-isolated/src/services/pdf.ts +++ b/desci-media-isolated/src/services/pdf.ts @@ -5,7 +5,7 @@ import path from 'path'; import fs from 'fs'; import * as fsp from 'fs/promises'; import { fileURLToPath } from 'url'; -import { PDFDocument, StandardFonts } from 'pdf-lib'; +import { PDFDocument, PDFFont, PDFPage, StandardFonts } from 'pdf-lib'; import { readFileToBuffer } from '../utils/utils.js'; const __filename = fileURLToPath(import.meta.url); @@ -29,9 +29,9 @@ export class PdfManipulationService { const tempFilePath = path.join(BASE_TEMP_DIR, PDF_FILES_DIR, `${taskId}.pdf`); // Saved pdf to manipulate const outputPdfFileName = this.getPdfPath(PDF_JOB_TYPE.ADD_COVER, cid); const outputFullPath = path.join(BASE_TEMP_DIR, PDF_OUTPUT_DIR, outputPdfFileName); - debugger; + // debugger; await IpfsService.saveFile(cid, tempFilePath); //failing - debugger; + // debugger; try { // Proccess the pdf file to add the cover page const pdfBytes = await readFileToBuffer(tempFilePath); @@ -41,14 +41,33 @@ export class PdfManipulationService { const newPage = pdfDoc.insertPage(0); const { width, height } = newPage.getSize(); + /* + * Header + */ const topHeader = `DOI ${doi} all code and data is available here`; - + const headerSize = 12; newPage.drawText(topHeader, { x: 10, - y: 5, + y: height - 20, size: 12, }); + /* + * Title + */ + const titleSize = 30; + // const textWidth = helveticaFont.widthOfTextAtSize(title, titleSize); + // const textHeight = helveticaFont.heightAtSize(titleSize); + + // newPage.drawText(title, { + // x: (width - textWidth) / 2, + // y: height / 2 + textHeight / 2, + // size: titleSize, + // font: helveticaFont, + // }); + + this.drawCenteredMultilineText(newPage, title, helveticaFont, titleSize, width, height); + const pdfBytesMod = await pdfDoc.save(); await fsp.writeFile(outputFullPath, pdfBytesMod); @@ -78,4 +97,47 @@ export class PdfManipulationService { static getPdfPath(jobType: PDF_JOB_TYPE, generationTaskId: string) { return `${jobType}-${generationTaskId}.pdf`; } + + static drawCenteredMultilineText( + page: PDFPage, + text: string, + font: PDFFont, + fontSize: number, + width: number, + height: number, + ): void { + const lines: string[] = []; + const words = text.split(' '); + let currentLine = ''; + + for (let i = 0; i < words.length; i++) { + const word = words[i]; + const prospectiveLine = currentLine ? currentLine + ' ' + word : word; + const prospectiveLineWidth: number = font.widthOfTextAtSize(prospectiveLine, fontSize); + + if (prospectiveLineWidth <= width) { + currentLine = prospectiveLine; + } else { + lines.push(currentLine); + currentLine = word; + } + } + + if (currentLine) { + lines.push(currentLine); + } + + const textHeight = font.heightAtSize(fontSize); + const totalHeight = lines.length * textHeight; + const startY = (height - totalHeight) / 2; + + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + const lineWidth = font.widthOfTextAtSize(line, fontSize); + const x = (width - lineWidth) / 2; + const y = startY + i * textHeight; + + page.drawText(line, { x, y, size: fontSize, font }); + } + } } From dba7f5424f13a09e299d7347281ca34d7eab5125 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Tue, 7 May 2024 09:40:29 +0000 Subject: [PATCH 007/278] add padding-x to helper, fix line ordering --- desci-media-isolated/src/services/pdf.ts | 49 +++++++++++++++++------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/desci-media-isolated/src/services/pdf.ts b/desci-media-isolated/src/services/pdf.ts index b67ecc7b..feb80a2d 100644 --- a/desci-media-isolated/src/services/pdf.ts +++ b/desci-media-isolated/src/services/pdf.ts @@ -24,6 +24,16 @@ export interface AddPdfCoverParams { dpid?: string; } +export interface DrawCenteredHelperParams { + page: PDFPage; + text: string; + font: PDFFont; + fontSize: number; + width: number; + height: number; + paddingX?: number; +} + export class PdfManipulationService { static async addPdfCover({ taskId, cid, title, doi, dpid }: AddPdfCoverParams) { const tempFilePath = path.join(BASE_TEMP_DIR, PDF_FILES_DIR, `${taskId}.pdf`); // Saved pdf to manipulate @@ -66,7 +76,15 @@ export class PdfManipulationService { // font: helveticaFont, // }); - this.drawCenteredMultilineText(newPage, title, helveticaFont, titleSize, width, height); + this.drawCenteredMultilineText({ + page: newPage, + text: title, + font: helveticaFont, + fontSize: titleSize, + width, + height, + paddingX: 20, + }); const pdfBytesMod = await pdfDoc.save(); await fsp.writeFile(outputFullPath, pdfBytesMod); @@ -98,43 +116,46 @@ export class PdfManipulationService { return `${jobType}-${generationTaskId}.pdf`; } - static drawCenteredMultilineText( - page: PDFPage, - text: string, - font: PDFFont, - fontSize: number, - width: number, - height: number, - ): void { + static drawCenteredMultilineText({ + page, + text, + font, + fontSize, + width, + height, + paddingX = 0, + }: DrawCenteredHelperParams): void { const lines: string[] = []; const words = text.split(' '); let currentLine = ''; + const availableWidth = width - 2 * paddingX; + for (let i = 0; i < words.length; i++) { const word = words[i]; const prospectiveLine = currentLine ? currentLine + ' ' + word : word; const prospectiveLineWidth: number = font.widthOfTextAtSize(prospectiveLine, fontSize); - if (prospectiveLineWidth <= width) { + if (prospectiveLineWidth <= availableWidth) { currentLine = prospectiveLine; } else { - lines.push(currentLine); + lines.unshift(currentLine); currentLine = word; } } if (currentLine) { - lines.push(currentLine); + lines.unshift(currentLine); } const textHeight = font.heightAtSize(fontSize); const totalHeight = lines.length * textHeight; - const startY = (height - totalHeight) / 2; + const startY = height / 2 - totalHeight / 2; for (let i = 0; i < lines.length; i++) { const line = lines[i]; const lineWidth = font.widthOfTextAtSize(line, fontSize); - const x = (width - lineWidth) / 2; + const x = paddingX + (availableWidth - lineWidth) / 2; const y = startY + i * textHeight; page.drawText(line, { x, y, size: fontSize, font }); From 790370501373d59c0de60ba39276677ed11421d9 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Tue, 7 May 2024 10:06:11 +0000 Subject: [PATCH 008/278] add y-axis positioning to helper --- desci-media-isolated/src/services/pdf.ts | 28 ++++++++++++------------ 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/desci-media-isolated/src/services/pdf.ts b/desci-media-isolated/src/services/pdf.ts index feb80a2d..ec41c077 100644 --- a/desci-media-isolated/src/services/pdf.ts +++ b/desci-media-isolated/src/services/pdf.ts @@ -32,6 +32,7 @@ export interface DrawCenteredHelperParams { width: number; height: number; paddingX?: number; + positionY?: number; // 0-1, vertical alignment, e.g. 0.5 is the center. } export class PdfManipulationService { @@ -56,25 +57,22 @@ export class PdfManipulationService { */ const topHeader = `DOI ${doi} all code and data is available here`; const headerSize = 12; - newPage.drawText(topHeader, { - x: 10, - y: height - 20, - size: 12, + + this.drawCenteredMultilineText({ + page: newPage, + text: topHeader, + font: helveticaFont, + fontSize: headerSize, + width, + height, + paddingX: 5, + positionY: 0.01, }); /* * Title */ const titleSize = 30; - // const textWidth = helveticaFont.widthOfTextAtSize(title, titleSize); - // const textHeight = helveticaFont.heightAtSize(titleSize); - - // newPage.drawText(title, { - // x: (width - textWidth) / 2, - // y: height / 2 + textHeight / 2, - // size: titleSize, - // font: helveticaFont, - // }); this.drawCenteredMultilineText({ page: newPage, @@ -124,7 +122,9 @@ export class PdfManipulationService { width, height, paddingX = 0, + positionY = 0.5, }: DrawCenteredHelperParams): void { + // debugger const lines: string[] = []; const words = text.split(' '); let currentLine = ''; @@ -150,7 +150,7 @@ export class PdfManipulationService { const textHeight = font.heightAtSize(fontSize); const totalHeight = lines.length * textHeight; - const startY = height / 2 - totalHeight / 2; + const startY = height * (1 - positionY) - totalHeight / 2; for (let i = 0; i < lines.length; i++) { const line = lines[i]; From 1dd720a22a4c55d4b19d04448e008edc173db9a9 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Tue, 7 May 2024 10:41:11 +0000 Subject: [PATCH 009/278] add image rendering helper, add attestation badges to cover gen template --- .../public/static/code-available.png | Bin 0 -> 7895 bytes .../public/static/data-available.png | Bin 0 -> 7425 bytes desci-media-isolated/src/services/pdf.ts | 105 +++++++++++++++++- 3 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 desci-media-isolated/public/static/code-available.png create mode 100644 desci-media-isolated/public/static/data-available.png diff --git a/desci-media-isolated/public/static/code-available.png b/desci-media-isolated/public/static/code-available.png new file mode 100644 index 0000000000000000000000000000000000000000..47af5823bcb976fdd89055d7f2ea954657d1d30a GIT binary patch literal 7895 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 literal 0 HcmV?d00001 diff --git a/desci-media-isolated/src/services/pdf.ts b/desci-media-isolated/src/services/pdf.ts index ec41c077..e97bb941 100644 --- a/desci-media-isolated/src/services/pdf.ts +++ b/desci-media-isolated/src/services/pdf.ts @@ -5,7 +5,7 @@ import path from 'path'; import fs from 'fs'; import * as fsp from 'fs/promises'; import { fileURLToPath } from 'url'; -import { PDFDocument, PDFFont, PDFPage, StandardFonts } from 'pdf-lib'; +import { PDFDocument, PDFFont, PDFImage, PDFPage, StandardFonts } from 'pdf-lib'; import { readFileToBuffer } from '../utils/utils.js'; const __filename = fileURLToPath(import.meta.url); @@ -35,6 +35,21 @@ export interface DrawCenteredHelperParams { positionY?: number; // 0-1, vertical alignment, e.g. 0.5 is the center. } +interface PdfImageObject { + content: PDFImage; + width: number; + height: number; +} +export interface DrawCenteredImagesParams { + page: PDFPage; + images: PdfImageObject[]; + pageWidth: number; + pageHeight: number; + paddingX?: number; + gap?: number; // Gap between images if multiple are passed into the array. + positionY?: number; // 0-1, vertical alignment, e.g. 0.5 is the center. +} + export class PdfManipulationService { static async addPdfCover({ taskId, cid, title, doi, dpid }: AddPdfCoverParams) { const tempFilePath = path.join(BASE_TEMP_DIR, PDF_FILES_DIR, `${taskId}.pdf`); // Saved pdf to manipulate @@ -84,6 +99,35 @@ export class PdfManipulationService { paddingX: 20, }); + /* + * Badges + */ + const codeBadgeBytes = await pdfDoc.embedPng( + await readFileToBuffer(path.join(__dirname, '../../public/static/code-available.png')), + ); + const dataBadgeBytes = await pdfDoc.embedPng( + await readFileToBuffer(path.join(__dirname, '../../public/static/data-available.png')), + ); + const codeBadge: PdfImageObject = { + content: codeBadgeBytes, + width: 125, + height: 125, + }; + const dataBadge: PdfImageObject = { + content: dataBadgeBytes, + width: 125, + height: 125, + }; + + this.drawCenteredImages({ + page: newPage, + images: [codeBadge, dataBadge], + pageWidth: width, + pageHeight: height, + positionY: 0.75, + gap: 20, + }); + const pdfBytesMod = await pdfDoc.save(); await fsp.writeFile(outputFullPath, pdfBytesMod); @@ -161,4 +205,63 @@ export class PdfManipulationService { page.drawText(line, { x, y, size: fontSize, font }); } } + + static drawCenteredImages({ + page, + images, + pageWidth, + pageHeight, + paddingX = 0, + gap = 0, + positionY = 0.5, + }: DrawCenteredImagesParams): void { + const availableWidth = pageWidth - 2 * paddingX; + + const rows: PdfImageObject[][] = []; + let currentRow: PdfImageObject[] = []; + let currentRowWidth = 0; + + for (const image of images) { + if (currentRowWidth + image.width + (currentRow.length > 0 ? gap : 0) > availableWidth) { + rows.push(currentRow); + currentRow = []; + currentRowWidth = 0; + } + currentRow.push(image); + currentRowWidth += image.width + (currentRow.length > 1 ? gap : 0); + } + + if (currentRow.length > 0) { + rows.push(currentRow); + } + + const rowHeights = rows.map((row) => Math.max(...row.map((image) => image.height))); + const totalHeight = rowHeights.reduce((sum, height) => sum + height, 0) + (rows.length - 1) * gap; + const startY = pageHeight * (1 - positionY) - totalHeight / 2; + + let currentY = startY; + + for (const row of rows) { + const rowWidth = row.reduce((sum, image) => sum + image.width, 0) + (row.length - 1) * gap; + let currentX = paddingX + (availableWidth - rowWidth) / 2; + + const rowHeight = Math.max(...row.map((image) => image.height)); + + for (const image of row) { + const x = currentX; + const y = currentY + (rowHeight - image.height) / 2; + + page.drawImage(image.content, { + x, + y, + width: image.width, + height: image.height, + }); + + currentX += image.width + gap; + } + + currentY += rowHeight + gap; + } + } } From 54556e47d56a318c8ab160a0c99f66696de2b6df Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Tue, 7 May 2024 18:19:18 +0000 Subject: [PATCH 010/278] add hyperlinking functionality to text and image helpers --- desci-media-isolated/src/services/pdf.ts | 63 +++++++++++++++++++++--- 1 file changed, 57 insertions(+), 6 deletions(-) diff --git a/desci-media-isolated/src/services/pdf.ts b/desci-media-isolated/src/services/pdf.ts index e97bb941..dcb0193c 100644 --- a/desci-media-isolated/src/services/pdf.ts +++ b/desci-media-isolated/src/services/pdf.ts @@ -5,7 +5,7 @@ import path from 'path'; import fs from 'fs'; import * as fsp from 'fs/promises'; import { fileURLToPath } from 'url'; -import { PDFDocument, PDFFont, PDFImage, PDFPage, StandardFonts } from 'pdf-lib'; +import { PDFArray, PDFDict, PDFDocument, PDFFont, PDFImage, PDFName, PDFPage, PDFString, StandardFonts } from 'pdf-lib'; import { readFileToBuffer } from '../utils/utils.js'; const __filename = fileURLToPath(import.meta.url); @@ -33,12 +33,14 @@ export interface DrawCenteredHelperParams { height: number; paddingX?: number; positionY?: number; // 0-1, vertical alignment, e.g. 0.5 is the center. + hyperlink?: string; } interface PdfImageObject { content: PDFImage; width: number; height: number; + hyperlink?: string; } export interface DrawCenteredImagesParams { page: PDFPage; @@ -82,6 +84,7 @@ export class PdfManipulationService { height, paddingX: 5, positionY: 0.01, + hyperlink: `https://www.doi.org`, }); /* @@ -112,11 +115,13 @@ export class PdfManipulationService { content: codeBadgeBytes, width: 125, height: 125, + hyperlink: `https://www.doi.org/${doi}`, }; const dataBadge: PdfImageObject = { content: dataBadgeBytes, width: 125, height: 125, + hyperlink: `https://www.doi.org/${doi}2`, }; this.drawCenteredImages({ @@ -158,7 +163,7 @@ export class PdfManipulationService { return `${jobType}-${generationTaskId}.pdf`; } - static drawCenteredMultilineText({ + static async drawCenteredMultilineText({ page, text, font, @@ -167,8 +172,8 @@ export class PdfManipulationService { height, paddingX = 0, positionY = 0.5, - }: DrawCenteredHelperParams): void { - // debugger + hyperlink, + }: DrawCenteredHelperParams): Promise { const lines: string[] = []; const words = text.split(' '); let currentLine = ''; @@ -203,10 +208,33 @@ export class PdfManipulationService { const y = startY + i * textHeight; page.drawText(line, { x, y, size: fontSize, font }); + + if (hyperlink && i === 0) { + const linkAnnotation = page.doc.context.obj({ + Type: 'Annot', + Subtype: 'Link', + Rect: [x, y, x + lineWidth, y + textHeight], + Border: [0, 0, 2], + C: [0, 0, 1], + A: { + Type: 'Action', + S: 'URI', + URI: PDFString.of(hyperlink), + }, + }) as PDFDict; + + const linkAnnotationRef = page.doc.context.register(linkAnnotation); + + const annotations = page.node.Annots() as PDFArray | undefined; + const annotationsArray = annotations ?? page.doc.context.obj([]); + annotationsArray.push(linkAnnotationRef); + + page.node.set(PDFName.of('Annots'), annotationsArray); + } } } - static drawCenteredImages({ + static async drawCenteredImages({ page, images, pageWidth, @@ -214,7 +242,7 @@ export class PdfManipulationService { paddingX = 0, gap = 0, positionY = 0.5, - }: DrawCenteredImagesParams): void { + }: DrawCenteredImagesParams): Promise { const availableWidth = pageWidth - 2 * paddingX; const rows: PdfImageObject[][] = []; @@ -258,6 +286,29 @@ export class PdfManipulationService { height: image.height, }); + if (image.hyperlink) { + const linkAnnotation = page.doc.context.obj({ + Type: 'Annot', + Subtype: 'Link', + Rect: [x, y, x + image.width, y + image.height], + Border: [0, 0, 2], + C: [0, 0, 1], + A: { + Type: 'Action', + S: 'URI', + URI: PDFString.of(image.hyperlink), + }, + }) as PDFDict; + + const linkAnnotationRef = page.doc.context.register(linkAnnotation); + + const annotations = page.node.Annots() as PDFArray | undefined; + const annotationsArray = annotations ?? page.doc.context.obj([]); + annotationsArray.push(linkAnnotationRef); + + page.node.set(PDFName.of('Annots'), annotationsArray); + } + currentX += image.width + gap; } From d2a1c5da6e2b6fdda54b9a8aa169699888042add Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Tue, 7 May 2024 18:28:30 +0000 Subject: [PATCH 011/278] cleanup --- desci-media-isolated/src/services/pdf.ts | 49 ++++-------------------- desci-media-isolated/src/types/pdf.ts | 41 ++++++++++++++++++++ 2 files changed, 49 insertions(+), 41 deletions(-) create mode 100644 desci-media-isolated/src/types/pdf.ts diff --git a/desci-media-isolated/src/services/pdf.ts b/desci-media-isolated/src/services/pdf.ts index dcb0193c..a88a5970 100644 --- a/desci-media-isolated/src/services/pdf.ts +++ b/desci-media-isolated/src/services/pdf.ts @@ -5,53 +5,20 @@ import path from 'path'; import fs from 'fs'; import * as fsp from 'fs/promises'; import { fileURLToPath } from 'url'; -import { PDFArray, PDFDict, PDFDocument, PDFFont, PDFImage, PDFName, PDFPage, PDFString, StandardFonts } from 'pdf-lib'; +import { PDFArray, PDFDict, PDFDocument, PDFName, PDFString, StandardFonts } from 'pdf-lib'; import { readFileToBuffer } from '../utils/utils.js'; +import { + PDF_JOB_TYPE, + type AddPdfCoverParams, + type DrawCenteredHelperParams, + type DrawCenteredImagesParams, + type PdfImageObject, +} from '../types/pdf.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const BASE_TEMP_DIR = path.resolve(__dirname, '../..', TEMP_DIR); -export enum PDF_JOB_TYPE { - ADD_COVER = 'cover', -} - -export interface AddPdfCoverParams { - taskId: string; - cid: string; - title: string; - doi: string; - dpid?: string; -} - -export interface DrawCenteredHelperParams { - page: PDFPage; - text: string; - font: PDFFont; - fontSize: number; - width: number; - height: number; - paddingX?: number; - positionY?: number; // 0-1, vertical alignment, e.g. 0.5 is the center. - hyperlink?: string; -} - -interface PdfImageObject { - content: PDFImage; - width: number; - height: number; - hyperlink?: string; -} -export interface DrawCenteredImagesParams { - page: PDFPage; - images: PdfImageObject[]; - pageWidth: number; - pageHeight: number; - paddingX?: number; - gap?: number; // Gap between images if multiple are passed into the array. - positionY?: number; // 0-1, vertical alignment, e.g. 0.5 is the center. -} - export class PdfManipulationService { static async addPdfCover({ taskId, cid, title, doi, dpid }: AddPdfCoverParams) { const tempFilePath = path.join(BASE_TEMP_DIR, PDF_FILES_DIR, `${taskId}.pdf`); // Saved pdf to manipulate diff --git a/desci-media-isolated/src/types/pdf.ts b/desci-media-isolated/src/types/pdf.ts new file mode 100644 index 00000000..8f1350c2 --- /dev/null +++ b/desci-media-isolated/src/types/pdf.ts @@ -0,0 +1,41 @@ +import type { PDFFont, PDFImage, PDFPage } from 'pdf-lib'; + +export enum PDF_JOB_TYPE { + ADD_COVER = 'cover', +} + +export interface AddPdfCoverParams { + taskId: string; + cid: string; + title: string; + doi: string; + dpid?: string; +} + +export interface DrawCenteredHelperParams { + page: PDFPage; + text: string; + font: PDFFont; + fontSize: number; + width: number; + height: number; + paddingX?: number; + positionY?: number; // 0-1, vertical alignment, e.g. 0.5 is the center. + hyperlink?: string; +} + +export interface PdfImageObject { + content: PDFImage; + width: number; + height: number; + hyperlink?: string; +} +export interface DrawCenteredImagesParams { + page: PDFPage; + images: PdfImageObject[]; + pageWidth: number; + pageHeight: number; + paddingX?: number; + gap?: number; // Gap between images if multiple are passed into the array. + positionY?: number; // 0-1, vertical alignment, e.g. 0.5 is the center. +} From a867e69491863f5df319ac3962d89837c8b51bbf Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Tue, 7 May 2024 18:40:25 +0000 Subject: [PATCH 012/278] conditional badge rendering added --- .../src/controllers/pdf/createCover.ts | 14 +++- desci-media-isolated/src/services/pdf.ts | 67 +++++++++++-------- desci-media-isolated/src/types/pdf.ts | 2 + 3 files changed, 53 insertions(+), 30 deletions(-) diff --git a/desci-media-isolated/src/controllers/pdf/createCover.ts b/desci-media-isolated/src/controllers/pdf/createCover.ts index 9ba04a69..38c903f1 100644 --- a/desci-media-isolated/src/controllers/pdf/createCover.ts +++ b/desci-media-isolated/src/controllers/pdf/createCover.ts @@ -11,6 +11,8 @@ export type GeneratePdfCoverRequestBody = { doi: string; title: string; dpid?: string; + codeAvailableDpid?: string; + dataAvailableDpid?: string; }; const __filename = fileURLToPath(import.meta.url); @@ -24,7 +26,7 @@ export const generatePdfCover = async ( req: Request, res: Response, ) => { - const { cid, doi, dpid, title } = req.body; + const { cid, doi, dpid, title, codeAvailableDpid, dataAvailableDpid } = req.body; const { header = true, headerAllPages = false } = req.query; try { if (!cid) throw new BadRequestError('Missing cid in request body'); @@ -33,7 +35,15 @@ export const generatePdfCover = async ( const generationTaskId = crypto.randomUUID(); - const pdfPath = await PdfManipulationService.addPdfCover({ taskId: generationTaskId, cid, doi, dpid, title }); + const pdfPath = await PdfManipulationService.addPdfCover({ + taskId: generationTaskId, + cid, + doi, + dpid, + title, + codeAvailableDpid, + dataAvailableDpid, + }); const fullPdfPath = path.join(BASE_TEMP_DIR, PDF_OUTPUT_DIR, pdfPath); // Check if the file exists before attempting to stream it diff --git a/desci-media-isolated/src/services/pdf.ts b/desci-media-isolated/src/services/pdf.ts index a88a5970..d69b409b 100644 --- a/desci-media-isolated/src/services/pdf.ts +++ b/desci-media-isolated/src/services/pdf.ts @@ -20,7 +20,7 @@ const __dirname = path.dirname(__filename); const BASE_TEMP_DIR = path.resolve(__dirname, '../..', TEMP_DIR); export class PdfManipulationService { - static async addPdfCover({ taskId, cid, title, doi, dpid }: AddPdfCoverParams) { + static async addPdfCover({ taskId, cid, title, doi, dpid, codeAvailableDpid, dataAvailableDpid }: AddPdfCoverParams) { const tempFilePath = path.join(BASE_TEMP_DIR, PDF_FILES_DIR, `${taskId}.pdf`); // Saved pdf to manipulate const outputPdfFileName = this.getPdfPath(PDF_JOB_TYPE.ADD_COVER, cid); const outputFullPath = path.join(BASE_TEMP_DIR, PDF_OUTPUT_DIR, outputPdfFileName); @@ -72,33 +72,44 @@ export class PdfManipulationService { /* * Badges */ - const codeBadgeBytes = await pdfDoc.embedPng( - await readFileToBuffer(path.join(__dirname, '../../public/static/code-available.png')), - ); - const dataBadgeBytes = await pdfDoc.embedPng( - await readFileToBuffer(path.join(__dirname, '../../public/static/data-available.png')), - ); - const codeBadge: PdfImageObject = { - content: codeBadgeBytes, - width: 125, - height: 125, - hyperlink: `https://www.doi.org/${doi}`, - }; - const dataBadge: PdfImageObject = { - content: dataBadgeBytes, - width: 125, - height: 125, - hyperlink: `https://www.doi.org/${doi}2`, - }; - - this.drawCenteredImages({ - page: newPage, - images: [codeBadge, dataBadge], - pageWidth: width, - pageHeight: height, - positionY: 0.75, - gap: 20, - }); + const badges: PdfImageObject[] = []; + if (codeAvailableDpid) { + const codeBadgeBytes = await pdfDoc.embedPng( + await readFileToBuffer(path.join(__dirname, '../../public/static/code-available.png')), + ); + + const codeBadge: PdfImageObject = { + content: codeBadgeBytes, + width: 125, + height: 125, + hyperlink: codeAvailableDpid, + }; + badges.push(codeBadge); + } + if (dataAvailableDpid) { + const dataBadgeBytes = await pdfDoc.embedPng( + await readFileToBuffer(path.join(__dirname, '../../public/static/data-available.png')), + ); + + const dataBadge: PdfImageObject = { + content: dataBadgeBytes, + width: 125, + height: 125, + hyperlink: dataAvailableDpid, + }; + badges.push(dataBadge); + } + + if (badges.length) { + this.drawCenteredImages({ + page: newPage, + images: badges, + pageWidth: width, + pageHeight: height, + positionY: 0.75, + gap: 20, + }); + } const pdfBytesMod = await pdfDoc.save(); await fsp.writeFile(outputFullPath, pdfBytesMod); diff --git a/desci-media-isolated/src/types/pdf.ts b/desci-media-isolated/src/types/pdf.ts index 8f1350c2..8044c40b 100644 --- a/desci-media-isolated/src/types/pdf.ts +++ b/desci-media-isolated/src/types/pdf.ts @@ -10,6 +10,8 @@ export interface AddPdfCoverParams { title: string; doi: string; dpid?: string; + codeAvailableDpid?: string; + dataAvailableDpid?: string; } export interface DrawCenteredHelperParams { From be48449e7b50c378b25230de900098692302c2cb Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Wed, 8 May 2024 09:51:47 +0000 Subject: [PATCH 013/278] add distribution pdf table --- .../migration.sql | 15 +++++++++++++++ desci-server/prisma/schema.prisma | 11 +++++++++++ 2 files changed, 26 insertions(+) create mode 100644 desci-server/prisma/migrations/20240508094116_add_distribution_pdfs_table/migration.sql diff --git a/desci-server/prisma/migrations/20240508094116_add_distribution_pdfs_table/migration.sql b/desci-server/prisma/migrations/20240508094116_add_distribution_pdfs_table/migration.sql new file mode 100644 index 00000000..bcb77ac4 --- /dev/null +++ b/desci-server/prisma/migrations/20240508094116_add_distribution_pdfs_table/migration.sql @@ -0,0 +1,15 @@ +-- CreateTable +CREATE TABLE "DistributionPdfs" ( + "id" SERIAL NOT NULL, + "originalPdfCid" TEXT NOT NULL, + "nodeUuid" TEXT NOT NULL, + "distPdfCid" TEXT NOT NULL, + + CONSTRAINT "DistributionPdfs_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "DistributionPdfs_nodeUuid_originalPdfCid_key" ON "DistributionPdfs"("nodeUuid", "originalPdfCid"); + +-- AddForeignKey +ALTER TABLE "DistributionPdfs" ADD CONSTRAINT "DistributionPdfs_nodeUuid_fkey" FOREIGN KEY ("nodeUuid") REFERENCES "Node"("uuid") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/desci-server/prisma/schema.prisma b/desci-server/prisma/schema.prisma index 19c75dc7..bdc11030 100755 --- a/desci-server/prisma/schema.prisma +++ b/desci-server/prisma/schema.prisma @@ -43,6 +43,7 @@ model Node { NodeContribution NodeContribution[] PrivateShare PrivateShare[] OrcidPutCodes OrcidPutCodes[] + DistributionPdfs DistributionPdfs[] @@index([ownerId]) @@index([uuid]) @@ -476,6 +477,16 @@ model NodeThumbnails { @@unique([nodeUuid, componentCid]) } +model DistributionPdfs { + id Int @id @default(autoincrement()) + originalPdfCid String + nodeUuid String + distPdfCid String + node Node @relation(fields: [nodeUuid], references: [uuid]) + + @@unique([nodeUuid, originalPdfCid]) +} + // The glue between a manifest contributor entry and a nodes profile model NodeContribution { id Int @id @default(autoincrement()) From 6388ffd21d2744bdc62b0c7a2f03e6f5248e3ced Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Wed, 8 May 2024 09:52:25 +0000 Subject: [PATCH 014/278] add publish package service and cover generation wrapper to nods backend --- desci-server/src/services/PublishPackage.ts | 68 +++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 desci-server/src/services/PublishPackage.ts diff --git a/desci-server/src/services/PublishPackage.ts b/desci-server/src/services/PublishPackage.ts new file mode 100644 index 00000000..19f0b561 --- /dev/null +++ b/desci-server/src/services/PublishPackage.ts @@ -0,0 +1,68 @@ +import { Node } from '@prisma/client'; +import axios from 'axios'; + +import { prisma } from '../client.js'; +import { logger as parentLogger } from '../logger.js'; + +import { pinFile } from './ipfs.js'; + +export type PrepareDistributionPdfParams = { + pdfCid: string; + codeAvailableDpid?: string; + dataAvailableDpid?: string; + node: Node; // Title extraction for now + doi: string; // Temporary till we have DOI system operational +}; + +type PrepareDistributionPdfResult = { + pdfCid: string; +} | null; + +class PublishPackageService { + private logger = parentLogger.child({ module: 'Services::PublishPackageService' }); + + private async prepareDistributionPdf({ + pdfCid, + codeAvailableDpid, + dataAvailableDpid, + node, + doi, + }: PrepareDistributionPdfParams): Promise { + // Check if distro PDF already exists + const existingDistributionPdf = await prisma.distributionPdfs.findFirst({ + where: { originalPdfCid: pdfCid }, + }); + + if (existingDistributionPdf) { + return { pdfCid: existingDistributionPdf.distPdfCid }; + } + + if (process.env.ISOLATED_MEDIA_SERVER_URL === undefined) { + this.logger.error('process.env.ISOLATED_MEDIA_SERVER_URL is not defined'); + return null; + } + + // Generate the PDF with the cover + const coverPdfStream = await axios.post( + `${process.env.ISOLATED_MEDIA_SERVER_URL}/v1/pdf/addCover`, + { cid: pdfCid, doi, title: node.title, codeAvailableDpid, dataAvailableDpid }, + { + responseType: 'stream', + }, + ); + // Save it on IPFS + const pinned = await pinFile(coverPdfStream.data); + + // Save it to the database + await prisma.distributionPdfs.create({ + data: { originalPdfCid: pdfCid, distPdfCid: pinned.cid, nodeUuid: node.uuid }, + }); + + // LATER: Add data ref + + // Return the CID + return { pdfCid: pinned.cid }; + } +} + +export const publishPackageService = new PublishPackageService(); From 7224107aa6155f9b4caa3244b81f06f068031b7e Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Wed, 8 May 2024 10:20:58 +0000 Subject: [PATCH 015/278] create publish package controller/endpoint on nodes backend --- .../nodes/preparePublishPackage.ts | 82 +++++++++++++++++++ desci-server/src/routes/v1/nodes.ts | 2 + desci-server/src/services/PublishPackage.ts | 3 +- 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 desci-server/src/controllers/nodes/preparePublishPackage.ts diff --git a/desci-server/src/controllers/nodes/preparePublishPackage.ts b/desci-server/src/controllers/nodes/preparePublishPackage.ts new file mode 100644 index 00000000..9b3a71c3 --- /dev/null +++ b/desci-server/src/controllers/nodes/preparePublishPackage.ts @@ -0,0 +1,82 @@ +import type { Request, Response } from 'express'; + +import { prisma } from '../../client.js'; +import { logger as parentLogger } from '../../logger.js'; +import { getManifestByCid } from '../../services/data/processing.js'; +import { publishPackageService } from '../../services/PublishPackage.js'; +import { CidString } from '../../services/Thumbnails.js'; +import { ensureUuidEndsWithDot } from '../../utils.js'; + +export type PreparePublishPackageReqBodyParams = { + manifestCid: string; + pdfCid: string; + doi: string; // temp till DOI system is operational + dpid: string; + nodeUuid: string; + codeAvailableDpid?: string; + dataAvailableDpid?: string; +}; + +type PreparePublishPackageResponse = { + ok: true; + distPdfCid: CidString; +}; + +type PreparePublishPackageErrorResponse = { + ok: false; + error: string; + status?: number; +}; + +/** + * Generates a prepublish package for a published node (at the moment just the distro PDF) + */ +export const preparePublishPackage = async ( + req: Request, + res: Response, +) => { + const { pdfCid, doi, nodeUuid, codeAvailableDpid, dataAvailableDpid, manifestCid } = req.body; + const logger = parentLogger.child({ + module: 'NODES::PreparePublishPackageController', + pdfCid, + doi, + nodeUuid, + codeAvailableDpid, + dataAvailableDpid, + }); + logger.trace({ fn: 'Retrieving Publish Package' }); + + if (!nodeUuid) return res.status(400).json({ ok: false, error: 'nodeUuid is required.' }); + if (!doi) return res.status(400).json({ ok: false, error: 'doi is required.' }); + if (!pdfCid) return res.status(400).json({ ok: false, error: 'pdfCid is required.' }); + if (!manifestCid) return res.status(400).json({ ok: false, error: 'manifestCid is required.' }); + + try { + const node = await prisma.node.findFirst({ + where: { + uuid: ensureUuidEndsWithDot(nodeUuid), + }, + }); + + if (!node) return res.status(404).json({ ok: false, error: 'Node not found' }); + + const manifest = await getManifestByCid(manifestCid); + + const dpid = manifest?.dpid.id; + + // debugger; + const { pdfCid: distPdfCid } = await publishPackageService.prepareDistributionPdf({ + pdfCid, + codeAvailableDpid, + dataAvailableDpid, + node, + doi, + dpid, + }); + + return res.status(200).json({ ok: true, distPdfCid }); + } catch (e) { + logger.error({ fn: 'preparePublishPackage', error: e.message }); + return res.status(500).json({ ok: false, error: 'Failed preparing distribution package' }); + } +}; diff --git a/desci-server/src/routes/v1/nodes.ts b/desci-server/src/routes/v1/nodes.ts index b3b06ca6..f1cf7fed 100755 --- a/desci-server/src/routes/v1/nodes.ts +++ b/desci-server/src/routes/v1/nodes.ts @@ -32,6 +32,7 @@ import { checkPublishConsentSchema, } from '../../controllers/nodes/index.js'; import { retrieveTitle } from '../../controllers/nodes/legacyManifestApi.js'; +import { preparePublishPackage } from '../../controllers/nodes/preparePublishPackage.js'; import { prepublish } from '../../controllers/nodes/prepublish.js'; import { listSharedNodes } from '../../controllers/nodes/sharedNodes.js'; import { thumbnails } from '../../controllers/nodes/thumbnails.js'; @@ -77,6 +78,7 @@ router.patch('/contributions/:uuid', [ensureUser, ensureWriteNodeAccess], update router.delete('/contributions/:uuid', [ensureUser, ensureWriteNodeAccess], deleteContributor); router.get('/contributions/user/:userId', [], getUserContributions); router.get('/contributions/user', [ensureUser], getUserContributionsAuthed); +router.post('/distribution', preparePublishPackage); router.delete('/:uuid', [ensureUser], deleteNode); diff --git a/desci-server/src/services/PublishPackage.ts b/desci-server/src/services/PublishPackage.ts index 19f0b561..24f4df33 100644 --- a/desci-server/src/services/PublishPackage.ts +++ b/desci-server/src/services/PublishPackage.ts @@ -12,6 +12,7 @@ export type PrepareDistributionPdfParams = { dataAvailableDpid?: string; node: Node; // Title extraction for now doi: string; // Temporary till we have DOI system operational + dpid: string; }; type PrepareDistributionPdfResult = { @@ -21,7 +22,7 @@ type PrepareDistributionPdfResult = { class PublishPackageService { private logger = parentLogger.child({ module: 'Services::PublishPackageService' }); - private async prepareDistributionPdf({ + async prepareDistributionPdf({ pdfCid, codeAvailableDpid, dataAvailableDpid, From 31211ae1eb8028046d7a3cea833452151dee6916 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Wed, 8 May 2024 10:22:16 +0000 Subject: [PATCH 016/278] switch to title from manifest for versioned result --- desci-server/src/controllers/nodes/preparePublishPackage.ts | 2 ++ desci-server/src/services/PublishPackage.ts | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/desci-server/src/controllers/nodes/preparePublishPackage.ts b/desci-server/src/controllers/nodes/preparePublishPackage.ts index 9b3a71c3..bc6db30d 100644 --- a/desci-server/src/controllers/nodes/preparePublishPackage.ts +++ b/desci-server/src/controllers/nodes/preparePublishPackage.ts @@ -61,6 +61,7 @@ export const preparePublishPackage = async ( if (!node) return res.status(404).json({ ok: false, error: 'Node not found' }); const manifest = await getManifestByCid(manifestCid); + const title = manifest.title; const dpid = manifest?.dpid.id; @@ -72,6 +73,7 @@ export const preparePublishPackage = async ( node, doi, dpid, + title, }); return res.status(200).json({ ok: true, distPdfCid }); diff --git a/desci-server/src/services/PublishPackage.ts b/desci-server/src/services/PublishPackage.ts index 24f4df33..bd9a737f 100644 --- a/desci-server/src/services/PublishPackage.ts +++ b/desci-server/src/services/PublishPackage.ts @@ -13,6 +13,7 @@ export type PrepareDistributionPdfParams = { node: Node; // Title extraction for now doi: string; // Temporary till we have DOI system operational dpid: string; + title: string; }; type PrepareDistributionPdfResult = { @@ -28,6 +29,7 @@ class PublishPackageService { dataAvailableDpid, node, doi, + title, }: PrepareDistributionPdfParams): Promise { // Check if distro PDF already exists const existingDistributionPdf = await prisma.distributionPdfs.findFirst({ @@ -46,7 +48,7 @@ class PublishPackageService { // Generate the PDF with the cover const coverPdfStream = await axios.post( `${process.env.ISOLATED_MEDIA_SERVER_URL}/v1/pdf/addCover`, - { cid: pdfCid, doi, title: node.title, codeAvailableDpid, dataAvailableDpid }, + { cid: pdfCid, doi, title, codeAvailableDpid, dataAvailableDpid }, { responseType: 'stream', }, From 8d9e4f35ccb74cf5f5c35e27c5ebe712916e1771 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Thu, 16 May 2024 20:06:53 +0000 Subject: [PATCH 017/278] node updated email created --- .../src/templates/emails/NodeUpdated.tsx | 83 +++++++++++++++++++ .../templates/emails/utils/emailRenderer.tsx | 3 + 2 files changed, 86 insertions(+) create mode 100644 desci-server/src/templates/emails/NodeUpdated.tsx diff --git a/desci-server/src/templates/emails/NodeUpdated.tsx b/desci-server/src/templates/emails/NodeUpdated.tsx new file mode 100644 index 00000000..831aada4 --- /dev/null +++ b/desci-server/src/templates/emails/NodeUpdated.tsx @@ -0,0 +1,83 @@ +import { Body, Container, Head, Heading, Html, Preview, Text, Button, Section } from '@react-email/components'; +import * as React from 'react'; + +import MainLayout from './MainLayout.js'; + +export interface NodeUpdatedEmailProps { + nodeOwner: string; + nodeTitle: string; + nodeUuid: string; + nodeDpid: string; + versionUpdate: string; +} + +const DAPP_URL = process.env.DAPP_URL || 'http://localhost:3000'; + +export const NodeUpdated = ({ nodeOwner, nodeTitle, nodeUuid, nodeDpid, versionUpdate }: NodeUpdatedEmailProps) => { + if (nodeUuid?.endsWith('.') || nodeUuid?.endsWith('=')) nodeUuid = nodeUuid.slice(0, -1); + nodeOwner = nodeOwner || 'The node owner'; + const nodeUrl = `${DAPP_URL}/dpid/${nodeDpid}/${versionUpdate}`; + return ( + + + + DPID {nodeDpid} has been updated + + + + (DPID {nodeDpid}) has been updated to version ${versionUpdate} + + + {nodeOwner} has published an updated version of their research object titled{' '} + "{nodeTitle}" that you have contributed to. + + +
+ +
+
+ + +
+ ); +}; + +export default NodeUpdated; + +const main = { + backgroundColor: '#ffffff', + margin: '0 auto', + fontFamily: + "-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif", +}; + +const container = { + margin: '0 auto', + padding: '0px 20px', +}; + +const h1 = { + color: '#000000', + fontSize: '30px', + fontWeight: '700', + margin: '30px 0', + padding: '0', + lineHeight: '42px', +}; + +const heroText = { + fontSize: '20px', + lineHeight: '28px', + marginBottom: '30px', +}; diff --git a/desci-server/src/templates/emails/utils/emailRenderer.tsx b/desci-server/src/templates/emails/utils/emailRenderer.tsx index fa79e326..01037184 100644 --- a/desci-server/src/templates/emails/utils/emailRenderer.tsx +++ b/desci-server/src/templates/emails/utils/emailRenderer.tsx @@ -3,6 +3,7 @@ import { render } from '@react-email/components'; import AttestationClaimedEmail, { AttestationClaimedEmailProps } from '../AttestationClaimed.js'; import ContributorInvite, { ContributorInviteEmailProps } from '../ContributorInvite.js'; import MagicCodeEmail, { MagicCodeEmailProps } from '../MagicCode.js'; +import NodeUpdated, { NodeUpdatedEmailProps } from '../NodeUpdated.js'; export const ContributorInviteEmailHtml = ({ inviter, @@ -17,3 +18,5 @@ export const MagicCodeEmailHtml = ({ magicCode, ip }: MagicCodeEmailProps) => re export const AttestationClaimedEmailHtml = (props: AttestationClaimedEmailProps) => render(AttestationClaimedEmail(props)); + +export const NodeUpdatedEmailHtml = (props: NodeUpdatedEmailProps) => render(NodeUpdated(props)); From 9c1772c34b423357ecc19f9c84b633f815e03087 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Fri, 17 May 2024 12:14:11 +0000 Subject: [PATCH 018/278] email updates to all contributors on publish --- .../contributions/getNodeContributions.ts | 2 +- desci-server/src/controllers/nodes/publish.ts | 4 + desci-server/src/services/Contributors.ts | 13 +++- desci-server/src/services/PublishServices.ts | 74 +++++++++++++++++++ .../src/templates/emails/NodeUpdated.tsx | 2 +- 5 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 desci-server/src/services/PublishServices.ts diff --git a/desci-server/src/controllers/nodes/contributions/getNodeContributions.ts b/desci-server/src/controllers/nodes/contributions/getNodeContributions.ts index 88799018..cf0b4c21 100644 --- a/desci-server/src/controllers/nodes/contributions/getNodeContributions.ts +++ b/desci-server/src/controllers/nodes/contributions/getNodeContributions.ts @@ -49,7 +49,7 @@ export const getNodeContributions = async ( const node = await prisma.node.findUnique({ where: { uuid: ensureUuidEndsWithDot(uuid) } }); const authedMode = !!user && user.id === node?.ownerId; const nodeContributions: NodeContributorMap | NodeContributorMapAuthed = - await contributorService.retrieveContributionsForNode(node, contributorIds, authedMode); + await contributorService.retrieveSelectedContributionsForNode(node, contributorIds, authedMode); if (nodeContributions) { logger.info({ totalContributions: nodeContributions.length }, 'Contributions retrieved successfully'); return res.status(200).json({ ok: true, nodeContributions }); diff --git a/desci-server/src/controllers/nodes/publish.ts b/desci-server/src/controllers/nodes/publish.ts index 364fd914..f905392e 100644 --- a/desci-server/src/controllers/nodes/publish.ts +++ b/desci-server/src/controllers/nodes/publish.ts @@ -16,6 +16,7 @@ import { setCeramicStream, } from '../../services/nodeManager.js'; import orcidApiService from '../../services/orcid.js'; +import { publishServices } from '../../services/PublishServices.js'; import { discordNotify } from '../../utils/discordUtils.js'; import { ensureUuidEndsWithDot } from '../../utils.js'; @@ -296,6 +297,9 @@ export const publishHandler = async ({ discordNotify(`${targetDpidUrl}/${manifestSource.dpid?.id}${error ? ' (note: estuary-err)' : ''}`); }; + // Send an email update to all contributors + await publishServices.sendVersionUpdateEmailToAllContributors({ node }); + /** * NOTE: uncomment when reactivating public ref mirroring const handleMirrorSuccess = async (publishedResearchObjectResult) => { diff --git a/desci-server/src/services/Contributors.ts b/desci-server/src/services/Contributors.ts index 9b52f983..87867839 100644 --- a/desci-server/src/services/Contributors.ts +++ b/desci-server/src/services/Contributors.ts @@ -164,7 +164,7 @@ class ContributorService { return false; } - async retrieveContributionsForNode( + async retrieveSelectedContributionsForNode( node: Node, contributorIds: string[], authedMode = false, @@ -187,6 +187,17 @@ class ContributorService { }, {}); } + /** + * To be used within the backend, if the data from this is returned to the frontend, it can potentially leak data, + * opt for retrieveSelectedContributionsForNode instead if the data is to be returned to the frontend + */ + async retrieveAllVerifiedContributionsForNode(node: Node): Promise<(NodeContribution & { user: User })[]> { + return prisma.nodeContribution.findMany({ + where: { nodeId: node.id, verified: true }, + include: { user: true }, + }); + } + async retrieveContributionsForUser(user: User): Promise { const contributions = await prisma.nodeContribution.findMany({ where: { userId: user.id }, diff --git a/desci-server/src/services/PublishServices.ts b/desci-server/src/services/PublishServices.ts new file mode 100644 index 00000000..e1072be7 --- /dev/null +++ b/desci-server/src/services/PublishServices.ts @@ -0,0 +1,74 @@ +import { Node } from '@prisma/client'; +import sgMail from '@sendgrid/mail'; + +import { prisma } from '../client.js'; +import { getNodeVersion } from '../internal.js'; +import { logger as parentLogger } from '../logger.js'; +import { NodeUpdatedEmailHtml } from '../templates/emails/utils/emailRenderer.js'; + +import { contributorService } from './Contributors.js'; +import { getLatestManifestFromNode } from './manifestRepo.js'; + +sgMail.setApiKey(process.env.SENDGRID_API_KEY); + +const logger = parentLogger.child({ + module: 'Services::PublishServices', +}); + +export class PublishServices { + async sendVersionUpdateEmailToAllContributors({ node }: { node: Node }) { + const contributors = await contributorService.retrieveAllVerifiedContributionsForNode(node); + const nodeOwner = await prisma.user.findUnique({ where: { id: node.ownerId } }); + const manifest = await getLatestManifestFromNode(node); + const dpid = manifest.dpid?.id; + const versionPublished = await getNodeVersion(node.uuid); + + if (!dpid) { + logger.error( + { nodeUuid: node.uuid, 'manifest.dpid': manifest?.dpid, nodeOwner, totalContributors: contributors.length }, + 'Failed to retrieve DPID for node, emails not sent during publish update.', + ); + } + + const emailPromises = contributors.map((contributor) => { + const emailHtml = NodeUpdatedEmailHtml({ + nodeOwner: nodeOwner.name, + nodeUuid: node.uuid, + nodeTitle: node.title, + nodeDpid: dpid, + versionUpdate: versionPublished, + }); + + const emailMsg = { + to: contributor.email, + from: 'no-reply@desci.com', + subject: `[nodes.desci.com] DPID ${dpid} has been updated`, + text: `${nodeOwner.name} has published an updated version (${versionPublished}) of their research object titled "${node.title}" that you have contributed to.`, + html: emailHtml, + }; + + return emailMsg; + }); + + if (process.env.NODE_ENV === 'production') { + await Promise.allSettled(emailPromises.map((emailMsg) => sgMail.send(emailMsg))); + } else { + logger.info( + { nodeEnv: process.env.NODE_ENV }, + 'Skipping add contributor email send in non-production environment', + ); + } + + return true; + } +} + +export interface NodeUpdatedEmailProps { + nodeOwner: string; + nodeTitle: string; + nodeUuid: string; + nodeDpid: string; + versionUpdate: string; +} + +export const publishServices = new PublishServices(); diff --git a/desci-server/src/templates/emails/NodeUpdated.tsx b/desci-server/src/templates/emails/NodeUpdated.tsx index 831aada4..5fc29aaa 100644 --- a/desci-server/src/templates/emails/NodeUpdated.tsx +++ b/desci-server/src/templates/emails/NodeUpdated.tsx @@ -25,7 +25,7 @@ export const NodeUpdated = ({ nodeOwner, nodeTitle, nodeUuid, nodeDpid, versionU - (DPID {nodeDpid}) has been updated to version ${versionUpdate} + DPID {nodeDpid} has been updated to version ${versionUpdate} {nodeOwner} has published an updated version of their research object titled{' '} From 9cedf13120dc5b88cd98c265f1e8a400001b53ff Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Fri, 17 May 2024 16:35:05 +0200 Subject: [PATCH 019/278] feat: implementing doi service and mock doi minting --- .../migration.sql | 23 ++++ desci-server/prisma/schema.prisma | 11 ++ desci-server/src/controllers/doi/check.ts | 10 ++ desci-server/src/controllers/doi/index.ts | 2 + desci-server/src/controllers/doi/mint.ts | 10 ++ desci-server/src/core/ApiError.ts | 11 ++ desci-server/src/internal.ts | 2 + desci-server/src/routes/v1/doi.ts | 10 ++ desci-server/src/routes/v1/index.ts | 2 + desci-server/src/services/Attestation.ts | 5 + desci-server/src/services/Doi.ts | 126 ++++++++++++++++++ desci-server/src/services/data/processing.ts | 2 +- desci-server/src/services/index.ts | 5 + desci-server/src/services/orcid.ts | 6 +- 14 files changed, 221 insertions(+), 4 deletions(-) create mode 100644 desci-server/prisma/migrations/20240517110638_add_doi_records_table/migration.sql create mode 100644 desci-server/src/controllers/doi/check.ts create mode 100644 desci-server/src/controllers/doi/index.ts create mode 100644 desci-server/src/controllers/doi/mint.ts create mode 100644 desci-server/src/routes/v1/doi.ts create mode 100644 desci-server/src/services/Doi.ts create mode 100644 desci-server/src/services/index.ts diff --git a/desci-server/prisma/migrations/20240517110638_add_doi_records_table/migration.sql b/desci-server/prisma/migrations/20240517110638_add_doi_records_table/migration.sql new file mode 100644 index 00000000..24fc6352 --- /dev/null +++ b/desci-server/prisma/migrations/20240517110638_add_doi_records_table/migration.sql @@ -0,0 +1,23 @@ +-- CreateTable +CREATE TABLE "DoiRecord" ( + "id" SERIAL NOT NULL, + "doi" TEXT NOT NULL, + "dpid" TEXT NOT NULL, + "uuid" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "DoiRecord_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "DoiRecord_doi_key" ON "DoiRecord"("doi"); + +-- CreateIndex +CREATE UNIQUE INDEX "DoiRecord_dpid_key" ON "DoiRecord"("dpid"); + +-- CreateIndex +CREATE UNIQUE INDEX "DoiRecord_uuid_key" ON "DoiRecord"("uuid"); + +-- AddForeignKey +ALTER TABLE "DoiRecord" ADD CONSTRAINT "DoiRecord_uuid_fkey" FOREIGN KEY ("uuid") REFERENCES "Node"("uuid") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/desci-server/prisma/schema.prisma b/desci-server/prisma/schema.prisma index 790372d9..6fc4830c 100755 --- a/desci-server/prisma/schema.prisma +++ b/desci-server/prisma/schema.prisma @@ -43,6 +43,7 @@ model Node { NodeContribution NodeContribution[] PrivateShare PrivateShare[] OrcidPutCodes OrcidPutCodes[] + DoiRecord DoiRecord[] @@index([ownerId]) @@index([uuid]) @@ -806,6 +807,16 @@ model OrcidPutCodes { @@unique([orcid, uuid, reference]) } +model DoiRecord { + id Int @id @default(autoincrement()) + doi String @unique + dpid String @unique + uuid String @unique + node Node @relation(fields: [uuid], references: [uuid]) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + enum ORCIDRecord { WORK QUALIFICATION diff --git a/desci-server/src/controllers/doi/check.ts b/desci-server/src/controllers/doi/check.ts new file mode 100644 index 00000000..111906c4 --- /dev/null +++ b/desci-server/src/controllers/doi/check.ts @@ -0,0 +1,10 @@ +import { Request, Response, NextFunction } from 'express'; + +import { BadRequestError, SuccessMessageResponse, doiService } from '../../internal.js'; + +export const checkMintability = async (req: Request, res: Response, next: NextFunction) => { + const { uuid } = req.params; + if (!uuid) throw new BadRequestError(); + await doiService.checkMintability(uuid); + new SuccessMessageResponse().send(res); +}; diff --git a/desci-server/src/controllers/doi/index.ts b/desci-server/src/controllers/doi/index.ts new file mode 100644 index 00000000..3313418d --- /dev/null +++ b/desci-server/src/controllers/doi/index.ts @@ -0,0 +1,2 @@ +export * from './check.js'; +export * from './mint.js'; diff --git a/desci-server/src/controllers/doi/mint.ts b/desci-server/src/controllers/doi/mint.ts new file mode 100644 index 00000000..492c309e --- /dev/null +++ b/desci-server/src/controllers/doi/mint.ts @@ -0,0 +1,10 @@ +import { Request, Response, NextFunction } from 'express'; + +import { BadRequestError, SuccessResponse, doiService } from '../../internal.js'; + +export const mintDoi = async (req: Request, res: Response, next: NextFunction) => { + const { uuid } = req.params; + if (!uuid) throw new BadRequestError(); + const doi = await doiService.mintDoi(uuid); + new SuccessResponse(doi).send(res); +}; diff --git a/desci-server/src/core/ApiError.ts b/desci-server/src/core/ApiError.ts index b66ddca1..b454b6a0 100644 --- a/desci-server/src/core/ApiError.ts +++ b/desci-server/src/core/ApiError.ts @@ -1,6 +1,7 @@ import { Response } from 'express'; import { AttestationError, AttestationErrorType } from '../internal.js'; +import { DoiError, DoiErrorType } from '../services/Doi.js'; import { AuthFailureResponse, @@ -60,6 +61,16 @@ export abstract class ApiError extends Error { default: return new InternalErrorResponse(err.message).send(res); } + } else if (err instanceof DoiError) { + switch (err.type) { + case DoiErrorType.BAD_METADATA: + case DoiErrorType.NO_MANUSCRIPT: + case DoiErrorType.INCOMPLETE_ATTESTATIONS: + case DoiErrorType.DUPLICATE_MINT: + return new BadRequestResponse(err.message, err).send(res); + default: + return new InternalErrorResponse(err.message).send(res); + } } return new InternalErrorResponse(err.message).send(res); } diff --git a/desci-server/src/internal.ts b/desci-server/src/internal.ts index d6d252c6..dbd9d7e7 100644 --- a/desci-server/src/internal.ts +++ b/desci-server/src/internal.ts @@ -5,11 +5,13 @@ export * from './core/ApiError.js'; export * from './core/ApiResponse.js'; export * from './middleware/index.js'; export * from './services/Communities.js'; +export * from './services/index.js'; export * from './services/Attestation.js'; export * from './utils/asyncHandler.js'; export * from './routes/v1/attestations/schema.js'; export * from './controllers/communities/index.js'; export * from './controllers/attestations/index.js'; +export * from './controllers/doi/index.js'; export * from './core/ApiResponse.js'; export * from './utils/manifest.js'; export * from './services/repoService.js'; diff --git a/desci-server/src/routes/v1/doi.ts b/desci-server/src/routes/v1/doi.ts new file mode 100644 index 00000000..bc4f4b8c --- /dev/null +++ b/desci-server/src/routes/v1/doi.ts @@ -0,0 +1,10 @@ +import { Router } from 'express'; + +import { asyncHander, checkMintability, ensureUser, mintDoi } from '../../internal.js'; + +const router = Router(); + +router.post('/check/:uuid', [ensureUser], asyncHander(checkMintability)); +router.post('/mint/:uuid', [ensureUser], asyncHander(mintDoi)); + +export default router; diff --git a/desci-server/src/routes/v1/index.ts b/desci-server/src/routes/v1/index.ts index e523b6e7..2d9d20d9 100755 --- a/desci-server/src/routes/v1/index.ts +++ b/desci-server/src/routes/v1/index.ts @@ -14,6 +14,7 @@ import attestations from './attestations/index.js'; import auth from './auth.js'; import communities from './communities/index.js'; import data from './data.js'; +import doi from './doi.js'; import log from './log.js'; import nodes from './nodes.js'; import pub from './pub.js'; @@ -54,6 +55,7 @@ router.use('/log', log); router.use('/services', services); router.use('/communities', communities); router.use('/attestations', attestations); +router.use('/doi', doi); router.get('/nft/:id', nft); router.use('/referral', referral); diff --git a/desci-server/src/services/Attestation.ts b/desci-server/src/services/Attestation.ts index 63c53a82..cedaf86c 100644 --- a/desci-server/src/services/Attestation.ts +++ b/desci-server/src/services/Attestation.ts @@ -255,6 +255,7 @@ export class AttestationService { image_url: claim.attestationVersion.image_url, verifications: claim._count.NodeAttestationVerification, community: claim.community.name, + attestationId: claim.attestationId, nodeVersion: claim.nodeVersion, })) .value(); @@ -262,6 +263,10 @@ export class AttestationService { return protectedClaims; } + async getDoiMintingPrerequisites() { + // todo() + } + async getNodeCommunityAttestations(dpid: string, communityId: number) { return prisma.nodeAttestation.findMany({ where: { nodeDpid10: dpid, desciCommunityId: communityId, revoked: false }, diff --git a/desci-server/src/services/Doi.ts b/desci-server/src/services/Doi.ts new file mode 100644 index 00000000..a4276a7c --- /dev/null +++ b/desci-server/src/services/Doi.ts @@ -0,0 +1,126 @@ +import crypto from 'node:crypto'; + +import { + PdfComponent, + ResearchObjectComponentDocumentSubtype, + ResearchObjectComponentType, +} from '@desci-labs/desci-models'; +import { PrismaClient } from '@prisma/client'; + +import { IndexedResearchObject, getIndexedResearchObjects } from '../theGraph.js'; +import { ensureUuidEndsWithDot, hexToCid } from '../utils.js'; + +import { attestationService } from './Attestation.js'; +import { getManifestByCid } from './data/processing.js'; + +export class DoiService { + dbClient: PrismaClient; + + constructor(prismaClient: PrismaClient) { + this.dbClient = prismaClient; + } + + async checkMintability(nodeUuid: string) { + const uuid = ensureUuidEndsWithDot(nodeUuid); + // check if node has claimed doi already + const exists = await this.dbClient.doiRecord.findUnique({ where: { uuid } }); + if (exists) throw new DuplicateMintError(); + + // retrieve node manifest/metadata + const { researchObjects } = await getIndexedResearchObjects([uuid]); + const researchObject = researchObjects[0] as IndexedResearchObject; + const manifestCid = hexToCid(researchObject.recentCid); + const latestManifest = await getManifestByCid(manifestCid); + researchObject.versions.reverse(); + // const nodeVersion = researchObject.versions.length; + + const doiAttestations = await attestationService.getProtectedAttestations({ protected: true }); + let claims = await attestationService.getProtectedNodeClaims(latestManifest.dpid.id); + claims = claims.filter((claim) => claim.verifications > 0); + const hasDataOrCode = claims.length > 0; + + // check if manuscript is included + const manuscript = + latestManifest && + latestManifest.components.find( + (component) => + component.type === ResearchObjectComponentType.PDF && + (component as PdfComponent).subtype === ResearchObjectComponentDocumentSubtype.MANUSCRIPT, + ); + if (!manuscript && !hasDataOrCode) { + throw new NoManuscriptError(); + } + + // validate title, abstract and contributors + const hasTitle = latestManifest.title.trim().length > 0; + const hasAbstract = latestManifest.description.trim().length > 0; + const hasContributors = latestManifest.authors.length > 0; + if (!hasTitle || !hasAbstract || !hasContributors) throw new BadManifestError(); + + const hasClaimedRequiredAttestations = doiAttestations.every((attestation) => + claims.find((claim) => claim.attestationId === attestation.id), + ); + if (!hasClaimedRequiredAttestations) throw new AttestationsError(); + + return { dpid: latestManifest.dpid.id, uuid }; + } + + async mintDoi(nodeUuid: string) { + const { dpid, uuid } = await this.checkMintability(nodeUuid); + // todo: handle over logic to cross-ref api service for minting DOIs + // mint new doi + const doiSuffix = crypto.randomBytes(8 - dpid.length); + const doi = `https://doi.org/10.555/${doiSuffix}`; + return await this.dbClient.doiRecord.create({ + data: { + uuid, + dpid, + doi, + }, + }); + } + + async checkDataOrCode(dpid: string) {} +} + +export enum DoiErrorType { + DUPLICATE_MINT = 'DuplicateDoiError', + NO_MANUSCRIPT = 'NoManuscriptError', + BAD_METADATA = 'InvalidManifestError', + INCOMPLETE_ATTESTATIONS = 'ForbiddenError', +} + +export class DoiError extends Error { + name = 'DoiValidationError'; + + constructor( + public type: DoiErrorType, + public message: string = 'Doi Error', + ) { + super(type); + } +} + +export class BadManifestError extends DoiError { + constructor(message = 'Title, Abstract or Contributors is missing') { + super(DoiErrorType.BAD_METADATA, message); + } +} + +export class NoManuscriptError extends DoiError { + constructor(message = 'Node has no manuscript') { + super(DoiErrorType.NO_MANUSCRIPT, message); + } +} + +export class AttestationsError extends DoiError { + constructor(message = 'All required attestations are not claimed or verified!') { + super(DoiErrorType.INCOMPLETE_ATTESTATIONS, message); + } +} + +export class DuplicateMintError extends DoiError { + constructor(message = 'DOI already minted for node') { + super(DoiErrorType.DUPLICATE_MINT, message); + } +} diff --git a/desci-server/src/services/data/processing.ts b/desci-server/src/services/data/processing.ts index e7c1b575..01ac09b0 100644 --- a/desci-server/src/services/data/processing.ts +++ b/desci-server/src/services/data/processing.ts @@ -14,6 +14,7 @@ import { } from '@desci-labs/desci-models'; import { User, Node, DataType, Prisma } from '@prisma/client'; import axios from 'axios'; +import { CID } from 'multiformats'; import { v4 } from 'uuid'; import { prisma } from '../../client.js'; @@ -59,7 +60,6 @@ import { createNotEnoughSpaceError, createUnhandledError, } from './processingErrors.js'; -import { CID } from 'multiformats'; interface ProcessS3DataToIpfsParams { files: any[]; diff --git a/desci-server/src/services/index.ts b/desci-server/src/services/index.ts new file mode 100644 index 00000000..c3f27e6b --- /dev/null +++ b/desci-server/src/services/index.ts @@ -0,0 +1,5 @@ +import { prisma } from '../client.js'; + +import { DoiService } from './Doi.js'; + +export const doiService = new DoiService(prisma); diff --git a/desci-server/src/services/orcid.ts b/desci-server/src/services/orcid.ts index dfa2271d..682eee87 100644 --- a/desci-server/src/services/orcid.ts +++ b/desci-server/src/services/orcid.ts @@ -516,7 +516,7 @@ const generateClaimWorkRecord = ({ const description = `${claim.name} Attestation`; const [month, day, year] = publicationDate.split('-'); - const externalUrl = `${process.env.DPID_URL_OVERRIDE}/${manifest.dpid.id}/attestation/${claim.id}`; + const externalUrl = `${DPID_URL_OVERRIDE}/${manifest.dpid.id}/attestation/${claim.id}`; const dataRoot = `${DPID_URL_OVERRIDE}/${manifest.dpid.id}/v${nodeVersion}`; logger.info({ codeAttr, workType, publicationDate, day, month, year, externalUrl }, 'CODE ATTR'); return ( @@ -537,13 +537,13 @@ const generateClaimWorkRecord = ({ uri - ${claim.name} URL + ${claim.name} Root ${dataRoot} ${dataRoot} self uri - ${claim.name} by ${claim.community} + ${externalUrl} ${externalUrl} part-of From cb6c77c3e1f98537c28452480c50c05c4bffede3 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Sat, 18 May 2024 14:29:29 +0000 Subject: [PATCH 020/278] copy updates to cover gen --- desci-media-isolated/src/services/ipfs.ts | 2 +- desci-media-isolated/src/services/pdf.ts | 47 +++++++++++++++++++++-- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/desci-media-isolated/src/services/ipfs.ts b/desci-media-isolated/src/services/ipfs.ts index fcc0eeec..f0fb9d95 100644 --- a/desci-media-isolated/src/services/ipfs.ts +++ b/desci-media-isolated/src/services/ipfs.ts @@ -11,7 +11,7 @@ export class IpfsService { throw new IpfsConfigurationError('process.env.IPFS_GATEWAY is not defined in environment variables'); } const url = `${IPFS_GATEWAY}/${cid}`; - debugger; + try { const response = await axios({ method: 'get', diff --git a/desci-media-isolated/src/services/pdf.ts b/desci-media-isolated/src/services/pdf.ts index d69b409b..3a9279d6 100644 --- a/desci-media-isolated/src/services/pdf.ts +++ b/desci-media-isolated/src/services/pdf.ts @@ -58,15 +58,55 @@ export class PdfManipulationService { * Title */ const titleSize = 30; + const titlePosY = 0.4; - this.drawCenteredMultilineText({ + const titleLines = await this.drawCenteredMultilineText({ page: newPage, text: title, font: helveticaFont, fontSize: titleSize, width, height, - paddingX: 20, + positionY: titlePosY, + paddingX: 100, + }); + + /* + * Authors + */ + const authors = 'M. Ansdell, J. Williams, N. van der Marel, J. Carpenter, G. Guidi'; + const authorsSize = 20; + const titleHeight = titleLines.length * helveticaFont.heightAtSize(titleSize); + const authorsPosY = titlePosY + titleHeight / height; + + const authorsLines = await this.drawCenteredMultilineText({ + page: newPage, + text: authors, + font: helveticaFont, + fontSize: authorsSize, + width, + height, + paddingX: 100, + positionY: authorsPosY, + }); + + /* + * Center Text (Artifacts available here) + */ + const centeredText = 'Data and/or code available at:'; + const centeredTextSize = 16; + const authorsHeight = authorsLines.length * helveticaFont.heightAtSize(authorsSize); + const centeredTextPosY = authorsPosY + authorsHeight / height + 0.02; + + this.drawCenteredMultilineText({ + page: newPage, + text: centeredText, + font: helveticaFont, + fontSize: centeredTextSize, + width, + height, + paddingX: 100, + positionY: centeredTextPosY, }); /* @@ -151,7 +191,7 @@ export class PdfManipulationService { paddingX = 0, positionY = 0.5, hyperlink, - }: DrawCenteredHelperParams): Promise { + }: DrawCenteredHelperParams): Promise { const lines: string[] = []; const words = text.split(' '); let currentLine = ''; @@ -210,6 +250,7 @@ export class PdfManipulationService { page.node.set(PDFName.of('Annots'), annotationsArray); } } + return lines; } static async drawCenteredImages({ From 7da6db3b04619ffd434ac562af1c686ef4ec1470 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Tue, 21 May 2024 12:01:29 +0200 Subject: [PATCH 021/278] modify api error and response formatting --- desci-server/src/controllers/attestations/claims.ts | 3 +++ desci-server/src/core/ApiResponse.ts | 10 +++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/desci-server/src/controllers/attestations/claims.ts b/desci-server/src/controllers/attestations/claims.ts index d499fc35..6998f81d 100644 --- a/desci-server/src/controllers/attestations/claims.ts +++ b/desci-server/src/controllers/attestations/claims.ts @@ -5,6 +5,9 @@ import _ from 'lodash'; import { AuthFailureError, + ForbiddenError, + ForbiddenResponse, + InternalError, NotFoundError, SuccessMessageResponse, SuccessResponse, diff --git a/desci-server/src/core/ApiResponse.ts b/desci-server/src/core/ApiResponse.ts index 188c3b3c..20b5fccf 100644 --- a/desci-server/src/core/ApiResponse.ts +++ b/desci-server/src/core/ApiResponse.ts @@ -18,7 +18,7 @@ export interface ToApiResponse { export abstract class ApiResponse { constructor( private status: ResponseStatus, - message: string, + private message: string, ) {} protected prepare(res: Response, response: T, headers: { [key: string]: string }): Response { @@ -40,17 +40,17 @@ export abstract class ApiResponse { } export class SuccessMessageResponse extends ApiResponse { - constructor(message = 'Success') { - super(ResponseStatus.SUCCESS, message); + constructor(_message = '') { + super(ResponseStatus.SUCCESS, undefined); } } export class SuccessResponse extends ApiResponse { constructor( private data: T, - message = 'Success', + _message = '', ) { - super(ResponseStatus.SUCCESS, message); + super(ResponseStatus.SUCCESS, undefined); } send(res: Response, headers?: Headers): Response { From 418125c4a04349bbbcc5491a1980a1f5da28f876 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Tue, 21 May 2024 16:36:46 +0200 Subject: [PATCH 022/278] implement api to query node doi, refactor doi generation code --- desci-server/package.json | 1 + desci-server/src/controllers/doi/check.ts | 14 ++++-- desci-server/src/core/doi/error.ts | 41 +++++++++++++++++ desci-server/src/routes/v1/doi.ts | 3 +- desci-server/src/services/Doi.ts | 54 ++++------------------- desci-server/yarn.lock | 5 +++ 6 files changed, 69 insertions(+), 49 deletions(-) create mode 100644 desci-server/src/core/doi/error.ts diff --git a/desci-server/package.json b/desci-server/package.json index 86eb086b..a3a40562 100755 --- a/desci-server/package.json +++ b/desci-server/package.json @@ -130,6 +130,7 @@ "@types/multer-s3": "^3.0.1", "@types/node": "^20.10.4", "@types/supertest": "^2.0.12", + "@types/uuid": "^9.0.8", "@types/ws": "^8.5.10", "@types/xmldom": "^0.1.34", "@typescript-eslint/eslint-plugin": "^6.14.0", diff --git a/desci-server/src/controllers/doi/check.ts b/desci-server/src/controllers/doi/check.ts index 111906c4..a282239d 100644 --- a/desci-server/src/controllers/doi/check.ts +++ b/desci-server/src/controllers/doi/check.ts @@ -1,10 +1,18 @@ -import { Request, Response, NextFunction } from 'express'; +import { Request, Response } from 'express'; -import { BadRequestError, SuccessMessageResponse, doiService } from '../../internal.js'; +import { BadRequestError, SuccessMessageResponse, SuccessResponse, doiService } from '../../internal.js'; -export const checkMintability = async (req: Request, res: Response, next: NextFunction) => { +export const checkMintability = async (req: Request, res: Response) => { const { uuid } = req.params; if (!uuid) throw new BadRequestError(); await doiService.checkMintability(uuid); new SuccessMessageResponse().send(res); }; + +export const getDoi = async (req: Request, res: Response) => { + const { identifier } = req.params; + if (!identifier) throw new BadRequestError(); + + const doi = await doiService.getDoiByDpidOrUuid(identifier); + new SuccessResponse(doi).send(res); +}; diff --git a/desci-server/src/core/doi/error.ts b/desci-server/src/core/doi/error.ts new file mode 100644 index 00000000..1b2ad6f4 --- /dev/null +++ b/desci-server/src/core/doi/error.ts @@ -0,0 +1,41 @@ +export enum DoiErrorType { + DUPLICATE_MINT = 'DuplicateDoiError', + NO_MANUSCRIPT = 'NoManuscriptError', + BAD_METADATA = 'InvalidManifestError', + INCOMPLETE_ATTESTATIONS = 'ForbiddenError', +} + +export class DoiError extends Error { + name = 'DoiValidationError'; + + constructor( + public type: DoiErrorType, + public message: string = 'Doi Error', + ) { + super(type); + } +} + +export class BadManifestError extends DoiError { + constructor(message = 'Title, Abstract or Contributors is missing') { + super(DoiErrorType.BAD_METADATA, message); + } +} + +export class NoManuscriptError extends DoiError { + constructor(message = 'Node has no manuscript') { + super(DoiErrorType.NO_MANUSCRIPT, message); + } +} + +export class AttestationsError extends DoiError { + constructor(message = 'All required attestations are not claimed or verified!') { + super(DoiErrorType.INCOMPLETE_ATTESTATIONS, message); + } +} + +export class DuplicateMintError extends DoiError { + constructor(message = 'DOI already minted for node') { + super(DoiErrorType.DUPLICATE_MINT, message); + } +} diff --git a/desci-server/src/routes/v1/doi.ts b/desci-server/src/routes/v1/doi.ts index bc4f4b8c..1b2754e7 100644 --- a/desci-server/src/routes/v1/doi.ts +++ b/desci-server/src/routes/v1/doi.ts @@ -1,10 +1,11 @@ import { Router } from 'express'; -import { asyncHander, checkMintability, ensureUser, mintDoi } from '../../internal.js'; +import { asyncHander, checkMintability, ensureUser, getDoi, mintDoi } from '../../internal.js'; const router = Router(); router.post('/check/:uuid', [ensureUser], asyncHander(checkMintability)); router.post('/mint/:uuid', [ensureUser], asyncHander(mintDoi)); +router.get('/:identifier', [ensureUser], asyncHander(getDoi)); export default router; diff --git a/desci-server/src/services/Doi.ts b/desci-server/src/services/Doi.ts index a4276a7c..71dfe7ef 100644 --- a/desci-server/src/services/Doi.ts +++ b/desci-server/src/services/Doi.ts @@ -1,12 +1,13 @@ -import crypto from 'node:crypto'; - import { PdfComponent, ResearchObjectComponentDocumentSubtype, ResearchObjectComponentType, } from '@desci-labs/desci-models'; import { PrismaClient } from '@prisma/client'; +import { v4 } from 'uuid'; +import { DuplicateMintError, NoManuscriptError, BadManifestError, AttestationsError } from '../core/doi/error.js'; +import { logger } from '../logger.js'; import { IndexedResearchObject, getIndexedResearchObjects } from '../theGraph.js'; import { ensureUuidEndsWithDot, hexToCid } from '../utils.js'; @@ -69,8 +70,9 @@ export class DoiService { const { dpid, uuid } = await this.checkMintability(nodeUuid); // todo: handle over logic to cross-ref api service for minting DOIs // mint new doi - const doiSuffix = crypto.randomBytes(8 - dpid.length); + const doiSuffix = v4().substring(0, 8); const doi = `https://doi.org/10.555/${doiSuffix}`; + logger.info({ doiSuffix, doi, uuid }, 'MINT DOI'); return await this.dbClient.doiRecord.create({ data: { uuid, @@ -80,47 +82,9 @@ export class DoiService { }); } - async checkDataOrCode(dpid: string) {} -} - -export enum DoiErrorType { - DUPLICATE_MINT = 'DuplicateDoiError', - NO_MANUSCRIPT = 'NoManuscriptError', - BAD_METADATA = 'InvalidManifestError', - INCOMPLETE_ATTESTATIONS = 'ForbiddenError', -} - -export class DoiError extends Error { - name = 'DoiValidationError'; - - constructor( - public type: DoiErrorType, - public message: string = 'Doi Error', - ) { - super(type); - } -} - -export class BadManifestError extends DoiError { - constructor(message = 'Title, Abstract or Contributors is missing') { - super(DoiErrorType.BAD_METADATA, message); - } -} - -export class NoManuscriptError extends DoiError { - constructor(message = 'Node has no manuscript') { - super(DoiErrorType.NO_MANUSCRIPT, message); - } -} - -export class AttestationsError extends DoiError { - constructor(message = 'All required attestations are not claimed or verified!') { - super(DoiErrorType.INCOMPLETE_ATTESTATIONS, message); - } -} - -export class DuplicateMintError extends DoiError { - constructor(message = 'DOI already minted for node') { - super(DoiErrorType.DUPLICATE_MINT, message); + async getDoiByDpidOrUuid(identifier: string) { + return this.dbClient.doiRecord.findFirst({ + where: { OR: [{ dpid: identifier }, { uuid: ensureUuidEndsWithDot(identifier) }] }, + }); } } diff --git a/desci-server/yarn.lock b/desci-server/yarn.lock index 60f309f2..2fd91603 100644 --- a/desci-server/yarn.lock +++ b/desci-server/yarn.lock @@ -5826,6 +5826,11 @@ dependencies: "@types/node" "*" +"@types/uuid@^9.0.8": + version "9.0.8" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.8.tgz#7545ba4fc3c003d6c756f651f3bf163d8f0f29ba" + integrity sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA== + "@types/webpack@5.28.5": version "5.28.5" resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-5.28.5.tgz#0e9d9a15efa09bbda2cef41356ca4ac2031ea9a2" From 942b7b58051cef0c889c01ec54df44715aa63281 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Tue, 21 May 2024 17:28:06 +0200 Subject: [PATCH 023/278] fix: broken imports --- desci-server/src/core/ApiError.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desci-server/src/core/ApiError.ts b/desci-server/src/core/ApiError.ts index b454b6a0..ded98099 100644 --- a/desci-server/src/core/ApiError.ts +++ b/desci-server/src/core/ApiError.ts @@ -1,7 +1,6 @@ import { Response } from 'express'; import { AttestationError, AttestationErrorType } from '../internal.js'; -import { DoiError, DoiErrorType } from '../services/Doi.js'; import { AuthFailureResponse, @@ -10,6 +9,7 @@ import { InternalErrorResponse, NotFoundResponse, } from './ApiResponse.js'; +import { DoiError, DoiErrorType } from './doi/error.js'; export enum ApiErrorType { BAD_REQUEST = 'BadRequestError', From 426fe0a3f72322851d767d4e9614e208af20e592 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Tue, 21 May 2024 18:59:12 +0000 Subject: [PATCH 024/278] final copy in, api adjusted for dynamic values --- .../src/controllers/pdf/createCover.ts | 21 +- desci-media-isolated/src/services/pdf.ts | 213 ++++++++++++------ desci-media-isolated/src/types/pdf.ts | 13 +- desci-media-isolated/src/utils/utils.ts | 6 + 4 files changed, 182 insertions(+), 71 deletions(-) diff --git a/desci-media-isolated/src/controllers/pdf/createCover.ts b/desci-media-isolated/src/controllers/pdf/createCover.ts index 38c903f1..dd1538d2 100644 --- a/desci-media-isolated/src/controllers/pdf/createCover.ts +++ b/desci-media-isolated/src/controllers/pdf/createCover.ts @@ -13,6 +13,9 @@ export type GeneratePdfCoverRequestBody = { dpid?: string; codeAvailableDpid?: string; dataAvailableDpid?: string; + authors?: string[]; + license: string; + publishDate: string; }; const __filename = fileURLToPath(import.meta.url); @@ -23,15 +26,21 @@ const BASE_TEMP_DIR = path.resolve(__dirname, '../../..', TEMP_DIR); * Generates a cover page inserting a DOI and a DPID link for a PDF file provided via its CID */ export const generatePdfCover = async ( - req: Request, + req: Request< + any, + any, + GeneratePdfCoverRequestBody, + { header?: boolean; headerAllPages?: boolean; authorLimit?: number } + >, res: Response, ) => { - const { cid, doi, dpid, title, codeAvailableDpid, dataAvailableDpid } = req.body; - const { header = true, headerAllPages = false } = req.query; + const { cid, doi, dpid, title, codeAvailableDpid, dataAvailableDpid, license, publishDate, authors } = req.body; + const { header = true, headerAllPages = false, authorLimit } = req.query; try { if (!cid) throw new BadRequestError('Missing cid in request body'); if (!doi) throw new BadRequestError('Missing doi in request body'); - if (!title) throw new BadRequestError('Missing title in request body'); + if (!license) throw new BadRequestError('Missing license in request body'); + if (!publishDate) throw new BadRequestError('Missing publishDate in request body'); const generationTaskId = crypto.randomUUID(); @@ -43,6 +52,10 @@ export const generatePdfCover = async ( title, codeAvailableDpid, dataAvailableDpid, + license, + authors, + publishDate, + authorLimit, }); const fullPdfPath = path.join(BASE_TEMP_DIR, PDF_OUTPUT_DIR, pdfPath); diff --git a/desci-media-isolated/src/services/pdf.ts b/desci-media-isolated/src/services/pdf.ts index 3a9279d6..76a086d5 100644 --- a/desci-media-isolated/src/services/pdf.ts +++ b/desci-media-isolated/src/services/pdf.ts @@ -5,8 +5,8 @@ import path from 'path'; import fs from 'fs'; import * as fsp from 'fs/promises'; import { fileURLToPath } from 'url'; -import { PDFArray, PDFDict, PDFDocument, PDFName, PDFString, StandardFonts } from 'pdf-lib'; -import { readFileToBuffer } from '../utils/utils.js'; +import { PDFArray, PDFDict, PDFDocument, PDFName, PDFString, StandardFonts, rgb } from 'pdf-lib'; +import { readFileToBuffer, startsWithVowel } from '../utils/utils.js'; import { PDF_JOB_TYPE, type AddPdfCoverParams, @@ -20,12 +20,24 @@ const __dirname = path.dirname(__filename); const BASE_TEMP_DIR = path.resolve(__dirname, '../..', TEMP_DIR); export class PdfManipulationService { - static async addPdfCover({ taskId, cid, title, doi, dpid, codeAvailableDpid, dataAvailableDpid }: AddPdfCoverParams) { + static async addPdfCover({ + taskId, + cid, + title, + doi, + dpid, + codeAvailableDpid, + dataAvailableDpid, + authors, + authorLimit, + license, + publishDate, + }: AddPdfCoverParams) { const tempFilePath = path.join(BASE_TEMP_DIR, PDF_FILES_DIR, `${taskId}.pdf`); // Saved pdf to manipulate const outputPdfFileName = this.getPdfPath(PDF_JOB_TYPE.ADD_COVER, cid); const outputFullPath = path.join(BASE_TEMP_DIR, PDF_OUTPUT_DIR, outputPdfFileName); // debugger; - await IpfsService.saveFile(cid, tempFilePath); //failing + await IpfsService.saveFile(cid, tempFilePath); // debugger; try { // Proccess the pdf file to add the cover page @@ -39,7 +51,10 @@ export class PdfManipulationService { /* * Header */ - const topHeader = `DOI ${doi} all code and data is available here`; + const licenseStartsWithVowel = startsWithVowel(license); + const topHeader = `Research object https://doi.org/${doi}, this version posted ${publishDate}. The copyright holder for this research object (which was not certified by peer review) is the author/funder, who has granted DeSci Labs a non-exclsuive license to display the research object in perpetuity. It is made available under a${ + licenseStartsWithVowel ? 'n' : '' + } ${license} license.`; const headerSize = 12; this.drawCenteredMultilineText({ @@ -49,16 +64,16 @@ export class PdfManipulationService { fontSize: headerSize, width, height, - paddingX: 5, - positionY: 0.01, - hyperlink: `https://www.doi.org`, + paddingX: 15, + positionY: 0.04, + hyperlink: `https://doi.org/${doi}`, }); /* * Title */ const titleSize = 30; - const titlePosY = 0.4; + const titlePosY = 0.35; const titleLines = await this.drawCenteredMultilineText({ page: newPage, @@ -74,14 +89,14 @@ export class PdfManipulationService { /* * Authors */ - const authors = 'M. Ansdell, J. Williams, N. van der Marel, J. Carpenter, G. Guidi'; - const authorsSize = 20; + const authorsProcessed = this.formatAuthors(authors || [], authorLimit); + const authorsSize = 18; const titleHeight = titleLines.length * helveticaFont.heightAtSize(titleSize); const authorsPosY = titlePosY + titleHeight / height; const authorsLines = await this.drawCenteredMultilineText({ page: newPage, - text: authors, + text: authorsProcessed, font: helveticaFont, fontSize: authorsSize, width, @@ -94,9 +109,9 @@ export class PdfManipulationService { * Center Text (Artifacts available here) */ const centeredText = 'Data and/or code available at:'; - const centeredTextSize = 16; + const centeredTextSize = 20; const authorsHeight = authorsLines.length * helveticaFont.heightAtSize(authorsSize); - const centeredTextPosY = authorsPosY + authorsHeight / height + 0.02; + const centeredTextPosY = authorsPosY + authorsHeight / height + 0.1; this.drawCenteredMultilineText({ page: newPage, @@ -109,48 +124,86 @@ export class PdfManipulationService { positionY: centeredTextPosY, }); + /* + * DOI URL + */ + const doiUrl = `https://doi.org/${doi}`; + const doiUrlSize = 20; + const centeredTextHeight = helveticaFont.heightAtSize(centeredTextSize); + const doiUrlPosY = centeredTextPosY + centeredTextHeight / height + 0.01; + const doiUrlColor = rgb(0, 0, 1); + + this.drawCenteredMultilineText({ + page: newPage, + text: doiUrl, + font: helveticaFont, + fontSize: doiUrlSize, + width, + height, + paddingX: 100, + positionY: doiUrlPosY, + hyperlink: doiUrl, + color: doiUrlColor, + }); + /* * Badges */ const badges: PdfImageObject[] = []; + + const badgeSize = 50; + if (codeAvailableDpid) { - const codeBadgeBytes = await pdfDoc.embedPng( + const openCodeBytes = await pdfDoc.embedPng( await readFileToBuffer(path.join(__dirname, '../../public/static/code-available.png')), ); - - const codeBadge: PdfImageObject = { - content: codeBadgeBytes, - width: 125, - height: 125, + badges.push({ + content: openCodeBytes, + width: badgeSize, + height: badgeSize, + text: 'Open Code', hyperlink: codeAvailableDpid, - }; - badges.push(codeBadge); + }); } if (dataAvailableDpid) { - const dataBadgeBytes = await pdfDoc.embedPng( + const openDataBytes = await pdfDoc.embedPng( await readFileToBuffer(path.join(__dirname, '../../public/static/data-available.png')), ); - - const dataBadge: PdfImageObject = { - content: dataBadgeBytes, - width: 125, - height: 125, + badges.push({ + content: openDataBytes, + width: badgeSize, + height: badgeSize, + text: 'Open Data', hyperlink: dataAvailableDpid, - }; - badges.push(dataBadge); + }); } + const claimedBadgesTitle = 'Claimed badges:'; + const claimedBadgesTitleSize = 14; + const claimedBadgesTitlePosY = 0.75; + if (badges.length) { + this.drawCenteredMultilineText({ + page: newPage, + text: claimedBadgesTitle, + font: helveticaFont, + fontSize: claimedBadgesTitleSize, + width, + height, + paddingX: 100, + positionY: claimedBadgesTitlePosY, + }); + this.drawCenteredImages({ page: newPage, images: badges, pageWidth: width, pageHeight: height, - positionY: 0.75, + positionY: claimedBadgesTitlePosY + claimedBadgesTitleSize / height + 0.04, gap: 20, + annotateImage: true, }); } - const pdfBytesMod = await pdfDoc.save(); await fsp.writeFile(outputFullPath, pdfBytesMod); @@ -191,6 +244,7 @@ export class PdfManipulationService { paddingX = 0, positionY = 0.5, hyperlink, + color = rgb(0, 0, 0), }: DrawCenteredHelperParams): Promise { const lines: string[] = []; const words = text.split(' '); @@ -225,7 +279,7 @@ export class PdfManipulationService { const x = paddingX + (availableWidth - lineWidth) / 2; const y = startY + i * textHeight; - page.drawText(line, { x, y, size: fontSize, font }); + page.drawText(line, { x, y, size: fontSize, font, color }); if (hyperlink && i === 0) { const linkAnnotation = page.doc.context.obj({ @@ -261,48 +315,61 @@ export class PdfManipulationService { paddingX = 0, gap = 0, positionY = 0.5, + annotateImage = false, // renders image.text besides it + font, }: DrawCenteredImagesParams): Promise { const availableWidth = pageWidth - 2 * paddingX; - const rows: PdfImageObject[][] = []; - let currentRow: PdfImageObject[] = []; - let currentRowWidth = 0; - - for (const image of images) { - if (currentRowWidth + image.width + (currentRow.length > 0 ? gap : 0) > availableWidth) { - rows.push(currentRow); - currentRow = []; - currentRowWidth = 0; + const embedDefaultFont = async () => { + if (!font) { + return await page.doc.embedFont(StandardFonts.Helvetica); } - currentRow.push(image); - currentRowWidth += image.width + (currentRow.length > 1 ? gap : 0); - } + return font; + }; - if (currentRow.length > 0) { - rows.push(currentRow); - } + const embeddedFont = await embedDefaultFont(); + + const imagesWithTextDimensions = await Promise.all( + images.map(async (image) => { + if (annotateImage && image.text) { + const textWidth = embeddedFont.widthOfTextAtSize(image.text, 12); + const textHeight = embeddedFont.heightAtSize(12); + return { ...image, textWidth, textHeight }; + } + return image; + }), + ); + + const totalWidth = imagesWithTextDimensions.reduce( + (sum, image) => sum + image.width + (annotateImage && image.text ? (image.textWidth ?? 0) + gap : 0), + 0, + ); - const rowHeights = rows.map((row) => Math.max(...row.map((image) => image.height))); - const totalHeight = rowHeights.reduce((sum, height) => sum + height, 0) + (rows.length - 1) * gap; - const startY = pageHeight * (1 - positionY) - totalHeight / 2; + const startX = (pageWidth - totalWidth) / 2; - let currentY = startY; + let currentX = startX; - for (const row of rows) { - const rowWidth = row.reduce((sum, image) => sum + image.width, 0) + (row.length - 1) * gap; - let currentX = paddingX + (availableWidth - rowWidth) / 2; + for (const image of imagesWithTextDimensions) { + const x = currentX; + const y = pageHeight * (1 - positionY) - image.height / 2; - const rowHeight = Math.max(...row.map((image) => image.height)); + page.drawImage(image.content, { + x, + y, + width: image.width, + height: image.height, + }); - for (const image of row) { - const x = currentX; - const y = currentY + (rowHeight - image.height) / 2; + if (annotateImage && image.text) { + const textX = x + image.width + 10; + const textY = y + (image.height - (image.textHeight ?? 0)) / 2; - page.drawImage(image.content, { - x, - y, - width: image.width, - height: image.height, + page.drawText(image.text, { + x: textX, + y: textY, + size: 12, + font: embeddedFont, + color: rgb(0, 0, 0), }); if (image.hyperlink) { @@ -328,10 +395,24 @@ export class PdfManipulationService { page.node.set(PDFName.of('Annots'), annotationsArray); } + currentX += image.width + (image.textWidth ?? 0) + gap; + } else { currentX += image.width + gap; } - - currentY += rowHeight + gap; } } + + static formatAuthors(authors: string[], limit: number = 5): string { + const exceedsLimit = authors.length > limit; + const authorsToFormat = exceedsLimit ? authors.slice(0, limit) : authors; + + const formattedAuthors = authorsToFormat.map((author) => { + const names = author.trim().split(' '); + const lastName = names[names.length - 1]; + const firstInitial = names[0][0].toUpperCase(); + return `${firstInitial}. ${lastName}`; + }); + + return exceedsLimit ? `${formattedAuthors.join(', ')}, et al.` : formattedAuthors.join(', '); + } } diff --git a/desci-media-isolated/src/types/pdf.ts b/desci-media-isolated/src/types/pdf.ts index 8044c40b..4c5b78ac 100644 --- a/desci-media-isolated/src/types/pdf.ts +++ b/desci-media-isolated/src/types/pdf.ts @@ -1,4 +1,4 @@ -import type { PDFFont, PDFImage, PDFPage } from 'pdf-lib'; +import type { PDFFont, PDFImage, PDFPage, Color } from 'pdf-lib'; export enum PDF_JOB_TYPE { ADD_COVER = 'cover', @@ -12,6 +12,11 @@ export interface AddPdfCoverParams { dpid?: string; codeAvailableDpid?: string; dataAvailableDpid?: string; + reprodEnabledDpid?: string; + authors?: string[]; + authorLimit?: number; + license: string; + publishDate: string; } export interface DrawCenteredHelperParams { @@ -24,6 +29,7 @@ export interface DrawCenteredHelperParams { paddingX?: number; positionY?: number; // 0-1, vertical alignment, e.g. 0.5 is the center. hyperlink?: string; + color?: Color; } export interface PdfImageObject { @@ -31,6 +37,9 @@ export interface PdfImageObject { width: number; height: number; hyperlink?: string; + text?: string; + textWidth?: number; + textHeight?: number; } export interface DrawCenteredImagesParams { page: PDFPage; @@ -40,4 +49,6 @@ export interface DrawCenteredImagesParams { paddingX?: number; gap?: number; // Gap between images if multiple are passed into the array. positionY?: number; // 0-1, vertical alignment, e.g. 0.5 is the center. + annotateImage?: boolean; // renders image.text besides it + font?: PDFFont; } diff --git a/desci-media-isolated/src/utils/utils.ts b/desci-media-isolated/src/utils/utils.ts index 37e9ede8..807edf88 100644 --- a/desci-media-isolated/src/utils/utils.ts +++ b/desci-media-isolated/src/utils/utils.ts @@ -4,3 +4,9 @@ export async function readFileToBuffer(filePath: string) { const fileBuffer = await fs.readFile(filePath); return fileBuffer; } + +export function startsWithVowel(str: string) { + const vowels = ['a', 'e', 'i', 'o', 'u']; + const firstChar = str.toLowerCase()[0]; + return vowels.includes(firstChar); +} From 05c5de07291cd404419cbb613e27c5ebff17358f Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Wed, 22 May 2024 12:18:07 +0000 Subject: [PATCH 025/278] update backend cover api endpoint/service for new changes --- .../nodes/preparePublishPackage.ts | 8 +-- desci-server/src/services/PublishPackage.ts | 57 +++++++++++++++++-- 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/desci-server/src/controllers/nodes/preparePublishPackage.ts b/desci-server/src/controllers/nodes/preparePublishPackage.ts index bc6db30d..5b2bb53d 100644 --- a/desci-server/src/controllers/nodes/preparePublishPackage.ts +++ b/desci-server/src/controllers/nodes/preparePublishPackage.ts @@ -44,6 +44,7 @@ export const preparePublishPackage = async ( codeAvailableDpid, dataAvailableDpid, }); + debugger; logger.trace({ fn: 'Retrieving Publish Package' }); if (!nodeUuid) return res.status(400).json({ ok: false, error: 'nodeUuid is required.' }); @@ -61,9 +62,6 @@ export const preparePublishPackage = async ( if (!node) return res.status(404).json({ ok: false, error: 'Node not found' }); const manifest = await getManifestByCid(manifestCid); - const title = manifest.title; - - const dpid = manifest?.dpid.id; // debugger; const { pdfCid: distPdfCid } = await publishPackageService.prepareDistributionPdf({ @@ -72,8 +70,8 @@ export const preparePublishPackage = async ( dataAvailableDpid, node, doi, - dpid, - title, + manifest, + manifestCid, }); return res.status(200).json({ ok: true, distPdfCid }); diff --git a/desci-server/src/services/PublishPackage.ts b/desci-server/src/services/PublishPackage.ts index bd9a737f..98aff80c 100644 --- a/desci-server/src/services/PublishPackage.ts +++ b/desci-server/src/services/PublishPackage.ts @@ -1,8 +1,11 @@ +import { ResearchObjectV1 } from '@desci-labs/desci-models'; import { Node } from '@prisma/client'; import axios from 'axios'; import { prisma } from '../client.js'; import { logger as parentLogger } from '../logger.js'; +import { getIndexedResearchObjects } from '../theGraph.js'; +import { hexToCid } from '../utils.js'; import { pinFile } from './ipfs.js'; @@ -12,8 +15,8 @@ export type PrepareDistributionPdfParams = { dataAvailableDpid?: string; node: Node; // Title extraction for now doi: string; // Temporary till we have DOI system operational - dpid: string; - title: string; + manifest: ResearchObjectV1; + manifestCid: string; }; type PrepareDistributionPdfResult = { @@ -29,7 +32,8 @@ class PublishPackageService { dataAvailableDpid, node, doi, - title, + manifest, + manifestCid, }: PrepareDistributionPdfParams): Promise { // Check if distro PDF already exists const existingDistributionPdf = await prisma.distributionPdfs.findFirst({ @@ -45,10 +49,17 @@ class PublishPackageService { return null; } + const title = manifest.title; + const dpid = manifest.dpid.id; + const license = manifest.defaultLicense; + const publishTime = await this.retrieveBlockTimeByManifestCid(node.uuid, manifestCid); + const publishDate = PublishPackageService.convertUnixTimestampToDate(publishTime); + const authors = manifest.authors?.map((author) => author.name); + // Generate the PDF with the cover const coverPdfStream = await axios.post( `${process.env.ISOLATED_MEDIA_SERVER_URL}/v1/pdf/addCover`, - { cid: pdfCid, doi, title, codeAvailableDpid, dataAvailableDpid }, + { cid: pdfCid, doi, title, codeAvailableDpid, dataAvailableDpid, dpid, license, publishDate, authors }, { responseType: 'stream', }, @@ -66,6 +77,44 @@ class PublishPackageService { // Return the CID return { pdfCid: pinned.cid }; } + + async retrieveBlockTimeByManifestCid(uuid: string, manifestCid: string) { + const { researchObjects } = await getIndexedResearchObjects([uuid]); + if (!researchObjects.length) + this.logger.warn({ fn: 'retrieveBlockTimeByManifestCid' }, `No research objects found for nodeUuid ${uuid}`); + const indexedNode = researchObjects[0]; + const targetVersion = indexedNode.versions.find((v) => hexToCid(v.cid) === manifestCid); + if (!targetVersion) { + this.logger.warn( + { fn: 'retrieveBlockTimeByManifestCid', uuid, manifestCid }, + `No version match was found for nodeUuid/manifestCid`, + ); + return '-1'; + } + return targetVersion.time; + } + + static convertUnixTimestampToDate(unixTimestamp: string): string { + const date = new Date(Number(unixTimestamp) * 1000); + const formattedDate = date.toLocaleString('en-US', { + month: 'long', + day: 'numeric', + year: 'numeric', + }); + return formattedDate; + } } export const publishPackageService = new PublishPackageService(); + +export type GeneratePdfCoverRequestBody = { + cid: string; + doi: string; + title: string; + dpid?: string; + codeAvailableDpid?: string; + dataAvailableDpid?: string; + authors?: string[]; + license: string; + publishDate: string; +}; From 2c55bdaae1045a24a4c00e3cef8456c62a8ae51e Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Wed, 22 May 2024 16:29:52 +0000 Subject: [PATCH 026/278] attestation claims from attestation api linked up --- .../nodes/preparePublishPackage.ts | 12 +++-------- desci-server/src/services/PublishPackage.ts | 21 ++++++++++++++----- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/desci-server/src/controllers/nodes/preparePublishPackage.ts b/desci-server/src/controllers/nodes/preparePublishPackage.ts index 5b2bb53d..7ae512a7 100644 --- a/desci-server/src/controllers/nodes/preparePublishPackage.ts +++ b/desci-server/src/controllers/nodes/preparePublishPackage.ts @@ -13,8 +13,6 @@ export type PreparePublishPackageReqBodyParams = { doi: string; // temp till DOI system is operational dpid: string; nodeUuid: string; - codeAvailableDpid?: string; - dataAvailableDpid?: string; }; type PreparePublishPackageResponse = { @@ -35,16 +33,14 @@ export const preparePublishPackage = async ( req: Request, res: Response, ) => { - const { pdfCid, doi, nodeUuid, codeAvailableDpid, dataAvailableDpid, manifestCid } = req.body; + const { pdfCid, doi, nodeUuid, manifestCid } = req.body; const logger = parentLogger.child({ module: 'NODES::PreparePublishPackageController', pdfCid, doi, nodeUuid, - codeAvailableDpid, - dataAvailableDpid, }); - debugger; + // debugger; logger.trace({ fn: 'Retrieving Publish Package' }); if (!nodeUuid) return res.status(400).json({ ok: false, error: 'nodeUuid is required.' }); @@ -62,12 +58,10 @@ export const preparePublishPackage = async ( if (!node) return res.status(404).json({ ok: false, error: 'Node not found' }); const manifest = await getManifestByCid(manifestCid); - + if (!manifest) return res.status(404).json({ ok: false, error: 'Manifest not found' }); // debugger; const { pdfCid: distPdfCid } = await publishPackageService.prepareDistributionPdf({ pdfCid, - codeAvailableDpid, - dataAvailableDpid, node, doi, manifest, diff --git a/desci-server/src/services/PublishPackage.ts b/desci-server/src/services/PublishPackage.ts index 98aff80c..1af52ba6 100644 --- a/desci-server/src/services/PublishPackage.ts +++ b/desci-server/src/services/PublishPackage.ts @@ -7,12 +7,11 @@ import { logger as parentLogger } from '../logger.js'; import { getIndexedResearchObjects } from '../theGraph.js'; import { hexToCid } from '../utils.js'; +import { attestationService } from './Attestation.js'; import { pinFile } from './ipfs.js'; export type PrepareDistributionPdfParams = { pdfCid: string; - codeAvailableDpid?: string; - dataAvailableDpid?: string; node: Node; // Title extraction for now doi: string; // Temporary till we have DOI system operational manifest: ResearchObjectV1; @@ -28,8 +27,6 @@ class PublishPackageService { async prepareDistributionPdf({ pdfCid, - codeAvailableDpid, - dataAvailableDpid, node, doi, manifest, @@ -56,10 +53,24 @@ class PublishPackageService { const publishDate = PublishPackageService.convertUnixTimestampToDate(publishTime); const authors = manifest.authors?.map((author) => author.name); + const attestations = await attestationService.getAllNodeAttestations(dpid); + + const openCodeAttestation = attestations.find((a) => a.attestationId === 15); + const openDataAttestation = attestations.find((a) => a.attestationId === 16); + + const attestationLinks = { + ...(openCodeAttestation && { + codeAvailableDpid: `https://beta.dpid.org/${dpid}/attestations/${openCodeAttestation.id}`, + }), + ...(openDataAttestation && { + dataAvailableDpid: `https://beta.dpid.org/${dpid}/attestations/${openDataAttestation.id}`, + }), + }; + // Generate the PDF with the cover const coverPdfStream = await axios.post( `${process.env.ISOLATED_MEDIA_SERVER_URL}/v1/pdf/addCover`, - { cid: pdfCid, doi, title, codeAvailableDpid, dataAvailableDpid, dpid, license, publishDate, authors }, + { cid: pdfCid, doi, title, ...attestationLinks, dpid, license, publishDate, authors }, { responseType: 'stream', }, From be9606ffb45636fd27be95906d263e000c9f21cf Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Wed, 22 May 2024 17:16:26 +0000 Subject: [PATCH 027/278] clean --- desci-server/src/services/PublishPackage.ts | 21 ++------------------ desci-server/src/services/PublishServices.ts | 19 +++++++++++++++++- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/desci-server/src/services/PublishPackage.ts b/desci-server/src/services/PublishPackage.ts index 1af52ba6..34a2c138 100644 --- a/desci-server/src/services/PublishPackage.ts +++ b/desci-server/src/services/PublishPackage.ts @@ -4,11 +4,10 @@ import axios from 'axios'; import { prisma } from '../client.js'; import { logger as parentLogger } from '../logger.js'; -import { getIndexedResearchObjects } from '../theGraph.js'; -import { hexToCid } from '../utils.js'; import { attestationService } from './Attestation.js'; import { pinFile } from './ipfs.js'; +import { publishServices } from './PublishServices.js'; export type PrepareDistributionPdfParams = { pdfCid: string; @@ -49,7 +48,7 @@ class PublishPackageService { const title = manifest.title; const dpid = manifest.dpid.id; const license = manifest.defaultLicense; - const publishTime = await this.retrieveBlockTimeByManifestCid(node.uuid, manifestCid); + const publishTime = await publishServices.retrieveBlockTimeByManifestCid(node.uuid, manifestCid); const publishDate = PublishPackageService.convertUnixTimestampToDate(publishTime); const authors = manifest.authors?.map((author) => author.name); @@ -89,22 +88,6 @@ class PublishPackageService { return { pdfCid: pinned.cid }; } - async retrieveBlockTimeByManifestCid(uuid: string, manifestCid: string) { - const { researchObjects } = await getIndexedResearchObjects([uuid]); - if (!researchObjects.length) - this.logger.warn({ fn: 'retrieveBlockTimeByManifestCid' }, `No research objects found for nodeUuid ${uuid}`); - const indexedNode = researchObjects[0]; - const targetVersion = indexedNode.versions.find((v) => hexToCid(v.cid) === manifestCid); - if (!targetVersion) { - this.logger.warn( - { fn: 'retrieveBlockTimeByManifestCid', uuid, manifestCid }, - `No version match was found for nodeUuid/manifestCid`, - ); - return '-1'; - } - return targetVersion.time; - } - static convertUnixTimestampToDate(unixTimestamp: string): string { const date = new Date(Number(unixTimestamp) * 1000); const formattedDate = date.toLocaleString('en-US', { diff --git a/desci-server/src/services/PublishServices.ts b/desci-server/src/services/PublishServices.ts index e1072be7..c0465905 100644 --- a/desci-server/src/services/PublishServices.ts +++ b/desci-server/src/services/PublishServices.ts @@ -2,9 +2,10 @@ import { Node } from '@prisma/client'; import sgMail from '@sendgrid/mail'; import { prisma } from '../client.js'; -import { getNodeVersion } from '../internal.js'; +import { getNodeVersion, hexToCid } from '../internal.js'; import { logger as parentLogger } from '../logger.js'; import { NodeUpdatedEmailHtml } from '../templates/emails/utils/emailRenderer.js'; +import { getIndexedResearchObjects } from '../theGraph.js'; import { contributorService } from './Contributors.js'; import { getLatestManifestFromNode } from './manifestRepo.js'; @@ -61,6 +62,22 @@ export class PublishServices { return true; } + + async retrieveBlockTimeByManifestCid(uuid: string, manifestCid: string) { + const { researchObjects } = await getIndexedResearchObjects([uuid]); + if (!researchObjects.length) + logger.warn({ fn: 'retrieveBlockTimeByManifestCid' }, `No research objects found for nodeUuid ${uuid}`); + const indexedNode = researchObjects[0]; + const targetVersion = indexedNode.versions.find((v) => hexToCid(v.cid) === manifestCid); + if (!targetVersion) { + logger.warn( + { fn: 'retrieveBlockTimeByManifestCid', uuid, manifestCid }, + `No version match was found for nodeUuid/manifestCid`, + ); + return '-1'; + } + return targetVersion.time; + } } export interface NodeUpdatedEmailProps { From b6722bcd69e11e7cd4ac98778780e4df57e9828d Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Wed, 22 May 2024 17:42:47 +0000 Subject: [PATCH 028/278] fire off dist manuscript email on publish package gen --- .../nodes/preparePublishPackage.ts | 4 ++++ desci-server/src/controllers/nodes/publish.ts | 2 +- desci-server/src/services/PublishServices.ts | 3 ++- .../src/templates/emails/NodeUpdated.tsx | 23 ++++++++++++++++++- 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/desci-server/src/controllers/nodes/preparePublishPackage.ts b/desci-server/src/controllers/nodes/preparePublishPackage.ts index 7ae512a7..75af8059 100644 --- a/desci-server/src/controllers/nodes/preparePublishPackage.ts +++ b/desci-server/src/controllers/nodes/preparePublishPackage.ts @@ -4,6 +4,7 @@ import { prisma } from '../../client.js'; import { logger as parentLogger } from '../../logger.js'; import { getManifestByCid } from '../../services/data/processing.js'; import { publishPackageService } from '../../services/PublishPackage.js'; +import { publishServices } from '../../services/PublishServices.js'; import { CidString } from '../../services/Thumbnails.js'; import { ensureUuidEndsWithDot } from '../../utils.js'; @@ -68,6 +69,9 @@ export const preparePublishPackage = async ( manifestCid, }); + // Fire off email to all contributors + await publishServices.sendVersionUpdateEmailToAllContributors({ node, manuscriptCid: distPdfCid }); + return res.status(200).json({ ok: true, distPdfCid }); } catch (e) { logger.error({ fn: 'preparePublishPackage', error: e.message }); diff --git a/desci-server/src/controllers/nodes/publish.ts b/desci-server/src/controllers/nodes/publish.ts index f905392e..47e5c18e 100644 --- a/desci-server/src/controllers/nodes/publish.ts +++ b/desci-server/src/controllers/nodes/publish.ts @@ -298,7 +298,7 @@ export const publishHandler = async ({ }; // Send an email update to all contributors - await publishServices.sendVersionUpdateEmailToAllContributors({ node }); + // await publishServices.sendVersionUpdateEmailToAllContributors({ node }); /** * NOTE: uncomment when reactivating public ref mirroring diff --git a/desci-server/src/services/PublishServices.ts b/desci-server/src/services/PublishServices.ts index c0465905..15dfbe57 100644 --- a/desci-server/src/services/PublishServices.ts +++ b/desci-server/src/services/PublishServices.ts @@ -17,7 +17,7 @@ const logger = parentLogger.child({ }); export class PublishServices { - async sendVersionUpdateEmailToAllContributors({ node }: { node: Node }) { + async sendVersionUpdateEmailToAllContributors({ node, manuscriptCid }: { node: Node; manuscriptCid: string }) { const contributors = await contributorService.retrieveAllVerifiedContributionsForNode(node); const nodeOwner = await prisma.user.findUnique({ where: { id: node.ownerId } }); const manifest = await getLatestManifestFromNode(node); @@ -38,6 +38,7 @@ export class PublishServices { nodeTitle: node.title, nodeDpid: dpid, versionUpdate: versionPublished, + manuscriptCid: manuscriptCid, }); const emailMsg = { diff --git a/desci-server/src/templates/emails/NodeUpdated.tsx b/desci-server/src/templates/emails/NodeUpdated.tsx index 5fc29aaa..b65e8204 100644 --- a/desci-server/src/templates/emails/NodeUpdated.tsx +++ b/desci-server/src/templates/emails/NodeUpdated.tsx @@ -9,14 +9,23 @@ export interface NodeUpdatedEmailProps { nodeUuid: string; nodeDpid: string; versionUpdate: string; + manuscriptCid: string; } const DAPP_URL = process.env.DAPP_URL || 'http://localhost:3000'; -export const NodeUpdated = ({ nodeOwner, nodeTitle, nodeUuid, nodeDpid, versionUpdate }: NodeUpdatedEmailProps) => { +export const NodeUpdated = ({ + nodeOwner, + nodeTitle, + nodeUuid, + nodeDpid, + versionUpdate, + manuscriptCid, +}: NodeUpdatedEmailProps) => { if (nodeUuid?.endsWith('.') || nodeUuid?.endsWith('=')) nodeUuid = nodeUuid.slice(0, -1); nodeOwner = nodeOwner || 'The node owner'; const nodeUrl = `${DAPP_URL}/dpid/${nodeDpid}/${versionUpdate}`; + const manuscriptUrl = `${process.env.IPFS_RESOLVER_OVERRIDE}/${manuscriptCid}`; return ( @@ -45,6 +54,18 @@ export const NodeUpdated = ({ nodeOwner, nodeTitle, nodeUuid, nodeDpid, versionU > View Version {versionUpdate} + From 3610ad37adaf9d7fceef6443b64c34bd7ee9df36 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Wed, 22 May 2024 18:39:26 +0000 Subject: [PATCH 029/278] change license logic, prioritize manuscript license if exists --- desci-server/src/services/PublishPackage.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/desci-server/src/services/PublishPackage.ts b/desci-server/src/services/PublishPackage.ts index 34a2c138..3cf5800a 100644 --- a/desci-server/src/services/PublishPackage.ts +++ b/desci-server/src/services/PublishPackage.ts @@ -47,7 +47,7 @@ class PublishPackageService { const title = manifest.title; const dpid = manifest.dpid.id; - const license = manifest.defaultLicense; + const license = PublishPackageService.extractManuscriptLicense(manifest, pdfCid); const publishTime = await publishServices.retrieveBlockTimeByManifestCid(node.uuid, manifestCid); const publishDate = PublishPackageService.convertUnixTimestampToDate(publishTime); const authors = manifest.authors?.map((author) => author.name); @@ -97,6 +97,13 @@ class PublishPackageService { }); return formattedDate; } + + static extractManuscriptLicense(manifest: ResearchObjectV1, manuscriptCid): string { + const manuscriptComponent = manifest.components?.find( + (c) => c.payload.url === manuscriptCid || c.payload.cid === manuscriptCid, + ); + return manuscriptComponent.payload.licenseType ?? manifest.defaultLicense; + } } export const publishPackageService = new PublishPackageService(); From 76213a1d02554d83efb270c4c75cd1f1a3f69ab5 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Thu, 23 May 2024 20:05:26 +0000 Subject: [PATCH 030/278] head call for ext pdfs to check mime type before processing --- .../src/services/data/externalUrlProcessing.ts | 15 +++++++++++---- desci-server/src/services/data/processing.ts | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/desci-server/src/services/data/externalUrlProcessing.ts b/desci-server/src/services/data/externalUrlProcessing.ts index d78d681e..5a308301 100644 --- a/desci-server/src/services/data/externalUrlProcessing.ts +++ b/desci-server/src/services/data/externalUrlProcessing.ts @@ -128,10 +128,17 @@ export async function processExternalUrlDataToIpfs({ */ if (componentType === ResearchObjectComponentType.PDF) { const url = externalUrl.url; - const res = await axios.get(url, { responseType: 'arraybuffer' }); - const buffer = Buffer.from(res.data, 'binary'); - externalUrlFiles = [{ path: externalUrl.path, content: buffer }]; - externalUrlTotalSizeBytes = buffer.length; + const response = await axios.head(url); + const contentType = response.headers['content-type']; + + if (contentType === 'application/pdf') { + const res = await axios.get(url, { responseType: 'arraybuffer' }); + const buffer = Buffer.from(res.data, 'binary'); + externalUrlFiles = [{ path: externalUrl.path, content: buffer }]; + externalUrlTotalSizeBytes = buffer.length; + } else { + throw new Error('Invalid file type. Only PDF files are supported.'); + } } } catch (e) { logger.warn( diff --git a/desci-server/src/services/data/processing.ts b/desci-server/src/services/data/processing.ts index e7c1b575..01ac09b0 100644 --- a/desci-server/src/services/data/processing.ts +++ b/desci-server/src/services/data/processing.ts @@ -14,6 +14,7 @@ import { } from '@desci-labs/desci-models'; import { User, Node, DataType, Prisma } from '@prisma/client'; import axios from 'axios'; +import { CID } from 'multiformats'; import { v4 } from 'uuid'; import { prisma } from '../../client.js'; @@ -59,7 +60,6 @@ import { createNotEnoughSpaceError, createUnhandledError, } from './processingErrors.js'; -import { CID } from 'multiformats'; interface ProcessS3DataToIpfsParams { files: any[]; From 9091b1818e2f68eb5113e051eeb0933fccb8e486 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Fri, 24 May 2024 10:01:45 +0000 Subject: [PATCH 031/278] adjust distPdfs table for unique generations across versions --- .../migration.sql | 15 +++++++++++++++ desci-server/prisma/schema.prisma | 3 ++- desci-server/src/services/PublishPackage.ts | 4 ++-- 3 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 desci-server/prisma/migrations/20240524095750_add_manifest_cid_dist_pdfs_table/migration.sql diff --git a/desci-server/prisma/migrations/20240524095750_add_manifest_cid_dist_pdfs_table/migration.sql b/desci-server/prisma/migrations/20240524095750_add_manifest_cid_dist_pdfs_table/migration.sql new file mode 100644 index 00000000..2bb111ea --- /dev/null +++ b/desci-server/prisma/migrations/20240524095750_add_manifest_cid_dist_pdfs_table/migration.sql @@ -0,0 +1,15 @@ +/* + Warnings: + + - A unique constraint covering the columns `[nodeUuid,originalPdfCid,manifestCid]` on the table `DistributionPdfs` will be added. If there are existing duplicate values, this will fail. + - Added the required column `manifestCid` to the `DistributionPdfs` table without a default value. This is not possible if the table is not empty. + +*/ +-- DropIndex +DROP INDEX "DistributionPdfs_nodeUuid_originalPdfCid_key"; + +-- AlterTable +ALTER TABLE "DistributionPdfs" ADD COLUMN "manifestCid" TEXT NOT NULL; + +-- CreateIndex +CREATE UNIQUE INDEX "DistributionPdfs_nodeUuid_originalPdfCid_manifestCid_key" ON "DistributionPdfs"("nodeUuid", "originalPdfCid", "manifestCid"); diff --git a/desci-server/prisma/schema.prisma b/desci-server/prisma/schema.prisma index 6910e8bb..eafd4f4b 100755 --- a/desci-server/prisma/schema.prisma +++ b/desci-server/prisma/schema.prisma @@ -480,11 +480,12 @@ model NodeThumbnails { model DistributionPdfs { id Int @id @default(autoincrement()) originalPdfCid String + manifestCid String nodeUuid String distPdfCid String node Node @relation(fields: [nodeUuid], references: [uuid]) - @@unique([nodeUuid, originalPdfCid]) + @@unique([nodeUuid, originalPdfCid, manifestCid]) } // The glue between a manifest contributor entry and a nodes profile diff --git a/desci-server/src/services/PublishPackage.ts b/desci-server/src/services/PublishPackage.ts index 3cf5800a..27646e71 100644 --- a/desci-server/src/services/PublishPackage.ts +++ b/desci-server/src/services/PublishPackage.ts @@ -33,7 +33,7 @@ class PublishPackageService { }: PrepareDistributionPdfParams): Promise { // Check if distro PDF already exists const existingDistributionPdf = await prisma.distributionPdfs.findFirst({ - where: { originalPdfCid: pdfCid }, + where: { originalPdfCid: pdfCid, manifestCid }, }); if (existingDistributionPdf) { @@ -79,7 +79,7 @@ class PublishPackageService { // Save it to the database await prisma.distributionPdfs.create({ - data: { originalPdfCid: pdfCid, distPdfCid: pinned.cid, nodeUuid: node.uuid }, + data: { originalPdfCid: pdfCid, distPdfCid: pinned.cid, nodeUuid: node.uuid, manifestCid }, }); // LATER: Add data ref From 3915588180ee34a820af9ae484f91ad7cb44bc42 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Fri, 24 May 2024 10:28:44 +0000 Subject: [PATCH 032/278] fix payload udf crash --- desci-server/src/services/PublishPackage.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/desci-server/src/services/PublishPackage.ts b/desci-server/src/services/PublishPackage.ts index 27646e71..73a06d2d 100644 --- a/desci-server/src/services/PublishPackage.ts +++ b/desci-server/src/services/PublishPackage.ts @@ -36,6 +36,7 @@ class PublishPackageService { where: { originalPdfCid: pdfCid, manifestCid }, }); + // debugger; if (existingDistributionPdf) { return { pdfCid: existingDistributionPdf.distPdfCid }; } @@ -44,7 +45,6 @@ class PublishPackageService { this.logger.error('process.env.ISOLATED_MEDIA_SERVER_URL is not defined'); return null; } - const title = manifest.title; const dpid = manifest.dpid.id; const license = PublishPackageService.extractManuscriptLicense(manifest, pdfCid); @@ -100,9 +100,9 @@ class PublishPackageService { static extractManuscriptLicense(manifest: ResearchObjectV1, manuscriptCid): string { const manuscriptComponent = manifest.components?.find( - (c) => c.payload.url === manuscriptCid || c.payload.cid === manuscriptCid, + (c) => c.payload?.url === manuscriptCid || c.payload?.cid === manuscriptCid, ); - return manuscriptComponent.payload.licenseType ?? manifest.defaultLicense; + return manuscriptComponent?.payload?.licenseType ?? manifest.defaultLicense; } } From 7834fbd7dcb4fec1208627ab8e4015ae4ccedbeb Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Fri, 24 May 2024 10:59:35 +0000 Subject: [PATCH 033/278] fixed header hyperlink rect --- desci-media-isolated/src/services/pdf.ts | 55 ++++++++++++++---------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/desci-media-isolated/src/services/pdf.ts b/desci-media-isolated/src/services/pdf.ts index 76a086d5..f918b8d6 100644 --- a/desci-media-isolated/src/services/pdf.ts +++ b/desci-media-isolated/src/services/pdf.ts @@ -273,6 +273,11 @@ export class PdfManipulationService { const totalHeight = lines.length * textHeight; const startY = height * (1 - positionY) - totalHeight / 2; + let minX = width; + let maxX = 0; + let minY = height; + let maxY = 0; + for (let i = 0; i < lines.length; i++) { const line = lines[i]; const lineWidth = font.widthOfTextAtSize(line, fontSize); @@ -281,29 +286,35 @@ export class PdfManipulationService { page.drawText(line, { x, y, size: fontSize, font, color }); - if (hyperlink && i === 0) { - const linkAnnotation = page.doc.context.obj({ - Type: 'Annot', - Subtype: 'Link', - Rect: [x, y, x + lineWidth, y + textHeight], - Border: [0, 0, 2], - C: [0, 0, 1], - A: { - Type: 'Action', - S: 'URI', - URI: PDFString.of(hyperlink), - }, - }) as PDFDict; - - const linkAnnotationRef = page.doc.context.register(linkAnnotation); - - const annotations = page.node.Annots() as PDFArray | undefined; - const annotationsArray = annotations ?? page.doc.context.obj([]); - annotationsArray.push(linkAnnotationRef); - - page.node.set(PDFName.of('Annots'), annotationsArray); - } + minX = Math.min(minX, x); + maxX = Math.max(maxX, x + lineWidth); + minY = Math.min(minY, y); + maxY = Math.max(maxY, y + textHeight); } + + if (hyperlink) { + const linkAnnotation = page.doc.context.obj({ + Type: 'Annot', + Subtype: 'Link', + Rect: [minX, minY, maxX, maxY], + Border: [0, 0, 2], + C: [0, 0, 1], + A: { + Type: 'Action', + S: 'URI', + URI: PDFString.of(hyperlink), + }, + }) as PDFDict; + + const linkAnnotationRef = page.doc.context.register(linkAnnotation); + + const annotations = page.node.Annots() as PDFArray | undefined; + const annotationsArray = annotations ?? page.doc.context.obj([]); + annotationsArray.push(linkAnnotationRef); + + page.node.set(PDFName.of('Annots'), annotationsArray); + } + return lines; } From 90b3e8cc26eb73201792bd354555be6dcc81ec20 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Fri, 24 May 2024 11:16:46 +0000 Subject: [PATCH 034/278] add auto hyperlink detection to text drawing helper for highlighting --- desci-media-isolated/src/services/pdf.ts | 47 ++++++++++++++++++++++-- desci-media-isolated/src/types/pdf.ts | 1 + 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/desci-media-isolated/src/services/pdf.ts b/desci-media-isolated/src/services/pdf.ts index f918b8d6..f50cc57f 100644 --- a/desci-media-isolated/src/services/pdf.ts +++ b/desci-media-isolated/src/services/pdf.ts @@ -243,8 +243,8 @@ export class PdfManipulationService { height, paddingX = 0, positionY = 0.5, - hyperlink, color = rgb(0, 0, 0), + hyperlinkColor = rgb(0, 0, 1), }: DrawCenteredHelperParams): Promise { const lines: string[] = []; const words = text.split(' '); @@ -284,7 +284,42 @@ export class PdfManipulationService { const x = paddingX + (availableWidth - lineWidth) / 2; const y = startY + i * textHeight; - page.drawText(line, { x, y, size: fontSize, font, color }); + const urlPattern = /(https?:\/\/[\w./%-]+)/g; + let match; + let textIndex = 0; + + while ((match = urlPattern.exec(line)) !== null) { + const url = match[0]; + const urlStartIndex = match.index; + const urlEndIndex = urlStartIndex + url.length; + + // Text before the URL + const textBeforeUrl = line.slice(textIndex, urlStartIndex); + page.drawText(textBeforeUrl, { + x: x + font.widthOfTextAtSize(line.slice(0, textIndex), fontSize), + y, + size: fontSize, + font, + color, + }); + + // URL text + const urlWidth = font.widthOfTextAtSize(url, fontSize); + const urlX = x + font.widthOfTextAtSize(line.slice(0, urlStartIndex), fontSize); + page.drawText(url, { x: urlX, y, size: fontSize, font, color: hyperlinkColor }); + + textIndex = urlEndIndex; + } + + // Text after URL + const textAfterUrl = line.slice(textIndex); + page.drawText(textAfterUrl, { + x: x + font.widthOfTextAtSize(line.slice(0, textIndex), fontSize), + y, + size: fontSize, + font, + color, + }); minX = Math.min(minX, x); maxX = Math.max(maxX, x + lineWidth); @@ -292,7 +327,11 @@ export class PdfManipulationService { maxY = Math.max(maxY, y + textHeight); } - if (hyperlink) { + const urlPattern = /(https?:\/\/[\w./%-]+)/g; + let match; + + while ((match = urlPattern.exec(text)) !== null) { + const url = match[0]; const linkAnnotation = page.doc.context.obj({ Type: 'Annot', Subtype: 'Link', @@ -302,7 +341,7 @@ export class PdfManipulationService { A: { Type: 'Action', S: 'URI', - URI: PDFString.of(hyperlink), + URI: PDFString.of(url), }, }) as PDFDict; diff --git a/desci-media-isolated/src/types/pdf.ts b/desci-media-isolated/src/types/pdf.ts index 4c5b78ac..4349bce8 100644 --- a/desci-media-isolated/src/types/pdf.ts +++ b/desci-media-isolated/src/types/pdf.ts @@ -30,6 +30,7 @@ export interface DrawCenteredHelperParams { positionY?: number; // 0-1, vertical alignment, e.g. 0.5 is the center. hyperlink?: string; color?: Color; + hyperlinkColor: Color; } export interface PdfImageObject { From ea05372c466ce3266a18c6f5e504e93039c9ca63 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Fri, 24 May 2024 11:42:36 +0000 Subject: [PATCH 035/278] type fix --- desci-media-isolated/src/types/pdf.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desci-media-isolated/src/types/pdf.ts b/desci-media-isolated/src/types/pdf.ts index 4349bce8..f429f933 100644 --- a/desci-media-isolated/src/types/pdf.ts +++ b/desci-media-isolated/src/types/pdf.ts @@ -30,7 +30,7 @@ export interface DrawCenteredHelperParams { positionY?: number; // 0-1, vertical alignment, e.g. 0.5 is the center. hyperlink?: string; color?: Color; - hyperlinkColor: Color; + hyperlinkColor?: Color; } export interface PdfImageObject { From 1b31d3c7e7b6b397f9b33dd9d964aa944509d83a Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Mon, 27 May 2024 08:05:12 +0000 Subject: [PATCH 036/278] DOIs made optional for cover generation, falling back on DPIDs --- .../src/controllers/pdf/createCover.ts | 6 +++--- desci-media-isolated/src/services/pdf.ts | 13 +++++++------ desci-media-isolated/src/types/pdf.ts | 4 ++-- .../src/controllers/nodes/preparePublishPackage.ts | 4 ++-- desci-server/src/services/PublishPackage.ts | 7 ++++++- 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/desci-media-isolated/src/controllers/pdf/createCover.ts b/desci-media-isolated/src/controllers/pdf/createCover.ts index dd1538d2..d366c6fc 100644 --- a/desci-media-isolated/src/controllers/pdf/createCover.ts +++ b/desci-media-isolated/src/controllers/pdf/createCover.ts @@ -8,9 +8,9 @@ import { PdfManipulationService } from '../../services/pdf.js'; export type GeneratePdfCoverRequestBody = { cid: string; - doi: string; + doi?: string; // Optional, will use DPID if unavailable title: string; - dpid?: string; + dpid: string; codeAvailableDpid?: string; dataAvailableDpid?: string; authors?: string[]; @@ -38,7 +38,7 @@ export const generatePdfCover = async ( const { header = true, headerAllPages = false, authorLimit } = req.query; try { if (!cid) throw new BadRequestError('Missing cid in request body'); - if (!doi) throw new BadRequestError('Missing doi in request body'); + if (!dpid) throw new BadRequestError('Missing dpid in request body'); if (!license) throw new BadRequestError('Missing license in request body'); if (!publishDate) throw new BadRequestError('Missing publishDate in request body'); diff --git a/desci-media-isolated/src/services/pdf.ts b/desci-media-isolated/src/services/pdf.ts index f50cc57f..51b2410e 100644 --- a/desci-media-isolated/src/services/pdf.ts +++ b/desci-media-isolated/src/services/pdf.ts @@ -33,6 +33,7 @@ export class PdfManipulationService { license, publishDate, }: AddPdfCoverParams) { + const usingDoi = doi ? true : false; const tempFilePath = path.join(BASE_TEMP_DIR, PDF_FILES_DIR, `${taskId}.pdf`); // Saved pdf to manipulate const outputPdfFileName = this.getPdfPath(PDF_JOB_TYPE.ADD_COVER, cid); const outputFullPath = path.join(BASE_TEMP_DIR, PDF_OUTPUT_DIR, outputPdfFileName); @@ -52,7 +53,8 @@ export class PdfManipulationService { * Header */ const licenseStartsWithVowel = startsWithVowel(license); - const topHeader = `Research object https://doi.org/${doi}, this version posted ${publishDate}. The copyright holder for this research object (which was not certified by peer review) is the author/funder, who has granted DeSci Labs a non-exclsuive license to display the research object in perpetuity. It is made available under a${ + const nodeUrl = usingDoi ? `https://doi.org/${doi}` : `https://beta.dpid.org/${dpid}`; + const topHeader = `Research object ${nodeUrl}, this version posted ${publishDate}. The copyright holder for this research object (which was not certified by peer review) is the author/funder, who has granted DeSci Labs a non-exclsuive license to display the research object in perpetuity. It is made available under a${ licenseStartsWithVowel ? 'n' : '' } ${license} license.`; const headerSize = 12; @@ -66,7 +68,7 @@ export class PdfManipulationService { height, paddingX: 15, positionY: 0.04, - hyperlink: `https://doi.org/${doi}`, + hyperlink: nodeUrl, }); /* @@ -125,9 +127,8 @@ export class PdfManipulationService { }); /* - * DOI URL + * NODE URL */ - const doiUrl = `https://doi.org/${doi}`; const doiUrlSize = 20; const centeredTextHeight = helveticaFont.heightAtSize(centeredTextSize); const doiUrlPosY = centeredTextPosY + centeredTextHeight / height + 0.01; @@ -135,14 +136,14 @@ export class PdfManipulationService { this.drawCenteredMultilineText({ page: newPage, - text: doiUrl, + text: nodeUrl, font: helveticaFont, fontSize: doiUrlSize, width, height, paddingX: 100, positionY: doiUrlPosY, - hyperlink: doiUrl, + hyperlink: nodeUrl, color: doiUrlColor, }); diff --git a/desci-media-isolated/src/types/pdf.ts b/desci-media-isolated/src/types/pdf.ts index f429f933..542638db 100644 --- a/desci-media-isolated/src/types/pdf.ts +++ b/desci-media-isolated/src/types/pdf.ts @@ -8,8 +8,8 @@ export interface AddPdfCoverParams { taskId: string; cid: string; title: string; - doi: string; - dpid?: string; + doi?: string; + dpid: string; codeAvailableDpid?: string; dataAvailableDpid?: string; reprodEnabledDpid?: string; diff --git a/desci-server/src/controllers/nodes/preparePublishPackage.ts b/desci-server/src/controllers/nodes/preparePublishPackage.ts index 75af8059..3ae17af2 100644 --- a/desci-server/src/controllers/nodes/preparePublishPackage.ts +++ b/desci-server/src/controllers/nodes/preparePublishPackage.ts @@ -11,7 +11,7 @@ import { ensureUuidEndsWithDot } from '../../utils.js'; export type PreparePublishPackageReqBodyParams = { manifestCid: string; pdfCid: string; - doi: string; // temp till DOI system is operational + doi?: string; // temp till DOI system is operational dpid: string; nodeUuid: string; }; @@ -45,7 +45,7 @@ export const preparePublishPackage = async ( logger.trace({ fn: 'Retrieving Publish Package' }); if (!nodeUuid) return res.status(400).json({ ok: false, error: 'nodeUuid is required.' }); - if (!doi) return res.status(400).json({ ok: false, error: 'doi is required.' }); + // if (!doi) return res.status(400).json({ ok: false, error: 'doi is required.' }); if (!pdfCid) return res.status(400).json({ ok: false, error: 'pdfCid is required.' }); if (!manifestCid) return res.status(400).json({ ok: false, error: 'manifestCid is required.' }); diff --git a/desci-server/src/services/PublishPackage.ts b/desci-server/src/services/PublishPackage.ts index 73a06d2d..a061c6d9 100644 --- a/desci-server/src/services/PublishPackage.ts +++ b/desci-server/src/services/PublishPackage.ts @@ -12,7 +12,7 @@ import { publishServices } from './PublishServices.js'; export type PrepareDistributionPdfParams = { pdfCid: string; node: Node; // Title extraction for now - doi: string; // Temporary till we have DOI system operational + doi?: string; // Temporary till we have DOI system operational manifest: ResearchObjectV1; manifestCid: string; }; @@ -47,6 +47,11 @@ class PublishPackageService { } const title = manifest.title; const dpid = manifest.dpid.id; + if (dpid === undefined) { + this.logger.warn({ dpid, nodeId: node.id }, 'Failed generating a publish package for node, dpid is undefined'); + throw new Error('DPID is undefined'); + } + const license = PublishPackageService.extractManuscriptLicense(manifest, pdfCid); const publishTime = await publishServices.retrieveBlockTimeByManifestCid(node.uuid, manifestCid); const publishDate = PublishPackageService.convertUnixTimestampToDate(publishTime); From ee7a385f7dfd6c3a8a891ee7d8761be60311ded0 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Mon, 27 May 2024 10:29:40 +0200 Subject: [PATCH 037/278] retrict doi check and mint api with node access middleware --- desci-server/src/middleware/authorisation.ts | 1 + desci-server/src/routes/v1/doi.ts | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/desci-server/src/middleware/authorisation.ts b/desci-server/src/middleware/authorisation.ts index a996295f..6913991c 100644 --- a/desci-server/src/middleware/authorisation.ts +++ b/desci-server/src/middleware/authorisation.ts @@ -73,6 +73,7 @@ export const ensureNodeAccess = async (req: RequestWithUser, res: Response, next where: { uuid: ensureUuidEndsWithDot(uuid), ownerId: user.id }, }); + logger.info({ uuid, node }, 'NodeAccess'); if (!node) { res.status(400).send({ ok: false, message: `Node: ${uuid} not found` }); return; diff --git a/desci-server/src/routes/v1/doi.ts b/desci-server/src/routes/v1/doi.ts index 1b2754e7..d80a6e49 100644 --- a/desci-server/src/routes/v1/doi.ts +++ b/desci-server/src/routes/v1/doi.ts @@ -1,11 +1,11 @@ import { Router } from 'express'; -import { asyncHander, checkMintability, ensureUser, getDoi, mintDoi } from '../../internal.js'; +import { asyncHander, checkMintability, ensureNodeAccess, ensureUser, getDoi, mintDoi } from '../../internal.js'; const router = Router(); -router.post('/check/:uuid', [ensureUser], asyncHander(checkMintability)); -router.post('/mint/:uuid', [ensureUser], asyncHander(mintDoi)); +router.post('/check/:uuid', [ensureUser, ensureNodeAccess], asyncHander(checkMintability)); +router.post('/mint/:uuid', [ensureUser, ensureNodeAccess], asyncHander(mintDoi)); router.get('/:identifier', [ensureUser], asyncHander(getDoi)); export default router; From 63180ad1e935ac5e4acc9eedf5700cdd2a7597ce Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Mon, 27 May 2024 09:17:07 +0000 Subject: [PATCH 038/278] update generaed cover fonts to match designs --- desci-media-isolated/package-lock.json | 9 ++++ desci-media-isolated/package.json | 1 + .../public/static/fonts/Inter-Medium.ttf | Bin 0 -> 315132 bytes .../public/static/fonts/Inter-Regular.ttf | Bin 0 -> 310252 bytes .../public/static/fonts/Satoshi-Bold.ttf | Bin 0 -> 73368 bytes desci-media-isolated/src/services/pdf.ts | 46 ++++++++++++++---- 6 files changed, 46 insertions(+), 10 deletions(-) create mode 100644 desci-media-isolated/public/static/fonts/Inter-Medium.ttf create mode 100644 desci-media-isolated/public/static/fonts/Inter-Regular.ttf create mode 100644 desci-media-isolated/public/static/fonts/Satoshi-Bold.ttf diff --git a/desci-media-isolated/package-lock.json b/desci-media-isolated/package-lock.json index 13596caa..2dee82cc 100644 --- a/desci-media-isolated/package-lock.json +++ b/desci-media-isolated/package-lock.json @@ -14,6 +14,7 @@ "filepreview_ts": "^1.0.0", "helmet": "^7.1.0", "pdf-lib": "^1.17.1", + "pdflib-fontkit": "^1.8.11", "tsx": "^4.7.1" }, "devDependencies": { @@ -2425,6 +2426,14 @@ "tslib": "^1.11.1" } }, + "node_modules/pdflib-fontkit": { + "version": "1.8.11", + "resolved": "https://registry.npmjs.org/pdflib-fontkit/-/pdflib-fontkit-1.8.11.tgz", + "integrity": "sha512-J1oiikl5E7en02DGIorof7c5b0JEXXW/DK3Kltv9va72Kn1230eAl1DNSXbcJPAUl0/G2e6UnJWQJoysdyQydA==", + "dependencies": { + "pako": "^1.0.6" + } + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", diff --git a/desci-media-isolated/package.json b/desci-media-isolated/package.json index 1da04348..13f8babc 100644 --- a/desci-media-isolated/package.json +++ b/desci-media-isolated/package.json @@ -18,6 +18,7 @@ "filepreview_ts": "^1.0.0", "helmet": "^7.1.0", "pdf-lib": "^1.17.1", + "pdflib-fontkit": "^1.8.11", "tsx": "^4.7.1" }, "devDependencies": { diff --git a/desci-media-isolated/public/static/fonts/Inter-Medium.ttf b/desci-media-isolated/public/static/fonts/Inter-Medium.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a01f3777a6fc284b7a720c0f8248a27066389ef9 GIT binary patch literal 315132 zcmd>{3Ajzw|M0(S?X!n-?sds<&AMdHJY`De%rlit*Gxz*k|ZQaMWm8sCL|H5Orgje zLX;sYN}^G@hWmcjK4)L_tKaY+-sgFr_ul8T*4k_QuJ8KpwfA0opS?wiNG6<+$lZ18 z)h}DV>>3eWoroNFw`kt_=)7a6M2)O0s^ph46$l{1e>k6gWyQwEyWNY9Gz_3HOX&vyAf z)S{Q>5MAJ8?;gqBOFo}`FX>%Kuhg4}e4BH=#y0Xu!QTA`56g7y>@Ol2dy5p=(eJ@- z$>AZbE{NPwf$hEhlZOqA#4CsVv?oaelKb~){O#aW5vPqvIP<^B5&SN zzrXqG{ycsElt;op`!QDN*v#5b&hDJC`frju&adR?&uep=z_GS14*mY-l@WRR#%E^J z5gn_;)b6n*lGS$$ihj6P@4+ggNJ_r}gHSL1OfsF!hHQL}O9s)M+nsb6q^Qx|dn(6vPA zI=TUFBi#nKoleH>rm-LWq<#hWRsAaNOuY_wquz}Bk=}y4L+`}htv|#4+^Q|gs%JIC zZDKuyJJ=e6`-n9Tcf7Rn$I0&?vs26| zhFiiZfm_XC?3_kUBivR_Pu$*4Z`=o*2XF^C18^U9hKc1o;ygllxHE$A80QJxxz0jS zuIEyxThJ|tTgUBy+u7}m`?&iA?o;klxKF!J<38g~!kywy!JX<(#hvD&2lrK%QFa%* zi*es@m*OsSm*cK3;-OD(xHp{e)}Vk zj}jgoW^}?YgkQj&9-fZ-es~?J8^W6i?+WiGygz&h_el5{?w4U|4u2c|7WaG@4Tpb< z&3F~`P%|^Jmxw&?#K*!)a@fDd!depS)3LB6rR?`&;m{3vY^h|U1HT@J_`b2QD{bt= zSlAQKPKbrWk`y{03&#=O6AQ=R5YC{ItYxwI1gT)5Z@>Ob60rux!na7g)jbx@d_A7& zF41ZhjaN$YSmk12Emid&v9Kle_1m#?vid~S~a&&R@fB%ch5h4XS)iH$F^BublD{H+{eYRAG!9CZrB!ugRWM=V@`kdUjN zBuh7WfLsk_FyVgEhwba}^<)_FgGi|@50cvbPdWcF{jc){v8|mem2h13VpUJrSMT9Ty>3?!}(7+ojH-SDu#-J4JfsYA$L->-WxHJI`PNg0eR zrk)%OnM*bDYd9+u%CMXc}>W)X;S;MZTi-o7KTVyUt%M{ zpqpyy=F2mb5@zI$)P2a=gfb8NwcIE}lbcEgd7JyvnwADob^xWW$D|N5?1t^0zAS_O zQtAi&vUMquf)xFc*ywzS->W{9Gc5#~G(9rbkmBnx1>HsEAMVR+MkEQ{8BLp>rLbir zGrCS9&XgYD_t!`p9oeqL4kG72YyWz`jLr6f!IZesh8y~=80{Nt9gJqGN@@O6kj9Lc zv5gcd1xCxI{5E@$-W-c)!v1aS(MVgL6eDkvv?kP((8K7#*oWzf$r0U;dyvc6hZ(zQ zpG@0PYchFTv)7wZyDs_ln$4cljk3`iN|37^TSfn*nUt7Tjja8l6mAc+*oxXs%n;lp+B0Ju?NN%a&mjNx zQA%QOYv@ZAwTBy1qIx#6N9RXVm)WNV`Ln4R6=O?*1lLQJyvZW|tkd#HTL!IG;ff$? zK_%HvmWsrckxH~t1`Xbrs}-Zz6sjSqu?f?oo7-qboY_;%TtDcBTuC=cQU@IjWS%m1 z7|f>SXw48EVPi4Z+enfY7y8oNVG@2$=8*Bb|Yth z#wE~FX<80?P)sDQpt&yPN^GUn|6ii|e_rpkJ?_f1l28#`I0oDP{d)d+`M8MGzY({b zoVDP42V>h{^2j=f$(R9Lo&d7Uiy12EF<#m^3% zk;mAc3tNaQ3?C4lt$)Av9sZ_hKH0z`#ŹD@)<7ltOtn$SSm;LMTrPEA?sR43d= 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�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 literal 0 HcmV?d00001 diff --git a/desci-media-isolated/public/static/fonts/Inter-Regular.ttf b/desci-media-isolated/public/static/fonts/Inter-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..5e4851f0ab7e0268da6ce903306e2f871ee19821 GIT binary patch literal 310252 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 z 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%0D1lG~DE2ff7BeoTnFxKM!4172W=IjHdV9zf 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

+ + +
+ + + + + ); +}; + +export default SubmissionPackage; + +const main = { + backgroundColor: '#ffffff', + margin: '0 auto', + fontFamily: + "-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif", +}; + +const container = { + margin: '0 auto', + padding: '0px 20px', +}; + +const h1 = { + color: '#000000', + fontSize: '30px', + fontWeight: '700', + margin: '30px 0', + padding: '0', + lineHeight: '42px', +}; + +const heroText = { + fontSize: '20px', + lineHeight: '28px', + marginBottom: '30px', +}; diff --git a/desci-server/src/templates/emails/utils/emailRenderer.tsx b/desci-server/src/templates/emails/utils/emailRenderer.tsx index 01037184..5dec6d31 100644 --- a/desci-server/src/templates/emails/utils/emailRenderer.tsx +++ b/desci-server/src/templates/emails/utils/emailRenderer.tsx @@ -4,6 +4,7 @@ import AttestationClaimedEmail, { AttestationClaimedEmailProps } from '../Attest import ContributorInvite, { ContributorInviteEmailProps } from '../ContributorInvite.js'; import MagicCodeEmail, { MagicCodeEmailProps } from '../MagicCode.js'; import NodeUpdated, { NodeUpdatedEmailProps } from '../NodeUpdated.js'; +import SubmissionPackage, { SubmissionPackageEmailProps } from '../SubmissionPackage.js'; export const ContributorInviteEmailHtml = ({ inviter, @@ -20,3 +21,5 @@ export const AttestationClaimedEmailHtml = (props: AttestationClaimedEmailProps) render(AttestationClaimedEmail(props)); export const NodeUpdatedEmailHtml = (props: NodeUpdatedEmailProps) => render(NodeUpdated(props)); + +export const SubmissionPackageEmailHtml = (props: SubmissionPackageEmailProps) => render(SubmissionPackage(props)); From 388f55707d397640f3c5b1bc56657522e303ec19 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Wed, 3 Jul 2024 13:15:00 +0200 Subject: [PATCH 266/278] clean up orcid --- desci-server/src/controllers/nodes/doi.ts | 2 +- desci-server/src/services/AutomatedMetadata.ts | 3 ++- desci-server/src/services/crossRef/utils.ts | 5 +++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/desci-server/src/controllers/nodes/doi.ts b/desci-server/src/controllers/nodes/doi.ts index 2f6cba16..d21dc0db 100644 --- a/desci-server/src/controllers/nodes/doi.ts +++ b/desci-server/src/controllers/nodes/doi.ts @@ -195,7 +195,7 @@ export const automateManuscriptDoi = async (req: RequestWithNode, res: Response, name: author.name, role: ResearchObjectV1AuthorRole.AUTHOR, ...(author.affiliations.length > 0 && { organizations: author.affiliations }), - ...(author.orcid && { orcid: author.orcid }), + ...(author.orcid && { orcid: getOrcidFromURL(author.orcid) }), })), }); } diff --git a/desci-server/src/services/AutomatedMetadata.ts b/desci-server/src/services/AutomatedMetadata.ts index 17894fea..2abaf7de 100644 --- a/desci-server/src/services/AutomatedMetadata.ts +++ b/desci-server/src/services/AutomatedMetadata.ts @@ -5,6 +5,7 @@ import { logger as parentLogger } from '../logger.js'; import { ONE_DAY_TTL, getFromCache, setToCache } from '../redisClient.js'; import repoService from './repoService.js'; +import { getOrcidFromURL } from './crossRef/utils.js'; const logger = parentLogger.child({ module: '[AutomatedMetadataClient]' }); @@ -187,7 +188,7 @@ export class AutomatedMetadataClient { name: author.name, role: ResearchObjectV1AuthorRole.AUTHOR, ...(author.affiliations.length > 0 && { organizations: author.affiliations }), - ...(author.orcid && { orcid: author.orcid }), + ...(author.orcid && { orcid: getOrcidFromURL(author.orcid) }), }) as ResearchObjectV1Author, ), }); // diff --git a/desci-server/src/services/crossRef/utils.ts b/desci-server/src/services/crossRef/utils.ts index 3ad31ff3..9777a976 100644 --- a/desci-server/src/services/crossRef/utils.ts +++ b/desci-server/src/services/crossRef/utils.ts @@ -21,6 +21,7 @@ const toDotsAndDashes = (str: string) => { }; export const getOrcidFromURL = (orcid: string) => { - const url = new URL(orcid); - return url.pathname.replace('/', ''); + const pattern = /[^/]+$/; + const match = orcid.match(pattern); + return match ? match[0] : orcid; }; From a7797ecbd25288382c9a61ae58d2344869130dfb Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Wed, 3 Jul 2024 13:41:00 +0200 Subject: [PATCH 267/278] add more logging for distribution --- desci-server/src/services/PublishPackage.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/desci-server/src/services/PublishPackage.ts b/desci-server/src/services/PublishPackage.ts index b607dfb1..76310685 100644 --- a/desci-server/src/services/PublishPackage.ts +++ b/desci-server/src/services/PublishPackage.ts @@ -33,6 +33,7 @@ class PublishPackageService { manifest, manifestCid, }: PrepareDistributionPdfParams): Promise { + this.logger.trace({ pdfCid, nodeUuid: node.uuid, doi, manifest, manifestCid }, 'Preparing distribution PDF'); // Check if distro PDF already exists const existingDistributionPdf = await prisma.distributionPdfs.findFirst({ where: { originalPdfCid: pdfCid, manifestCid }, @@ -80,6 +81,7 @@ class PublishPackageService { }; // Generate the PDF with the cover + this.logger.trace({ pdfCid, doi, title, dpid, license, publishDate, authors }, 'Generating PDF cover'); const coverPdfStream = await axios.post( `${process.env.ISOLATED_MEDIA_SERVER_URL}/v1/pdf/addCover`, { cid: pdfCid, doi, title, ...attestationLinks, dpid, license, publishDate, authors }, @@ -87,9 +89,12 @@ class PublishPackageService { responseType: 'stream', }, ); + + this.logger.trace({ pdfCid, doi, title, dpid, license, publishDate, authors }, 'Generated PDF cover'); // Save it on IPFS const pinned = await pinFile(coverPdfStream.data); + this.logger.trace({ pdfCid, doi, title, dpid, license, publishDate, authors }, 'Pinned PDF cover'); // Save it to the database await prisma.distributionPdfs.create({ data: { originalPdfCid: pdfCid, distPdfCid: pinned.cid, nodeUuid: node.uuid, manifestCid }, @@ -97,6 +102,11 @@ class PublishPackageService { // LATER: Add data ref + this.logger.trace( + { pdfCid, doi, title, dpid, license, publishDate, authors, pinnedCid: pinned.cid }, + 'Saved PDF cover', + ); + // Return the CID return { pdfCid: pinned.cid }; } @@ -124,6 +134,7 @@ class PublishPackageService { pageNums: PageNumber[], nodeUuid: string, ): Promise { + this.logger.trace({ pdfCid, heightPx, pageNums, nodeUuid }, 'Generating PDF preview'); if (process.env.ISOLATED_MEDIA_SERVER_URL === undefined) { this.logger.error('process.env.ISOLATED_MEDIA_SERVER_URL is not defined'); return null; @@ -139,6 +150,8 @@ class PublishPackageService { }, ); + this.logger.trace({ pdfCid, heightPx, pageNums, nodeUuid }, 'Generated PDF preview'); + const previewStreams = previewResponse.data; const previewMap: PreviewMap = {}; @@ -153,6 +166,8 @@ class PublishPackageService { previewMap[pageNumber] = pinned.cid; } + this.logger.trace({ pdfCid, heightPx, pageNums, nodeUuid, previewMap }, 'Pinned PDF preview'); + // Save it to the database // const existingPreviews = await prisma.pdfPreviews.findFirst({ // where: { pdfCid, nodeUuid }, From 37171358cfc6a255ef5c992626e254d6aad9b0a3 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Wed, 3 Jul 2024 14:35:57 +0200 Subject: [PATCH 268/278] fix: doi schema error --- desci-server/src/services/crossRef/client.ts | 20 +++++++++++--------- desci-server/src/utils.ts | 4 ++-- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/desci-server/src/services/crossRef/client.ts b/desci-server/src/services/crossRef/client.ts index 03e39cc8..465351dd 100644 --- a/desci-server/src/services/crossRef/client.ts +++ b/desci-server/src/services/crossRef/client.ts @@ -34,7 +34,7 @@ const metadataTemplate = ` &_.registrant; - + &_.title; @@ -44,11 +44,11 @@ const metadataTemplate = ` - - &_.id; - &_.name; + + &_.id; + @@ -183,24 +183,26 @@ class CrossRefClient { doi: string; publicationDate: PublicationDate; }): Promise { - const contributors = await asyncMap(query.manifest.authors ?? [], async (author) => { + const contributors = await asyncMap(query.manifest.authors ?? [], async (author, index) => { const user = author.orcid ? await prisma.user.findUnique({ where: { orcid: author.orcid } }) : null; logger.info({ user: { orcid: user?.orcid } }); const affiliations = user ? ( await prisma.userOrganizations.findMany({ where: { userId: user.id }, include: { organization: true } }) )?.map((org) => ({ name: org.organization.name, id: org.organization.id })) - : author?.organizations?.map((org) => ({ name: org.name })); + : author?.organizations?.map((org) => ({ name: org.name, id: org.id })); return { name: author.name.split(' ')[0], surname: author.name.split(' ').slice(1)?.join(' ') || '-', - + isAuthenticated: !!user, + sequence: index === 0 ? 'first' : 'additional', // don't substitute with `sandbox.orcid.org`, the submission will be rejected // due to schema errors - orcid: `https://orcid.org/${author.orcid}`, + ...(author.orcid && { + orcid: author.orcid.startsWith('https://orcid.org/') ? author.orcid : `https://orcid.org/${author.orcid}`, + }), - isAuthenticated: !!user, // crossref schema only allows a maximum of one affiliation per contributor ...(affiliations?.length > 0 && { affiliations: affiliations.slice(0, 1) }), }; diff --git a/desci-server/src/utils.ts b/desci-server/src/utils.ts index 87f12168..fe63496d 100644 --- a/desci-server/src/utils.ts +++ b/desci-server/src/utils.ts @@ -50,8 +50,8 @@ export const hexToCid = (hexCid: string) => { return cidString; }; -export async function asyncMap(arr: E[], predicate: (input: E) => Promise): Promise { - const results = await Promise.all(arr.map(predicate)); +export async function asyncMap(arr: E[], predicate: (input: E, index: number) => Promise): Promise { + const results = await Promise.all(arr.map((value, index) => predicate(value, index))); return results as T[]; } From 5861cc8823e126bfaae86a3f6e211975151f7b17 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Wed, 3 Jul 2024 18:10:46 +0200 Subject: [PATCH 269/278] feat: doi database schema upgrade, fix issues with workflow attestation check and more --- .../migration.sql | 26 ++++++++++++++ desci-server/prisma/schema.prisma | 21 ++++++----- desci-server/src/controllers/doi/mint.ts | 36 +++++++++++++++---- desci-server/src/services/Attestation.ts | 4 +-- desci-server/src/services/Doi.ts | 28 ++++++++------- desci-server/src/services/crossRef/client.ts | 31 ++++++++++++---- desci-server/src/services/orcid.ts | 4 +-- 7 files changed, 111 insertions(+), 39 deletions(-) create mode 100644 desci-server/prisma/migrations/20240703141325_add_dpid_unique_doi_uuid_to_submission_queue/migration.sql diff --git a/desci-server/prisma/migrations/20240703141325_add_dpid_unique_doi_uuid_to_submission_queue/migration.sql b/desci-server/prisma/migrations/20240703141325_add_dpid_unique_doi_uuid_to_submission_queue/migration.sql new file mode 100644 index 00000000..ba58b19e --- /dev/null +++ b/desci-server/prisma/migrations/20240703141325_add_dpid_unique_doi_uuid_to_submission_queue/migration.sql @@ -0,0 +1,26 @@ +/* + Warnings: + + - A unique constraint covering the columns `[uniqueDoi]` on the table `DoiSubmissionQueue` will be added. If there are existing duplicate values, this will fail. + - Added the required column `dpid` to the `DoiSubmissionQueue` table without a default value. This is not possible if the table is not empty. + - Added the required column `uniqueDoi` to the `DoiSubmissionQueue` table without a default value. This is not possible if the table is not empty. + - Added the required column `uuid` to the `DoiSubmissionQueue` table without a default value. This is not possible if the table is not empty. + +*/ +-- DropForeignKey +ALTER TABLE "DoiSubmissionQueue" DROP CONSTRAINT "DoiSubmissionQueue_doiRecordId_fkey"; + +-- AlterTable +ALTER TABLE "DoiSubmissionQueue" ADD COLUMN "dpid" TEXT NOT NULL, +ADD COLUMN "uniqueDoi" TEXT NOT NULL, +ADD COLUMN "uuid" TEXT NOT NULL, +ALTER COLUMN "doiRecordId" DROP NOT NULL; + +-- CreateIndex +CREATE UNIQUE INDEX "DoiSubmissionQueue_uniqueDoi_key" ON "DoiSubmissionQueue"("uniqueDoi"); + +-- AddForeignKey +ALTER TABLE "DoiSubmissionQueue" ADD CONSTRAINT "DoiSubmissionQueue_doiRecordId_fkey" FOREIGN KEY ("doiRecordId") REFERENCES "DoiRecord"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "DoiSubmissionQueue" ADD CONSTRAINT "DoiSubmissionQueue_uuid_fkey" FOREIGN KEY ("uuid") REFERENCES "Node"("uuid") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/desci-server/prisma/schema.prisma b/desci-server/prisma/schema.prisma index 4acc6123..4c4a09e0 100755 --- a/desci-server/prisma/schema.prisma +++ b/desci-server/prisma/schema.prisma @@ -47,6 +47,7 @@ model Node { PdfPreviews PdfPreviews[] DoiRecord DoiRecord[] dpidAlias Int? + DoiSubmissionQueue DoiSubmissionQueue[] @@index([ownerId]) @@index([uuid]) @@ -839,7 +840,7 @@ model OrcidPutCodes { model DoiRecord { id Int @id @default(autoincrement()) doi String @unique - dpid String @unique // remove unique constrant + dpid String @unique // add dpid or resource path the doi is registered for uuid String node Node @relation(fields: [uuid], references: [uuid]) @@ -849,14 +850,18 @@ model DoiRecord { } model DoiSubmissionQueue { - id Int @id @default(autoincrement()) - batchId String @unique - createdAt DateTime @default(now()) - doiRecordId Int - doi DoiRecord @relation(fields: [doiRecordId], references: [id]) + id Int @id @default(autoincrement()) + batchId String @unique + createdAt DateTime @default(now()) + dpid String + doiRecordId Int? + doi DoiRecord? @relation(fields: [doiRecordId], references: [id]) notification Json? - status DoiStatus @default(PENDING) - updatedAt DateTime @updatedAt + status DoiStatus @default(PENDING) + uniqueDoi String @unique + uuid String + node Node @relation(fields: [uuid], references: [uuid]) + updatedAt DateTime @updatedAt } enum ORCIDRecord { diff --git a/desci-server/src/controllers/doi/mint.ts b/desci-server/src/controllers/doi/mint.ts index 1401f1bb..e64b7e55 100644 --- a/desci-server/src/controllers/doi/mint.ts +++ b/desci-server/src/controllers/doi/mint.ts @@ -11,7 +11,8 @@ import { crossRefClient, doiService, ensureUuidEndsWithDot, - logger, + logger as parentLogger, + prisma, } from '../../internal.js'; export const mintDoi = async (req: Request, res: Response, _next: NextFunction) => { @@ -44,6 +45,8 @@ export const handleCrossrefNotificationCallback = async ( res: Response, _next: NextFunction, ) => { + const logger = parentLogger.child({ module: 'handleCrossrefNotificationCallback' }); + const submission = await doiService.getPendingSubmission(req.payload.externalId); logger.info({ submission }, 'SUBMISSION'); @@ -52,7 +55,6 @@ export const handleCrossrefNotificationCallback = async ( throw new NotFoundError('submission not found'); } - logger.info({ submission }, 'SUBMISSION FOUND'); await doiService.updateSubmission({ id: submission.id }, { notification: req.payload }); logger.info('SUBMISSION UPDATED'); @@ -61,10 +63,30 @@ export const handleCrossrefNotificationCallback = async ( // check retrieve url to get submission result const response = await crossRefClient.retrieveSubmission(req.payload.retrieveUrl); - // TODO: email authors about the submission status + logger.info({ response, submission }, 'CREATE DOI CALLBACK RESPONSE'); + if (response.success) { + logger.info('CREATE DOI '); + const doiRecord = await prisma.doiRecord.create({ + data: { + uuid: submission.uuid, + dpid: submission.dpid, + doi: submission.uniqueDoi, + }, + }); + await doiService.updateSubmission( + { id: submission.id }, + { + status: DoiStatus.SUCCESS, + doiRecordId: doiRecord.id, + }, + ); + } else { + logger.info('ERROR CREATING DOI'); + await doiService.updateSubmission( + { id: submission.id }, + { status: response.failure ? DoiStatus.FAILED : DoiStatus.PENDING }, + ); + } - await doiService.updateSubmission( - { id: submission.id }, - { status: response.success ? DoiStatus.SUCCESS : response.failure ? DoiStatus.FAILED : DoiStatus.PENDING }, - ); + // TODO: email authors about the submission status }; diff --git a/desci-server/src/services/Attestation.ts b/desci-server/src/services/Attestation.ts index 60352229..791fdf17 100644 --- a/desci-server/src/services/Attestation.ts +++ b/desci-server/src/services/Attestation.ts @@ -245,9 +245,9 @@ export class AttestationService { }); } - async getProtectedNodeClaims(dpid: string) { + async getProtectedNodeClaims(nodeUuid: string) { const data = await prisma.nodeAttestation.findMany({ - where: { nodeDpid10: dpid, revoked: false }, + where: { nodeUuid, revoked: false }, include: { community: { select: { name: true } }, attestation: { select: { protected: true } }, diff --git a/desci-server/src/services/Doi.ts b/desci-server/src/services/Doi.ts index 23a7ccb0..afd01207 100644 --- a/desci-server/src/services/Doi.ts +++ b/desci-server/src/services/Doi.ts @@ -9,7 +9,7 @@ import { MintError, ForbiddenMintError, } from '../core/doi/error.js'; -import { logger } from '../logger.js'; +import { logger as parentLogger } from '../logger.js'; import { IndexedResearchObject, getIndexedResearchObjects } from '../theGraph.js'; import { asyncMap, ensureUuidEndsWithDot, hexToCid } from '../utils.js'; @@ -22,6 +22,8 @@ import { crossRefClient } from './index.js'; const DOI_PREFIX = process.env.DOI_PREFIX; if (!DOI_PREFIX) throw new Error('env DOI_PREFIX is missing!'); + +const logger = parentLogger.child({ module: '[DoiService]' }); export class DoiService { dbClient: PrismaClient; @@ -39,18 +41,19 @@ export class DoiService { return !exists; } - async assertHasValidatedAttestations(manifest: ResearchObjectV1) { + async assertHasValidatedAttestations(uuid: string) { const doiAttestations = await attestationService.getProtectedAttestations({ protected: true, community: { slug: 'desci-foundation' }, }); // logger.info(doiAttestations, 'DOI Requirements'); - let claims = await attestationService.getProtectedNodeClaims(manifest.dpid.id); + let claims = await attestationService.getProtectedNodeClaims(uuid); claims = claims.filter((claim) => claim.verifications > 0); const hasClaimedRequiredAttestation = doiAttestations.some((attestation) => claims.find((claim) => claim.attestationId === attestation.id), ); + logger.info({ hasClaimedRequiredAttestation }, 'hasClaimedRequiredAttestation'); if (!hasClaimedRequiredAttestation) throw new AttestationsError(); } @@ -85,11 +88,13 @@ export class DoiService { // check mintability for either root node or manuscript async checkMintability(nodeUuid: string) { + logger.info({ nodeUuid }, 'checkMintability'); const uuid = ensureUuidEndsWithDot(nodeUuid); // retrieve node manifest/metadata const { researchObjects } = await getIndexedResearchObjects([uuid]); const researchObject = researchObjects[0] as IndexedResearchObject; + logger.info({ researchObject }, 'RESEARCH OBJECT'); const manifestCid = hexToCid(researchObject?.recentCid); if (!manifestCid) throw new ForbiddenMintError('Node not published yet!'); @@ -118,11 +123,11 @@ export class DoiService { // does manuscript(s) already have a DOI if (existingDois.length) { // Validate node has claimed all necessary attestations - await this.assertHasValidatedAttestations(latestManifest); + await this.assertHasValidatedAttestations(uuid); } } else { // Validate node has claimed all necessary attestations - await this.assertHasValidatedAttestations(latestManifest); + await this.assertHasValidatedAttestations(uuid); } // validate title, abstract and contributors @@ -156,16 +161,13 @@ export class DoiService { logger.info({ doiSuffix, doi, uuid, metadataResponse }, 'DOI SUBMITTED'); // todo: - const doiRecord = await this.dbClient.doiRecord.create({ - data: { - uuid, - dpid, - doi, - }, - }); + // only create doi if submission status is success const submission = await crossRefClient.addSubmissiontoQueue({ - doi: doiRecord.id, + // doi: doiRecord.id, + dpid, + uuid: ensureUuidEndsWithDot(uuid), + uniqueDoi: doi, batchId: metadataResponse.batchId, }); diff --git a/desci-server/src/services/crossRef/client.ts b/desci-server/src/services/crossRef/client.ts index 465351dd..3377857f 100644 --- a/desci-server/src/services/crossRef/client.ts +++ b/desci-server/src/services/crossRef/client.ts @@ -325,9 +325,19 @@ class CrossRefClient { return response; } - async addSubmissiontoQueue({ doi, batchId }: { doi: number; batchId: string }) { + async addSubmissiontoQueue({ + uniqueDoi, + dpid, + uuid, + batchId, + }: { + uniqueDoi: string; + dpid: string; + uuid: string; + batchId: string; + }) { // check if there is no pending submission log - return await prisma.doiSubmissionQueue.create({ data: { doiRecordId: doi, batchId } }); + return await prisma.doiSubmissionQueue.create({ data: { batchId, uniqueDoi, dpid, uuid } }); } async retrieveSubmission(retrieveUrl: string) { @@ -336,11 +346,18 @@ class CrossRefClient { // query submssion payload from param.CROSSREF-RETRIEVE-URL // only create doi if submission status is success - const response = (await fetch(retrieveUrl).then((res) => res.json())) as NotificationResult; - logger.info(response, 'CROSSREF NOTIFICATION: retrieveSubmission'); - // return interprete the response from the api to determine if the - // submission status has either `success | pending | failed` - return { success: response?.completed !== null, pending: false, failure: true }; + try { + logger.info({ retrieveUrl }, 'ATTEMPT TO RETRIEVE SUBMISSION'); + const response = (await fetch(retrieveUrl).then((res) => res.json())) as NotificationResult; + logger.info(response, 'RETRIEVE SUBMISSION'); + // return interprete the response from the api to determine if the + // submission status has either `success | pending | failed` + const isSuccess = response?.completed !== null && !!response.recordCreated; + return { success: isSuccess, failure: !isSuccess }; + } catch (err) { + logger.error({ err }, 'ERROR RETRIEVING SUBMISSION'); + return { success: false, failure: true }; + } } } diff --git a/desci-server/src/services/orcid.ts b/desci-server/src/services/orcid.ts index 8b037722..c3cc0a60 100644 --- a/desci-server/src/services/orcid.ts +++ b/desci-server/src/services/orcid.ts @@ -145,7 +145,7 @@ class OrcidApiService { const researchObject = researchObjects[0] as IndexedResearchObject; const manifestCid = hexToCid(researchObject.recentCid); const latestManifest = await getManifestByCid(manifestCid); - let claims = await attestationService.getProtectedNodeClaims(latestManifest.dpid.id); + let claims = await attestationService.getProtectedNodeClaims(nodeUuid); claims = claims.filter((claim) => claim.verifications > 0); logger.info({ claims: claims.length }, '[ORCID::DELETE]:: CHECK CLAIMS'); @@ -250,7 +250,7 @@ class OrcidApiService { researchObject.versions.reverse(); const nodeVersion = researchObject.versions.length; - let claims = await attestationService.getProtectedNodeClaims(latestManifest.dpid.id); + let claims = await attestationService.getProtectedNodeClaims(nodeUuid); claims = claims.filter((claim) => claim.verifications > 0); // TODO: if claims is empty remove orcid record From 968f83eb45f5332ed6434de84758b77dd786f23c Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Wed, 3 Jul 2024 19:41:56 +0200 Subject: [PATCH 270/278] fix: contributor sequence in xml template --- desci-server/src/controllers/doi/check.ts | 9 ++ desci-server/src/services/Doi.ts | 13 +-- desci-server/src/services/crossRef/client.ts | 92 ++++++++++---------- 3 files changed, 59 insertions(+), 55 deletions(-) diff --git a/desci-server/src/controllers/doi/check.ts b/desci-server/src/controllers/doi/check.ts index 5962f061..34ca702d 100644 --- a/desci-server/src/controllers/doi/check.ts +++ b/desci-server/src/controllers/doi/check.ts @@ -6,6 +6,8 @@ import { RequestWithNode, SuccessResponse, doiService, + ensureUuidEndsWithDot, + logger, logger as parentLogger, } from '../../internal.js'; @@ -33,6 +35,13 @@ export const getDoi = async (req: Request, res: Response, next: NextFunction) => const { identifier } = req.params; if (!identifier) throw new BadRequestError(); + const pending = await doiService.hasPendingSubmission(ensureUuidEndsWithDot(identifier)); + logger.info({ pending }, 'GET DOI'); + if (pending) { + new SuccessResponse({ status: pending.status }).send(res); + return; + } + const doi = await doiService.getDoiByDpidOrUuid(identifier); new SuccessResponse(doi).send(res); }; diff --git a/desci-server/src/services/Doi.ts b/desci-server/src/services/Doi.ts index afd01207..d8e2786c 100644 --- a/desci-server/src/services/Doi.ts +++ b/desci-server/src/services/Doi.ts @@ -153,15 +153,11 @@ export class DoiService { publicationDate: { day, month, year }, }); + logger.info({ doiSuffix, doi, uuid, metadataResponse }, 'DOI SUBMITTED'); if (!metadataResponse.ok) { throw new MintError("We couldn't register a DOI for this research object"); } - // todo: add submissionId and doi to DoiSubmissionLog table to keep track of status - logger.info({ doiSuffix, doi, uuid, metadataResponse }, 'DOI SUBMITTED'); - - // todo: - // only create doi if submission status is success const submission = await crossRefClient.addSubmissiontoQueue({ // doi: doiRecord.id, @@ -182,12 +178,11 @@ export class DoiService { } async hasPendingSubmission(uuid: string) { - const pending = await this.dbClient.doiRecord.findFirst({ - where: { uuid: ensureUuidEndsWithDot(uuid) }, - include: { DoiSubmission: { where: { status: DoiStatus.PENDING } } }, + const pending = await this.dbClient.doiSubmissionQueue.findFirst({ + where: { uuid: ensureUuidEndsWithDot(uuid), status: DoiStatus.PENDING }, }); - return pending?.DoiSubmission && pending.DoiSubmission.length > 0 ? true : false; + return pending; } async getPendingSubmission(batchId: string) { diff --git a/desci-server/src/services/crossRef/client.ts b/desci-server/src/services/crossRef/client.ts index 3377857f..b8026f2f 100644 --- a/desci-server/src/services/crossRef/client.ts +++ b/desci-server/src/services/crossRef/client.ts @@ -38,52 +38,52 @@ const metadataTemplate = ` &_.title; - - &_.name; - &_.surname; - - - - - &_.name; - - &_.id; - - - - - - - - &_.orcid; - - - &_.orcid; - - - - - - - &_.title; - - - &publishedDate.month; - &publishedDate.day; - &publishedDate.year; - - - &publishedDate.month; - &publishedDate.day; - &publishedDate.year; - - &_.dpid; - - &_.doi; - &_.doiResource; - - - + + &_.name; + &_.surname; + + + + + &_.name; + + &_.id; + + + + + + + + &_.orcid; + + + &_.orcid; + + + + + + + &_.title; + + + &publishedDate.month; + &publishedDate.day; + &publishedDate.year; + + + &publishedDate.month; + &publishedDate.day; + &publishedDate.year; + + &_.dpid; + + &_.doi; + &_.doiResource; + + + `; From c29acaace47da582fa59bb38030b2eec385256d2 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Thu, 4 Jul 2024 08:52:49 +0000 Subject: [PATCH 271/278] optional coupling of preview generation on submission pkg call for simplification/optimization --- .../nodes/preparePublishPackage.ts | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/desci-server/src/controllers/nodes/preparePublishPackage.ts b/desci-server/src/controllers/nodes/preparePublishPackage.ts index 62c52ee1..7b72b079 100644 --- a/desci-server/src/controllers/nodes/preparePublishPackage.ts +++ b/desci-server/src/controllers/nodes/preparePublishPackage.ts @@ -3,8 +3,7 @@ import type { Request, Response } from 'express'; import { prisma } from '../../client.js'; import { logger as parentLogger } from '../../logger.js'; import { getManifestByCid } from '../../services/data/processing.js'; -import { publishPackageService } from '../../services/PublishPackage.js'; -import { publishServices } from '../../services/PublishServices.js'; +import { PreviewMap, publishPackageService } from '../../services/PublishPackage.js'; import { CidString } from '../../services/Thumbnails.js'; import { ensureUuidEndsWithDot } from '../../utils.js'; @@ -14,11 +13,14 @@ export type PreparePublishPackageReqBodyParams = { doi?: string; // temp till DOI system is operational dpid: string; nodeUuid: string; + withPreviews?: boolean; }; type PreparePublishPackageResponse = { ok: true; distPdfCid: CidString; + frontmatterPageCid?: string; + contentPageCid?: string; }; type PreparePublishPackageErrorResponse = { @@ -34,12 +36,13 @@ export const preparePublishPackage = async ( req: Request, res: Response, ) => { - const { pdfCid, doi, nodeUuid, manifestCid } = req.body; + const { pdfCid, doi, nodeUuid, manifestCid, withPreviews } = req.body; const logger = parentLogger.child({ module: 'NODES::PreparePublishPackageController', pdfCid, doi, nodeUuid, + withPreviews, }); // debugger; logger.trace({ fn: 'Retrieving Publish Package' }); @@ -72,7 +75,16 @@ export const preparePublishPackage = async ( // Fire off email to all contributors // await publishServices.sendVersionUpdateEmailToAllContributors({ node, manuscriptCid: distPdfCid }); - return res.status(200).json({ ok: true, distPdfCid }); + let previewMap: PreviewMap = {}; + if (withPreviews) { + previewMap = await publishPackageService.generatePdfPreview(distPdfCid, 1000, [1, 2], node.uuid); + } + + return res.status(200).json({ + ok: true, + distPdfCid, + ...(withPreviews && { frontmatterPageCid: previewMap[1], contentPageCid: previewMap[2] }), + }); } catch (e) { logger.error({ fn: 'preparePublishPackage', error: e.message }); return res.status(500).json({ ok: false, error: 'Failed preparing distribution package' }); From d69ebb9acd772777b90c9a07267f523146bcab6d Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Thu, 4 Jul 2024 11:19:19 +0000 Subject: [PATCH 272/278] temporary removal of --parallel flag in dockerDev script to allow local dev to run (maybe system specific issue) --- dockerDev.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dockerDev.sh b/dockerDev.sh index c130b3d5..7913c991 100755 --- a/dockerDev.sh +++ b/dockerDev.sh @@ -72,7 +72,6 @@ COMPOSE_HTTP_TIMEOUT=320 docker-compose \ --file docker-compose.yml \ --file docker-compose.dev.yml \ --file docker-compose.repo.yml \ - --parallel=4 \ $ADDITIONAL_FLAGS \ --compatibility \ up \ From 26567eb056428ecca9f7a20e598733f866859c9f Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Thu, 4 Jul 2024 11:27:40 +0000 Subject: [PATCH 273/278] fix invite sent flag, add silent invitebody paam --- .../src/controllers/nodes/contributions/create.ts | 8 +++++--- .../src/controllers/nodes/contributions/update.ts | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/desci-server/src/controllers/nodes/contributions/create.ts b/desci-server/src/controllers/nodes/contributions/create.ts index 0d7a489e..4d608a1f 100644 --- a/desci-server/src/controllers/nodes/contributions/create.ts +++ b/desci-server/src/controllers/nodes/contributions/create.ts @@ -14,6 +14,7 @@ export type AddContributorReqBody = { email?: string; orcid?: string; userId?: number; + silent?: boolean; // Don't fire an email }; export type AddContributorRequest = Request & { @@ -37,7 +38,7 @@ export const addContributor = async (req: AddContributorRequest, res: Response & { @@ -36,7 +37,7 @@ export const updateContributor = async (req: UpdateContributorRequest, res: Resp if (!node || !user) throw Error('Middleware not properly setup for addContributor controller, requires req.node and req.user'); - const { contributorId, orcid, userId } = req.body; + const { contributorId, orcid, userId, silent } = req.body; let { email } = req.body; if (email) email = email.toLowerCase(); @@ -46,6 +47,7 @@ export const updateContributor = async (req: UpdateContributorRequest, res: Resp uuid: node.uuid, user: (req as any).user, nodeId: node.id, + silent, }); if (!contributorId) { @@ -78,7 +80,7 @@ export const updateContributor = async (req: UpdateContributorRequest, res: Resp } // Future: - if (currentEmail !== email && email !== user.email) { + if (currentEmail !== email && email !== user.email && !silent) { // If email was changed, send a new email. logger.info({ contributorId, recipient: email }, 'Firing off contributor invite email for updated contributor'); @@ -102,7 +104,7 @@ export const updateContributor = async (req: UpdateContributorRequest, res: Resp if (process.env.NODE_ENV === 'production') { sgMail.send(emailMsg); - prisma.nodeContribution.update({ + await prisma.nodeContribution.update({ where: { id: contributorUpdated.id }, data: { inviteSent: true }, }); From b3121c0bba06ab0f43e9e399828467269ae5072d Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Thu, 4 Jul 2024 23:43:08 +0200 Subject: [PATCH 274/278] feat: Grobid integration, implement custom {bibtext => json} parser for grobid metadata extraction, improve metadata extraction success rate by merging outputs from grobid and open alex --- desci-server/src/controllers/nodes/doi.ts | 104 +++--- .../src/services/AutomatedMetadata.ts | 305 +++++++++++++++++- desci-server/src/services/Doi.ts | 5 +- 3 files changed, 361 insertions(+), 53 deletions(-) diff --git a/desci-server/src/controllers/nodes/doi.ts b/desci-server/src/controllers/nodes/doi.ts index d21dc0db..c5730d33 100644 --- a/desci-server/src/controllers/nodes/doi.ts +++ b/desci-server/src/controllers/nodes/doi.ts @@ -115,44 +115,70 @@ export const automateManuscriptDoi = async (req: RequestWithNode, res: Response, // if doi is present, pull from openalex if (component.payload?.doi) { doi = component.payload.doi[0]; - try { - const result = await fetch( - `https://api.openalex.org/works/doi:${doi}?select=id,title,doi,authorships,keywords,open_access,best_oa_location,abstract_inverted_index`, - { - headers: { - Accept: '*/*', - 'content-type': 'application/json', - }, - }, - ); - logger.info({ status: result.status, message: result.statusText }, 'OPEN ALEX QUERY'); - const work = (await result.json()) as OpenAlexWork; - logger.info({ openAlexWork: work }, 'OPEN ALEX QUERY'); - metadata = transformOpenAlexWorkToMetadata(work); - } catch (err) { - logger.error({ err }, 'ERROR: OPEN ALEX WORK QUERY'); - } + metadata = await metadataClient.queryDoiFromOpenAlex(doi); } + let grobidMetadata: { + authors: string[]; + title: string; + abstract: string; + doi: string; + } | null; + if (!metadata) { - // pull metadata from AM service - metadata = await metadataClient.getResourceMetadata({ - cid: component.payload.cid, - doi: doi || component.payload?.doi?.[0], - }); + logger.info('Pull from grobid'); + // pull from grobid + grobidMetadata = await metadataClient.queryFromGrobid(component.payload.cid); + + logger.info({ grobidMetadata }, 'GROBID METADATA'); + if (grobidMetadata?.doi) { + // doi = grobidMetadata.doi; + logger.info({ doi }, 'DOI PARSED FROM GROBID'); + const openAlexMetadata = await metadataClient.queryDoiFromOpenAlex(grobidMetadata.doi); + metadata = { + ...openAlexMetadata, + abstract: grobidMetadata.abstract || openAlexMetadata.abstract, + title: grobidMetadata.title || openAlexMetadata.title, + }; + } else { + metadata = { + title: grobidMetadata.title, + abstract: grobidMetadata.abstract, + authors: grobidMetadata.authors.map((author) => ({ name: author, affiliations: [], orcid: '' })), + pdfUrl: '', + keywords: [], + }; + } + + logger.info({ grobidMetadata }, 'Grobid Metadata'); } // todo: pull metadata from crossrefClient#getDoiMetadata // const doiMetadata = await crossRefClient.getDoiMetadata(''); + // attempt to pull doi from crossref api + if (!doi && metadata?.title) { + const works = await crossRefClient.listWorks({ + rows: 5, + select: [WorkSelectOptions.DOI, WorkSelectOptions.TITLE, WorkSelectOptions.AUTHOR], + queryTitle: metadata.title, + }); + const work = works?.data?.message?.items.find((item) => + item.title.some((t) => t.toLowerCase() === metadata?.title.toLowerCase()), + ); + if (work?.DOI) { + doi = work.DOI; + } + } logger.info({ metadata }, 'METADATA'); if (!metadata) throw new NotFoundError('DOI not found!'); const actions: ManifestActions[] = []; - if (!doi) { + if (!doi && metadata?.doi) { // fallback to metadata.doi if component payload has no doi doi = metadata?.doi; + logger.info({ doi }, 'USE DOI FROM METADATA'); } if (doi) { @@ -163,11 +189,11 @@ export const automateManuscriptDoi = async (req: RequestWithNode, res: Response, payload: { ...component.payload, doi: component.payload?.doi ? component.payload.doi : [doi], - ...(metadata?.keywords && { - keywords: component.payload?.keywords - ? component?.payload.keywords.concat(metadata.keywords) - : metadata.keywords, - }), + // ...(metadata?.keywords && { + // keywords: component.payload?.keywords + // ? component?.payload.keywords.concat(metadata.keywords) + // : metadata.keywords, + // }), } as PdfComponentPayload & CommonComponentPayload, }, componentIndex, @@ -214,28 +240,6 @@ export const automateManuscriptDoi = async (req: RequestWithNode, res: Response, new SuccessResponse(true).send(res); }; -const transformOpenAlexWorkToMetadata = (work: OpenAlexWork): MetadataResponse => { - const authors = work.authorships.map((author) => ({ - orcid: author.author?.orcid ? getOrcidFromURL(author.author.orcid) : null, - name: author.author.display_name, - affiliations: author?.institutions.map((org) => ({ name: org.display_name, id: org?.ror || '' })) ?? [], - })); - - const keywords = work?.keywords.map((entry) => entry.display_name) ?? []; - - const abstract = work?.abstract_inverted_index ? transformInvertedAbstractToText(work.abstract_inverted_index) : ''; - - return { title: work.title, doi: work.doi, authors, pdfUrl: '', keywords, abstract }; -}; - -const transformInvertedAbstractToText = (abstract: OpenAlexWork['abstract_inverted_index']) => { - const words = []; - Object.entries(abstract).map(([word, positions]) => { - positions.forEach((pos) => words.splice(pos, 0, word)); - }); - return words.filter(Boolean).join(' '); -}; - const transformWorkToMetadata = (work: Work): MetadataResponse => { const title = work.title[0]; const authors = work.author.map((author) => ({ diff --git a/desci-server/src/services/AutomatedMetadata.ts b/desci-server/src/services/AutomatedMetadata.ts index 2abaf7de..92ba5017 100644 --- a/desci-server/src/services/AutomatedMetadata.ts +++ b/desci-server/src/services/AutomatedMetadata.ts @@ -1,11 +1,15 @@ +import { Readable } from 'stream'; + import { DocumentId } from '@automerge/automerge-repo'; import { ManifestActions, ResearchObjectV1Author, ResearchObjectV1AuthorRole } from '@desci-labs/desci-models'; +import axios from 'axios'; +import FormData from 'form-data'; import { logger as parentLogger } from '../logger.js'; import { ONE_DAY_TTL, getFromCache, setToCache } from '../redisClient.js'; -import repoService from './repoService.js'; import { getOrcidFromURL } from './crossRef/utils.js'; +import repoService from './repoService.js'; const logger = parentLogger.child({ module: '[AutomatedMetadataClient]' }); @@ -58,13 +62,58 @@ export type AutomatedMetadataResponse = { export type MetadataResponse = { abstract?: string; - authors: Array<{ orcid: string; name: string; affiliations: { name: string; id: string }[] }>; + authors: Array<{ orcid?: string; name: string; affiliations?: { name: string; id: string }[] }>; title: string; pdfUrl: string | null; keywords: string[]; doi?: string; }; +export interface OpenAlexWork { + id: string; + title: string; + doi: string; + open_access: { + is_oa: boolean; + oa_status: string; + oa_url: string; + }; + best_oa_location: { + is_oa: boolean; + pdf_url: string; + }; + authorships: Array<{ + author_position: string; + author: { + id: string; + display_name: string; + orcid: string; + }; + institutions: Array<{ + id: string; + display_name: string; + ror: string; + country_code: string; + type: string; + lineage: string[]; + }>; + countries: string[]; + is_corresponding: boolean; + raw_author_name: string; + raw_affiliation_strings: string[]; + affiliations: Array<{ + raw_affiliation_string: string; + institution_ids: string[]; + }>; + }>; + keywords: Array<{ + id: string; + display_name: string; + score: number; + }>; + abstract_inverted_index?: { [key: string]: number[] }; +} + /** * A wrapper http client for querying, caching and parsing requests * from the CrossRef Rest Api https://www.crossref.org/documentation/retrieve-metadata/rest-api/ @@ -127,6 +176,77 @@ export class AutomatedMetadataClient { } } + /** + * Returns all the Grobid header metadata associated with a pdf cid + */ + async queryFromGrobid(cid: string) { + try { + if (!cid) throw new Error('Invalid data'); + + const pdfUrl = `${process.env.IPFS_RESOLVER_OVERRIDE}/${cid}`; + + let response = await axios.head(pdfUrl); + const contentType = response.headers['content-type']; + const fileSize = response.headers['content-length']; + + if (contentType.toLowerCase() !== 'application/pdf') { + logger.error({ contentType, cid: cid }, 'CID CONTENT NOT A PDF FILE'); + return null; + } + + logger.info({ contentType, pdfUrl }, 'PDF RESPONSE CONTENT'); + + const axiosRes = await axios.get(pdfUrl, { responseType: 'arraybuffer' }); + logger.info({ status: axiosRes.status, headers: axiosRes.headers }, 'DOWNLOAD PDF AXIOS'); + + const fetchRes = await fetch(pdfUrl); + logger.info({ status: fetchRes.status, headers: fetchRes.headers }, 'DOWNLOAD PDF FETCH'); + const res = await fetchRes.arrayBuffer(); + const buffer = Buffer.from(res); + const inputStream = Readable.from(buffer); + // const blob = new Blob([res.data], { type: 'application/pdf' }); + logger.info({ SIZE: inputStream.readableLength, fileSize }, 'PDF CONTENT'); + + const formdata = new FormData(); + formdata.append('input', inputStream, { filename: 'manuscript.pdf', contentType: 'application/pdf' }); + + const url = 'https://grobid-dev.desci.com/api/processHeaderDocument'; + response = await axios.request({ url, method: 'POST', data: formdata, headers: { ...formdata.getHeaders() } }); + logger.info({ header: response.data }, 'GROBID RESPONSE'); + if (response.status !== 200) return null; + // transform data + const headerMetadata = parseBibtext(response.data); + return headerMetadata; + } catch (error) { + logger.error(error, 'ERROR'); + return null; + } + } + + /** + * Pull metadata from Open Alex api + */ + async queryDoiFromOpenAlex(doi: string): Promise { + try { + const result = await fetch( + `https://api.openalex.org/works/doi:${doi}?select=id,title,doi,authorships,keywords,open_access,best_oa_location,abstract_inverted_index`, + { + headers: { + Accept: '*/*', + 'content-type': 'application/json', + }, + }, + ); + logger.info({ status: result.status, message: result.statusText }, 'OPEN ALEX QUERY'); + const work = (await result.json()) as OpenAlexWork; + logger.info({ openAlexWork: work }, 'OPEN ALEX QUERY'); + return transformOpenAlexWorkToMetadata(work); + } catch (err) { + logger.error({ err }, 'ERROR: OPEN ALEX WORK QUERY'); + return null; + } + } + async performFetch(request: Request, cacheKey: string): Promise { const responseFromCache = await getFromCache(request.url); logger.info({ responseFromCache, request: request.headers, cacheKey }, 'METADATA From Cache'); @@ -203,3 +323,184 @@ export class AutomatedMetadataClient { return response; } } + +/** + * Custom Bibtext to JSON parser for pdf headers returned + * from Grobid 'https://grobid-dev.desci.com/api/processHeaderDocument' + * @param input Bibtext string + * @returns Metadata + */ +const parseBibtext = (input: string) => { + const metadata: { + authors: string[]; + title: string; + abstract: string; + doi: string; + } = { title: '', authors: [], abstract: '', doi: '' }; + + let cursor = 0; + + const skipSpaces = (text: string) => { + let char = text[cursor]; + while (char === ' ') { + cursor++; + char = text[cursor]; + } + }; + + const parseFieldName = (text: string) => { + // parseFieldName + const start = cursor; + while (text[cursor] !== ' ') { + cursor++; + } + cursor++; + const name = text.slice(start, cursor).trim(); + console.log({ fieldName: name }); + return name; + }; + + const skipUntil = (delimiter: string) => { + // skip until delimiter + while (input[cursor] !== delimiter) { + cursor += 1; + } + + // move cursor to next char after the delimeter + cursor += 1; + // console.log("skipped until", input[cursor], delimiter); + }; + + const parseFieldValue = (fieldName: string) => { + // parseFieldValue + + let start = cursor, + line = ''; + console.log('start', start); + + // skip to start of value + skipUntil('{'); + if (input[cursor] === '}' && input[cursor - 1] === '{') return; + + switch (fieldName) { + case 'author': + console.log('Parse author'); + start = cursor; + console.log({ start, cursor }); + skipUntil('}'); + line = input.substring(start, cursor - 1); + const authors = line + .split(',') + .map((text) => text.trim()) + .filter(Boolean); + // console.log({ authors, line, cursor }); + metadata['authors'] = authors; + break; + case 'title': + console.log('Parse title'); + // skipUntil("{"); + start = cursor; + skipUntil('}'); + line = input.substring(start, cursor - 1); + const title = line.trim(); + // console.log({ title }); + metadata['title'] = title; + break; + case 'doi': + // Parse doi + start = cursor; + skipUntil('}'); + line = input.substring(start, cursor - 1); + const doi = line.trim(); + // console.log({ doi }); + metadata['doi'] = doi; + break; + case 'abstract': + // Parse abstract + start = cursor; + skipUntil('}'); + line = input.substring(start, cursor - 1); + const abstract = line.trim(); + metadata['abstract'] = abstract; + break; + default: + console.log('Unknown field value: ', fieldName); + skipUntil('}'); + break; + } + }; + + const skipBy = (n: number) => { + cursor += n; + }; + + while (cursor < input.length) { + const char = input[cursor]; + // console.log({ cursor, char }); + + switch (char) { + case '@': + console.log('Found @', { cursor }); + skipUntil('\n'); + break; + case '-1': + // skip to next character as this is irrelevant + skipUntil('\n'); + break; + case ' ': + // skip spaces + skipSpaces(input); + break; + case '{': + // skip opening tag + skipBy(1); + break; + case '}': + // skip closing tag + skipBy(1); + break; + case '\n': + // skip line break + skipBy(1); + break; + case ',': + // skip end of value delimiter + skipBy(1); + break; + case '\r': + // skip spaces + skipBy(1); + break; + default: + const fieldName = parseFieldName(input); + parseFieldValue(fieldName); + break; + } + + console.log({ cursor }); + } + + return metadata; +}; + +const transformOpenAlexWorkToMetadata = (work: OpenAlexWork): MetadataResponse => { + const authors = work.authorships.map((author) => ({ + orcid: author.author?.orcid ? getOrcidFromURL(author.author.orcid) : null, + name: author.author.display_name, + affiliations: author?.institutions.map((org) => ({ name: org.display_name, id: org?.ror || '' })) ?? [], + })); + + const keywords = work?.keywords.map((entry) => entry.display_name) ?? []; + + const abstract = work?.abstract_inverted_index ? transformInvertedAbstractToText(work.abstract_inverted_index) : ''; + + return { title: work.title, doi: work.doi, authors, pdfUrl: '', keywords, abstract }; +}; + +const transformInvertedAbstractToText = (abstract: OpenAlexWork['abstract_inverted_index']) => { + const words = []; + Object.entries(abstract).map(([word, positions]) => { + positions.forEach((pos) => words.splice(pos, 0, word)); + }); + return words.filter(Boolean).join(' '); +}; diff --git a/desci-server/src/services/Doi.ts b/desci-server/src/services/Doi.ts index 23a7ccb0..4ddab913 100644 --- a/desci-server/src/services/Doi.ts +++ b/desci-server/src/services/Doi.ts @@ -55,6 +55,7 @@ export class DoiService { } async extractManuscriptDoi(manuscripts: PdfComponent[]) { + // todo: update this to use Grobid/openAlex const manuscriptDois = await asyncMap(manuscripts, async (component) => { const manuscriptTitle = component.name.replace(/\.pdf/g, '') || @@ -66,7 +67,9 @@ export class DoiService { select: [WorkSelectOptions.DOI, WorkSelectOptions.TITLE, WorkSelectOptions.AUTHOR], queryTitle: manuscriptTitle, }); - const doi = works?.data?.message?.items.find((item) => item.title.some((t) => t === manuscriptTitle)); + const doi = works?.data?.message?.items.find((item) => + item.title.some((t) => t.toLowerCase() === manuscriptTitle.toLowerCase()), + ); logger.info({ status: works.ok, manuscript: manuscriptTitle, doi }, 'Search Manuscripts'); if (!doi) return null; From fecf4a57ed7ff7381d47330450bf9fd7d3bf28af Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Thu, 4 Jul 2024 23:46:37 +0200 Subject: [PATCH 275/278] chore: clean up --- desci-server/src/controllers/nodes/doi.ts | 46 ----------------------- 1 file changed, 46 deletions(-) diff --git a/desci-server/src/controllers/nodes/doi.ts b/desci-server/src/controllers/nodes/doi.ts index c5730d33..13e98f64 100644 --- a/desci-server/src/controllers/nodes/doi.ts +++ b/desci-server/src/controllers/nodes/doi.ts @@ -12,7 +12,6 @@ import { z } from 'zod'; import { BadRequestError, - ForbiddenError, NotFoundError, RequestWithNode, SuccessResponse, @@ -33,51 +32,6 @@ export const attachDoiSchema = z.object({ }), }); -export interface OpenAlexWork { - id: string; - title: string; - doi: string; - open_access: { - is_oa: boolean; - oa_status: string; - oa_url: string; - }; - best_oa_location: { - is_oa: boolean; - pdf_url: string; - }; - authorships: Array<{ - author_position: string; - author: { - id: string; - display_name: string; - orcid: string; - }; - institutions: Array<{ - id: string; - display_name: string; - ror: string; - country_code: string; - type: string; - lineage: string[]; - }>; - countries: string[]; - is_corresponding: boolean; - raw_author_name: string; - raw_affiliation_strings: string[]; - affiliations: Array<{ - raw_affiliation_string: string; - institution_ids: string[]; - }>; - }>; - keywords: Array<{ - id: string; - display_name: string; - score: number; - }>; - abstract_inverted_index?: { [key: string]: number[] }; -} - export const automateManuscriptDoi = async (req: RequestWithNode, res: Response, _next: NextFunction) => { const { uuid, path, prepublication } = req.body; From b1ccaaecee5c232fea4bfbaf8fb5bd794584ad95 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Fri, 5 Jul 2024 16:36:12 +0200 Subject: [PATCH 276/278] set fallback ipfs resolver, set default grobid metadata response --- desci-server/src/controllers/nodes/doi.ts | 8 ++++---- .../src/services/AutomatedMetadata.ts | 19 ++++++++++++++----- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/desci-server/src/controllers/nodes/doi.ts b/desci-server/src/controllers/nodes/doi.ts index 13e98f64..4a3a2a54 100644 --- a/desci-server/src/controllers/nodes/doi.ts +++ b/desci-server/src/controllers/nodes/doi.ts @@ -94,11 +94,11 @@ export const automateManuscriptDoi = async (req: RequestWithNode, res: Response, abstract: grobidMetadata.abstract || openAlexMetadata.abstract, title: grobidMetadata.title || openAlexMetadata.title, }; - } else { + } else if (grobidMetadata) { metadata = { - title: grobidMetadata.title, - abstract: grobidMetadata.abstract, - authors: grobidMetadata.authors.map((author) => ({ name: author, affiliations: [], orcid: '' })), + title: grobidMetadata?.title, + abstract: grobidMetadata?.abstract, + authors: grobidMetadata?.authors.map((author) => ({ name: author, affiliations: [], orcid: '' })), pdfUrl: '', keywords: [], }; diff --git a/desci-server/src/services/AutomatedMetadata.ts b/desci-server/src/services/AutomatedMetadata.ts index 92ba5017..0a3aa288 100644 --- a/desci-server/src/services/AutomatedMetadata.ts +++ b/desci-server/src/services/AutomatedMetadata.ts @@ -13,6 +13,8 @@ import repoService from './repoService.js'; const logger = parentLogger.child({ module: '[AutomatedMetadataClient]' }); +const IPFS_RESOLVER = process.env.IPFS_RESOLVER_OVERRIDE || 'https://ipfs.desci.com/ipfs'; + export const delay = async (timeMs: number) => { return new Promise((resolve) => setTimeout(resolve, timeMs)); }; @@ -114,6 +116,13 @@ export interface OpenAlexWork { abstract_inverted_index?: { [key: string]: number[] }; } +const DEFAULT_GROBID_METADATA = { + authors: [], + title: '', + abstract: '', + doi: '', +}; + /** * A wrapper http client for querying, caching and parsing requests * from the CrossRef Rest Api https://www.crossref.org/documentation/retrieve-metadata/rest-api/ @@ -142,7 +151,7 @@ export class AutomatedMetadataClient { const body: { pdf: string; doi?: string } | { doi: string; pdf?: string } = { pdf: '' }; if (query.cid) { - body.pdf = `https://ipfs.desci.com/ipfs/${query.cid}`; + body.pdf = `${IPFS_RESOLVER}/${query.cid}`; } if (query.doi) { @@ -183,7 +192,7 @@ export class AutomatedMetadataClient { try { if (!cid) throw new Error('Invalid data'); - const pdfUrl = `${process.env.IPFS_RESOLVER_OVERRIDE}/${cid}`; + const pdfUrl = `${IPFS_RESOLVER}/${cid}`; let response = await axios.head(pdfUrl); const contentType = response.headers['content-type']; @@ -191,7 +200,7 @@ export class AutomatedMetadataClient { if (contentType.toLowerCase() !== 'application/pdf') { logger.error({ contentType, cid: cid }, 'CID CONTENT NOT A PDF FILE'); - return null; + return DEFAULT_GROBID_METADATA; } logger.info({ contentType, pdfUrl }, 'PDF RESPONSE CONTENT'); @@ -213,13 +222,13 @@ export class AutomatedMetadataClient { const url = 'https://grobid-dev.desci.com/api/processHeaderDocument'; response = await axios.request({ url, method: 'POST', data: formdata, headers: { ...formdata.getHeaders() } }); logger.info({ header: response.data }, 'GROBID RESPONSE'); - if (response.status !== 200) return null; + if (response.status !== 200) return DEFAULT_GROBID_METADATA; // transform data const headerMetadata = parseBibtext(response.data); return headerMetadata; } catch (error) { logger.error(error, 'ERROR'); - return null; + return DEFAULT_GROBID_METADATA; } } From 0ade08f60ad6474c15b0dfb103b2d916e65dcfcd Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Mon, 8 Jul 2024 15:16:41 +0200 Subject: [PATCH 277/278] fix: parser --- desci-server/src/services/AutomatedMetadata.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/desci-server/src/services/AutomatedMetadata.ts b/desci-server/src/services/AutomatedMetadata.ts index 0a3aa288..305d3adb 100644 --- a/desci-server/src/services/AutomatedMetadata.ts +++ b/desci-server/src/services/AutomatedMetadata.ts @@ -399,8 +399,14 @@ const parseBibtext = (input: string) => { skipUntil('}'); line = input.substring(start, cursor - 1); const authors = line - .split(',') - .map((text) => text.trim()) + .split(' and ') + .map((text) => + text + .trim() + .split(',') + .map((t) => t.trim()) + .join(' '), + ) .filter(Boolean); // console.log({ authors, line, cursor }); metadata['authors'] = authors; From bd03fcd1be71aa92b7d94f306458d469d65ca9a4 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Mon, 8 Jul 2024 23:44:27 +0200 Subject: [PATCH 278/278] sync with main --- .../src/routes/v1/attestations/index.ts | 4 +-- desci-server/src/workers/publish.ts | 34 +++++++++++-------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/desci-server/src/routes/v1/attestations/index.ts b/desci-server/src/routes/v1/attestations/index.ts index 825e7a70..aa16950b 100644 --- a/desci-server/src/routes/v1/attestations/index.ts +++ b/desci-server/src/routes/v1/attestations/index.ts @@ -41,8 +41,8 @@ import { const router = Router(); -router.get('/suggestions/all', [ensureUser], asyncHandler(getAllRecommendations)); -router.get('/suggestions/protected', [ensureUser], asyncHandler(getValidatedRecommendations)); +router.get('/suggestions/all', [], asyncHandler(getAllRecommendations)); +router.get('/suggestions/protected', [], asyncHandler(getValidatedRecommendations)); router.get( '/claims/:communityId/:dpid', [ensureUser, validate(showCommunityClaimsSchema)], diff --git a/desci-server/src/workers/publish.ts b/desci-server/src/workers/publish.ts index d78b1484..2f3c3bd8 100644 --- a/desci-server/src/workers/publish.ts +++ b/desci-server/src/workers/publish.ts @@ -33,7 +33,7 @@ const checkTransaction = async (transactionId: string, uuid: string) => { }, 'TX::check transaction', ); - }; + } const tx = await provider.getTransactionReceipt(transactionId); logger.info({ tx, uuid, transactionId, ETHEREUM_RPC_URL, network: await provider.getNetwork() }, 'TX::Receipt'); @@ -58,7 +58,7 @@ async function processPublishQueue() { await fixDpid(task.dpid); } else { logger.warn('DPID URL not set, skipping dpid fix'); - }; + } lockService.freeLock(task.transactionId); }) .catch((err) => { @@ -112,19 +112,23 @@ const delay = async (timeMs: number) => { export async function runWorkerUntilStopped() { while (true) { - const outcome = await processPublishQueue(); - if (!process.env.MUTE_PUBLISH_WORKER) logger.trace({ outcome }, 'Processed Queue'); - switch (outcome) { - case ProcessOutcome.EmptyQueue: - await delay(10000); - break; - case ProcessOutcome.Error: - await delay(1000); - break; - case ProcessOutcome.TaskCompleted: - break; - default: - logger.error({ outcome }, 'UNREACHABLE CODE REACHED, CHECK IMMEDIATELY'); + try { + const outcome = await processPublishQueue(); + if (!process.env.MUTE_PUBLISH_WORKER) logger.trace({ outcome }, 'Processed Queue'); + switch (outcome) { + case ProcessOutcome.EmptyQueue: + await delay(10000); + break; + case ProcessOutcome.Error: + await delay(1000); + break; + case ProcessOutcome.TaskCompleted: + break; + default: + logger.error({ outcome }, 'UNREACHABLE CODE REACHED, CHECK IMMEDIATELY'); + } + } catch (e) { + logger.error({ e }, 'PUBLISH WORKER LOOP ERROR'); } } }

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 sYNXjns@1Px# literal 0 HcmV?d00001 diff --git a/desci-media-isolated/src/services/pdf.ts b/desci-media-isolated/src/services/pdf.ts index 51b2410e..12c3c1ab 100644 --- a/desci-media-isolated/src/services/pdf.ts +++ b/desci-media-isolated/src/services/pdf.ts @@ -14,6 +14,7 @@ import { type DrawCenteredImagesParams, type PdfImageObject, } from '../types/pdf.js'; +import fontkit from 'pdflib-fontkit'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -44,7 +45,31 @@ export class PdfManipulationService { // Proccess the pdf file to add the cover page const pdfBytes = await readFileToBuffer(tempFilePath); const pdfDoc = await PDFDocument.load(pdfBytes); - const helveticaFont = await pdfDoc.embedFont(StandardFonts.Helvetica); + + /** + * Load Fonts + */ + + // Enable custom font loading + pdfDoc.registerFontkit(fontkit); + + // Satoshi Bold + const satoshiBoldBytes = await fs.promises.readFile( + path.join(__dirname, '../../public/static/fonts/Satoshi-Bold.ttf'), + ); + const satoshiBoldFont = await pdfDoc.embedFont(satoshiBoldBytes); + + // Inter Medium + const interMediumBytes = await fs.promises.readFile( + path.join(__dirname, '../../public/static/fonts/Inter-Medium.ttf'), + ); + const interMediumFont = await pdfDoc.embedFont(interMediumBytes); + + // Inter Regular + const interRegularBytes = await fs.promises.readFile( + path.join(__dirname, '../../public/static/fonts/Inter-Regular.ttf'), + ); + const interRegularFont = await pdfDoc.embedFont(interRegularBytes); const newPage = pdfDoc.insertPage(0); const { width, height } = newPage.getSize(); @@ -62,7 +87,7 @@ export class PdfManipulationService { this.drawCenteredMultilineText({ page: newPage, text: topHeader, - font: helveticaFont, + font: interRegularFont, fontSize: headerSize, width, height, @@ -80,7 +105,7 @@ export class PdfManipulationService { const titleLines = await this.drawCenteredMultilineText({ page: newPage, text: title, - font: helveticaFont, + font: satoshiBoldFont, fontSize: titleSize, width, height, @@ -93,13 +118,13 @@ export class PdfManipulationService { */ const authorsProcessed = this.formatAuthors(authors || [], authorLimit); const authorsSize = 18; - const titleHeight = titleLines.length * helveticaFont.heightAtSize(titleSize); + const titleHeight = titleLines.length * interMediumFont.heightAtSize(titleSize); const authorsPosY = titlePosY + titleHeight / height; const authorsLines = await this.drawCenteredMultilineText({ page: newPage, text: authorsProcessed, - font: helveticaFont, + font: interMediumFont, fontSize: authorsSize, width, height, @@ -112,13 +137,13 @@ export class PdfManipulationService { */ const centeredText = 'Data and/or code available at:'; const centeredTextSize = 20; - const authorsHeight = authorsLines.length * helveticaFont.heightAtSize(authorsSize); + const authorsHeight = authorsLines.length * interMediumFont.heightAtSize(authorsSize); const centeredTextPosY = authorsPosY + authorsHeight / height + 0.1; this.drawCenteredMultilineText({ page: newPage, text: centeredText, - font: helveticaFont, + font: interRegularFont, fontSize: centeredTextSize, width, height, @@ -130,14 +155,14 @@ export class PdfManipulationService { * NODE URL */ const doiUrlSize = 20; - const centeredTextHeight = helveticaFont.heightAtSize(centeredTextSize); + const centeredTextHeight = interRegularFont.heightAtSize(centeredTextSize); const doiUrlPosY = centeredTextPosY + centeredTextHeight / height + 0.01; const doiUrlColor = rgb(0, 0, 1); this.drawCenteredMultilineText({ page: newPage, text: nodeUrl, - font: helveticaFont, + font: interRegularFont, fontSize: doiUrlSize, width, height, @@ -187,7 +212,7 @@ export class PdfManipulationService { this.drawCenteredMultilineText({ page: newPage, text: claimedBadgesTitle, - font: helveticaFont, + font: interRegularFont, fontSize: claimedBadgesTitleSize, width, height, @@ -203,6 +228,7 @@ export class PdfManipulationService { positionY: claimedBadgesTitlePosY + claimedBadgesTitleSize / height + 0.04, gap: 20, annotateImage: true, + font: interRegularFont, }); } const pdfBytesMod = await pdfDoc.save(); From 02d16cf67895538320f905bee166b7f387807f22 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Mon, 27 May 2024 09:20:30 +0000 Subject: [PATCH 039/278] font sizes maatch designs --- desci-media-isolated/src/services/pdf.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/desci-media-isolated/src/services/pdf.ts b/desci-media-isolated/src/services/pdf.ts index 12c3c1ab..217f8708 100644 --- a/desci-media-isolated/src/services/pdf.ts +++ b/desci-media-isolated/src/services/pdf.ts @@ -82,7 +82,7 @@ export class PdfManipulationService { const topHeader = `Research object ${nodeUrl}, this version posted ${publishDate}. The copyright holder for this research object (which was not certified by peer review) is the author/funder, who has granted DeSci Labs a non-exclsuive license to display the research object in perpetuity. It is made available under a${ licenseStartsWithVowel ? 'n' : '' } ${license} license.`; - const headerSize = 12; + const headerSize = 10; this.drawCenteredMultilineText({ page: newPage, @@ -99,7 +99,7 @@ export class PdfManipulationService { /* * Title */ - const titleSize = 30; + const titleSize = 24; const titlePosY = 0.35; const titleLines = await this.drawCenteredMultilineText({ @@ -117,7 +117,7 @@ export class PdfManipulationService { * Authors */ const authorsProcessed = this.formatAuthors(authors || [], authorLimit); - const authorsSize = 18; + const authorsSize = 14; const titleHeight = titleLines.length * interMediumFont.heightAtSize(titleSize); const authorsPosY = titlePosY + titleHeight / height; @@ -136,7 +136,7 @@ export class PdfManipulationService { * Center Text (Artifacts available here) */ const centeredText = 'Data and/or code available at:'; - const centeredTextSize = 20; + const centeredTextSize = 14; const authorsHeight = authorsLines.length * interMediumFont.heightAtSize(authorsSize); const centeredTextPosY = authorsPosY + authorsHeight / height + 0.1; @@ -154,7 +154,7 @@ export class PdfManipulationService { /* * NODE URL */ - const doiUrlSize = 20; + const doiUrlSize = 14; const centeredTextHeight = interRegularFont.heightAtSize(centeredTextSize); const doiUrlPosY = centeredTextPosY + centeredTextHeight / height + 0.01; const doiUrlColor = rgb(0, 0, 1); From c256385d37d1ab2865738a991e4d3c38bd579e96 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Mon, 27 May 2024 11:55:43 +0200 Subject: [PATCH 040/278] add community member guard api for protected attestations resources and add tests --- .../controllers/attestations/verification.ts | 29 ++--- .../src/controllers/communities/guard.ts | 18 +++ .../src/controllers/communities/index.ts | 1 + .../src/routes/v1/attestations/index.ts | 3 - .../src/routes/v1/attestations/schema.ts | 6 - .../src/routes/v1/communities/index.ts | 6 +- .../src/routes/v1/communities/schema.ts | 6 + desci-server/src/services/Attestation.ts | 38 +++++- .../test/integration/Attestation.test.ts | 115 ++++++++++++------ 9 files changed, 157 insertions(+), 65 deletions(-) create mode 100644 desci-server/src/controllers/communities/guard.ts diff --git a/desci-server/src/controllers/attestations/verification.ts b/desci-server/src/controllers/attestations/verification.ts index a791f28f..19a2ace0 100644 --- a/desci-server/src/controllers/attestations/verification.ts +++ b/desci-server/src/controllers/attestations/verification.ts @@ -3,15 +3,10 @@ import { NextFunction, Request, Response } from 'express'; import _ from 'lodash'; import { - AuthFailureResponse, - BadRequestError, ForbiddenError, - NotFoundError, - RequestWithUser, SuccessMessageResponse, SuccessResponse, attestationService, - communityService, ensureUuidEndsWithDot, prisma, } from '../../internal.js'; @@ -131,17 +126,17 @@ export const getAttestationVerifications = async (req: Request, res: Response, n return new SuccessResponse(data).send(res); }; -export const canVerifyClaim = async (req: RequestWithUser, res: Response) => { - const logger = parentLogger.child({ - module: 'ATTESTATIONS::canVerify', - }); - const userId = req.user.id; - const claimId = parseInt(req.params.claimId); +// export const canVerifyClaim = async (req: RequestWithUser, res: Response) => { +// const logger = parentLogger.child({ +// module: 'ATTESTATIONS::canVerify', +// }); +// const userId = req.user.id; +// const claimId = parseInt(req.params.claimId); - const claim = await attestationService.findClaimById(claimId); - const isMember = await communityService.findMemberByUserId(claim.desciCommunityId, userId); +// const claim = await attestationService.findClaimById(claimId); +// const isMember = await communityService.findMemberByUserId(claim.desciCommunityId, userId); - logger.info({ userId: req.user.id, claimId, community: claim.desciCommunityId }, 'Claim Verification check'); - if (!isMember) new SuccessResponse({ ok: false }).send(res); - else new SuccessResponse({ ok: true }).send(res); -}; +// logger.info({ userId: req.user.id, claimId, community: claim.desciCommunityId }, 'Claim Verification check'); +// if (!isMember) new SuccessResponse({ ok: false }).send(res); +// else new SuccessResponse({ ok: true }).send(res); +// }; diff --git a/desci-server/src/controllers/communities/guard.ts b/desci-server/src/controllers/communities/guard.ts new file mode 100644 index 00000000..d788627c --- /dev/null +++ b/desci-server/src/controllers/communities/guard.ts @@ -0,0 +1,18 @@ +import { Response } from 'express'; + +import { SuccessResponse, communityService, logger } from '../../internal.js'; +import { RequestWithUser } from '../../middleware/authorisation.js'; + +export const checkMemberGuard = async (req: RequestWithUser, res: Response) => { + const log = logger.child({ + module: 'ATTESTATIONS::MemberGuard', + }); + const userId = req.user.id; + const communityId = parseInt(req.params.communityId); + + log.info({ userId: req.user.id, community: communityId }, 'Community Member Guard check'); + const isMember = await communityService.findMemberByUserId(communityId, userId); + + if (!isMember) new SuccessResponse({ ok: false }).send(res); + else new SuccessResponse({ ok: true }).send(res); +}; diff --git a/desci-server/src/controllers/communities/index.ts b/desci-server/src/controllers/communities/index.ts index 8788f837..e9fe2aaf 100644 --- a/desci-server/src/controllers/communities/index.ts +++ b/desci-server/src/controllers/communities/index.ts @@ -3,3 +3,4 @@ export * from './radar.js'; export * from './list.js'; export * from './types.js'; export * from './util.js'; +export * from './guard.js'; diff --git a/desci-server/src/routes/v1/attestations/index.ts b/desci-server/src/routes/v1/attestations/index.ts index cfefa0b0..359e3693 100644 --- a/desci-server/src/routes/v1/attestations/index.ts +++ b/desci-server/src/routes/v1/attestations/index.ts @@ -19,7 +19,6 @@ import { getAttestationVerifications, validate, getValidatedRecommendations, - canVerifyClaim, } from '../../../internal.js'; import { ensureUser } from '../../../middleware/permissions.js'; @@ -38,7 +37,6 @@ import { showCommunityClaimsSchema, showNodeAttestationsSchema, claimEntryAttestationsSchema, - canVerificationSchema, } from './schema.js'; const router = Router(); @@ -67,7 +65,6 @@ router.post('/claimAll', [ensureUser, validate(claimEntryAttestationsSchema)], a router.post('/comment', [ensureUser, validate(createCommentSchema)], asyncHander(addComment)); router.post('/reaction', [ensureUser, validate(addReactionSchema)], asyncHander(addReaction)); router.post('/verification', [ensureUser, validate(addVerificationSchema)], asyncHander(addVerification)); -router.post('/verification/check/:claimId', [ensureUser, validate(canVerificationSchema)], asyncHander(canVerifyClaim)); router.delete('/comments/:commentId', [ensureUser, validate(deleteCommentSchema)], asyncHander(removeComment)); router.delete('/reactions/:reactionId', [ensureUser, validate(deleteReactionSchema)], asyncHander(removeReaction)); diff --git a/desci-server/src/routes/v1/attestations/schema.ts b/desci-server/src/routes/v1/attestations/schema.ts index c7584f14..a720edf2 100644 --- a/desci-server/src/routes/v1/attestations/schema.ts +++ b/desci-server/src/routes/v1/attestations/schema.ts @@ -128,12 +128,6 @@ export const addVerificationSchema = z.object({ }), }); -export const canVerificationSchema = z.object({ - params: z.object({ - claimId: z.coerce.number(), - }), -}); - export const deleteCommentSchema = z.object({ params: z.object({ commentId: z.coerce.number() }), }); diff --git a/desci-server/src/routes/v1/communities/index.ts b/desci-server/src/routes/v1/communities/index.ts index 5881ddc1..5153e240 100644 --- a/desci-server/src/routes/v1/communities/index.ts +++ b/desci-server/src/routes/v1/communities/index.ts @@ -2,6 +2,8 @@ import { Router } from 'express'; import { asyncHander, + checkMemberGuard, + ensureUser, getAllFeeds, getCommunityDetails, getCommunityFeed, @@ -12,7 +14,7 @@ import { validate, } from '../../../internal.js'; -import { getCommunityDetailsSchema, getCommunityFeedSchema } from './schema.js'; +import { getCommunityDetailsSchema, getCommunityFeedSchema, memberGuardSchema } from './schema.js'; const router = Router(); @@ -35,4 +37,6 @@ router.get( router.get('/:communityId/feed', [validate(getCommunityFeedSchema)], asyncHander(getCommunityFeed)); router.get('/:communityId/radar', [validate(getCommunityFeedSchema)], asyncHander(getCommunityRadar)); +router.post('/:communityId/memberGuard', [ensureUser, validate(memberGuardSchema)], asyncHander(checkMemberGuard)); + export default router; diff --git a/desci-server/src/routes/v1/communities/schema.ts b/desci-server/src/routes/v1/communities/schema.ts index 7b04e43b..39ec76e7 100644 --- a/desci-server/src/routes/v1/communities/schema.ts +++ b/desci-server/src/routes/v1/communities/schema.ts @@ -11,3 +11,9 @@ export const getCommunityFeedSchema = z.object({ communityId: z.coerce.number(), }), }); + +export const memberGuardSchema = z.object({ + params: z.object({ + communityId: z.coerce.number(), + }), +}); diff --git a/desci-server/src/services/Attestation.ts b/desci-server/src/services/Attestation.ts index 63c53a82..d288c175 100644 --- a/desci-server/src/services/Attestation.ts +++ b/desci-server/src/services/Attestation.ts @@ -102,6 +102,16 @@ export class AttestationService { }; } + async checkUserIsMember(userId: number, communityId: number) { + // const attestation = await this.findAttestationById(claim.attestationId); + const member = await prisma.communityMember.findUnique({ + where: { userId_communityId: { userId, communityId } }, + }); + if (!member) throw new NoAccessError('Only Community members are allowed'); + + return true; + } + async #publishVersion(attestationVersion: Prisma.AttestationVersionUncheckedCreateInput) { return prisma.attestationVersion.create({ data: attestationVersion }); } @@ -448,10 +458,7 @@ export class AttestationService { const attestation = await this.findAttestationById(claim.attestationId); if (attestation.protected) { - const member = await prisma.communityMember.findUnique({ - where: { userId_communityId: { userId, communityId: attestation.communityId } }, - }); - if (!member) throw new NoAccessError('Only Community members are allowed'); + await this.checkUserIsMember(userId, claim.desciCommunityId); } const node = await prisma.node.findFirst({ where: { uuid: claim.nodeUuid } }); @@ -506,6 +513,11 @@ export class AttestationService { if (duplicate) throw new DuplicateReactionError(); + const attestation = await this.findAttestationById(claim.attestationId); + if (attestation.protected) { + await this.checkUserIsMember(authorId, claim.desciCommunityId); + } + return prisma.nodeAttestationReaction.create({ data: { authorId, reaction, nodeAttestationId: claimId } }); } @@ -537,6 +549,15 @@ export class AttestationService { }) { assert(authorId > 0, 'Error: authorId is zero'); assert(claimId > 0, 'Error: claimId is zero'); + + const claim = await this.findClaimById(claimId); + if (!claim) throw new ClaimNotFoundError(); + + const attestation = await this.findAttestationById(claim.attestationId); + if (attestation.protected) { + await this.checkUserIsMember(authorId, attestation.communityId); + } + const data: Prisma.AnnotationUncheckedCreateInput = { type: AnnotationType.COMMENT, authorId, @@ -562,6 +583,15 @@ export class AttestationService { }) { assert(authorId > 0, 'Error: authorId is zero'); assert(claimId > 0, 'Error: claimId is zero'); + + const claim = await this.findClaimById(claimId); + if (!claim) throw new ClaimNotFoundError(); + + const attestation = await this.findAttestationById(claim.attestationId); + if (attestation.protected) { + await this.checkUserIsMember(authorId, attestation.communityId); + } + const data: Prisma.AnnotationUncheckedCreateInput = { type: AnnotationType.HIGHLIGHT, authorId, diff --git a/desci-server/test/integration/Attestation.test.ts b/desci-server/test/integration/Attestation.test.ts index 9a908ff7..31ed8777 100644 --- a/desci-server/test/integration/Attestation.test.ts +++ b/desci-server/test/integration/Attestation.test.ts @@ -2179,49 +2179,96 @@ describe('Attestations Service', async () => { expect(verifications.some((v) => v.userId === members[0].userId)).to.equal(true); expect(verifications.some((v) => v.userId === members[1].userId)).to.equal(true); }); + }); - it.skip('should prevent double verification of Node Attestation(Claim)', async () => { - try { - await attestationService.verifyClaim(openCodeClaim.id, users[1].id); - } catch (err) { - expect(err).to.be.instanceOf(DuplicateVerificationError); - } - }); + describe.only('Protected Attestation Review', async () => { + let openCodeClaim: NodeAttestation; + let openDataClaim: NodeAttestation; + let node: Node; + const nodeVersion = 0; + let attestationVersion: AttestationVersion; + let author: User; + let members: (CommunityMember & { + user: User; + })[]; + let UserJwtToken: string, + UserAuthHeaderVal: string, + MemberJwtToken1: string, + MemberJwtToken2: string, + memberAuthHeaderVal1: string, + memberAuthHeaderVal2: string; - it.skip('should restrict author from verifying their claim', async () => { - try { - assert(author.id === node.ownerId); - await attestationService.verifyClaim(openCodeClaim.id, author.id); - } catch (err) { - expect(err).to.be.instanceOf(VerificationError); - } - }); + before(async () => { + node = nodes[0]; + author = users[0]; + assert(node.uuid); + const versions = await attestationService.getAttestationVersions(protectedOpenCode.id); + attestationVersion = versions[versions.length - 1]; + openCodeClaim = await attestationService.claimAttestation({ + attestationId: protectedOpenCode.id, + attestationVersion: attestationVersion.id, + nodeDpid: '1', + nodeUuid: node.uuid, + nodeVersion, + claimerId: author.id, + }); - it.skip('should remove verification', async () => { - const removedVerification = await attestationService.removeVerification(verification.id, users[1].id); - expect(removedVerification).to.not.be.null; - expect(removedVerification).to.not.be.undefined; - expect(removedVerification.id).to.equal(verification.id); + members = await communityService.getAllMembers(desciCommunity.id); + MemberJwtToken1 = jwt.sign({ email: members[0].user.email }, process.env.JWT_SECRET!, { + expiresIn: '1y', + }); + memberAuthHeaderVal1 = `Bearer ${MemberJwtToken1}`; - const voidVerification = await attestationService.getUserClaimVerification(openCodeClaim.id, users[1].id); - expect(voidVerification).to.be.null; + MemberJwtToken2 = jwt.sign({ email: members[1].user.email }, process.env.JWT_SECRET!, { + expiresIn: '1y', + }); + memberAuthHeaderVal2 = `Bearer ${MemberJwtToken2}`; + + UserJwtToken = jwt.sign({ email: users[1].email }, process.env.JWT_SECRET!, { + expiresIn: '1y', + }); + UserAuthHeaderVal = `Bearer ${UserJwtToken}`; }); - it.skip('should allow multiple users verify a node attestation(claim)', async () => { - const user2Verification = await attestationService.verifyClaim(openCodeClaim.id, users[2].id); - expect(user2Verification.nodeAttestationId).to.be.equal(openCodeClaim.id); - expect(user2Verification.userId).to.be.equal(users[2].id); + after(async () => { + await prisma.$queryRaw`TRUNCATE TABLE "NodeAttestation" CASCADE;`; + await prisma.$queryRaw`TRUNCATE TABLE "Annotation" CASCADE;`; + await prisma.$queryRaw`TRUNCATE TABLE "NodeAttestationVerification" CASCADE;`; + // await prisma.$queryRaw`TRUNCATE TABLE "CommunityMember" CASCADE;`; + }); - const user3Verification = await attestationService.verifyClaim(openCodeClaim.id, users[3].id); - expect(user3Verification.nodeAttestationId).to.be.equal(openCodeClaim.id); - expect(user3Verification.userId).to.be.equal(users[3].id); + it('should allow only community members review/comment a claimed attestation', async () => { + let res = await request(app).post(`/v1/attestations/comment`).set('authorization', memberAuthHeaderVal1).send({ + author: members[0].id, + claimId: openCodeClaim.id, + body: 'review 1', + }); + expect(res.statusCode).to.equal(200); - const verifications = await attestationService.getAllClaimVerfications(openCodeClaim.id); - expect(verifications.length).to.be.equal(2); + res = await request(app).post(`/v1/attestations/comment`).set('authorization', memberAuthHeaderVal2).send({ + claimId: openCodeClaim.id, + author: members[1].id, + body: 'review 2', + }); + expect(res.statusCode).to.equal(200); - assert(node.uuid); - const nodeVerifications = await attestationService.getAllNodeVerfications(node.uuid); - expect(nodeVerifications.length).to.be.equal(2); + const comments = await attestationService.getAllClaimComments({ nodeAttestationId: openCodeClaim.id }); + expect(comments.length).to.equal(2); + expect(comments.some((v) => v.authorId === members[0].userId && v.body)).to.equal(true); + expect(comments.some((v) => v.authorId === members[1].userId)).to.equal(true); + }); + + it('should prevent non-authorized users from reviewing a protected attestation(claim)', async () => { + const apiResponse = await request(app) + .post(`/v1/attestations/comment`) + .set('authorization', UserAuthHeaderVal) + .send({ + claimId: openDataClaim.id, + }); + expect(apiResponse.statusCode).to.equal(401); + + const comments = await attestationService.getAllClaimComments({ nodeAttestationId: openDataClaim.id }); + expect(comments.length).to.equal(0); }); }); }); From eca433c1a744d9833425e22affe12dfaf55d594c Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Mon, 27 May 2024 12:18:51 +0200 Subject: [PATCH 041/278] chore: add DPID_URL_OVERRIDE to k8s config, dpid url override if necessary --- desci-server/kubernetes/deployment_dev.yaml | 1 + desci-server/kubernetes/deployment_prod.yaml | 1 + desci-server/kubernetes/deployment_staging.yaml | 1 + desci-server/src/services/orcid.ts | 2 +- 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/desci-server/kubernetes/deployment_dev.yaml b/desci-server/kubernetes/deployment_dev.yaml index 4349fc74..878233b0 100644 --- a/desci-server/kubernetes/deployment_dev.yaml +++ b/desci-server/kubernetes/deployment_dev.yaml @@ -41,6 +41,7 @@ spec: export SESSION_KEY={{ .Data.SESSION_KEY }} export COOKIE_DOMAIN={{ .Data.COOKIE_DOMAIN }} export ORCID_API_DOMAIN={{ .Data.ORCID_API_DOMAIN }} + export DPID_URL_OVERRIDE={{ .Data.DPID_URL_OVERRIDE }} export ORCID_CLIENT_ID={{ .Data.ORCID_CLIENT_ID }} export ORCID_CLIENT_SECRET={{ .Data.ORCID_CLIENT_SECRET }} export ARWEAVE_ENABLED=0 diff --git a/desci-server/kubernetes/deployment_prod.yaml b/desci-server/kubernetes/deployment_prod.yaml index 8cc357a2..02c1398a 100755 --- a/desci-server/kubernetes/deployment_prod.yaml +++ b/desci-server/kubernetes/deployment_prod.yaml @@ -43,6 +43,7 @@ spec: export ORCID_API_DOMAIN={{ .Data.ORCID_API_DOMAIN }} export ORCID_CLIENT_ID={{ .Data.ORCID_CLIENT_ID }} export ORCID_CLIENT_SECRET={{ .Data.ORCID_CLIENT_SECRET }} + export DPID_URL_OVERRIDE={{ .Data.DPID_URL_OVERRIDE }} export ARWEAVE_ENABLED=0 export ARWEAVE_HOST= export ARWEAVE_PORT=1984 diff --git a/desci-server/kubernetes/deployment_staging.yaml b/desci-server/kubernetes/deployment_staging.yaml index 10b77a57..47fd50c9 100644 --- a/desci-server/kubernetes/deployment_staging.yaml +++ b/desci-server/kubernetes/deployment_staging.yaml @@ -55,6 +55,7 @@ spec: export ORCID_API_DOMAIN={{ .Data.ORCID_API_DOMAIN }} export ORCID_CLIENT_ID={{ .Data.ORCID_CLIENT_ID }} export ORCID_CLIENT_SECRET={{ .Data.ORCID_CLIENT_SECRET }} + export DPID_URL_OVERRIDE={{ .Data.DPID_URL_OVERRIDE }} export ARWEAVE_ENABLED=0 export ARWEAVE_HOST= export ARWEAVE_PORT=1984 diff --git a/desci-server/src/services/orcid.ts b/desci-server/src/services/orcid.ts index 6944393c..05a1cd19 100644 --- a/desci-server/src/services/orcid.ts +++ b/desci-server/src/services/orcid.ts @@ -10,7 +10,7 @@ import { getManifestByCid } from './data/processing.js'; // const PUTCODE_REGEX = /put-code=.*?(?\d+)/m; -const DPID_URL_OVERRIDE = process.env.DPID_URL_OVERRIDE || 'https://dev-beta.dpid.org'; +const DPID_URL_OVERRIDE = process.env.DPID_URL_OVERRIDE || 'https://beta.dpid.org'; const ORCID_DOMAIN = process.env.ORCID_API_DOMAIN || 'sandbox.orcid.org'; type Claim = Awaited>[number]; const logger = parentLogger.child({ module: 'ORCIDApiService' }); From e34fb2defcdc862ba79debc0c9fdfd1624ef5360 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20H=C3=BCbinette?= Date: Mon, 27 May 2024 13:21:30 +0200 Subject: [PATCH 042/278] Revert "DPID url config " --- desci-server/kubernetes/deployment_dev.yaml | 1 - desci-server/kubernetes/deployment_prod.yaml | 1 - desci-server/kubernetes/deployment_staging.yaml | 1 - desci-server/src/services/orcid.ts | 2 +- 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/desci-server/kubernetes/deployment_dev.yaml b/desci-server/kubernetes/deployment_dev.yaml index 878233b0..4349fc74 100644 --- a/desci-server/kubernetes/deployment_dev.yaml +++ b/desci-server/kubernetes/deployment_dev.yaml @@ -41,7 +41,6 @@ spec: export SESSION_KEY={{ .Data.SESSION_KEY }} export COOKIE_DOMAIN={{ .Data.COOKIE_DOMAIN }} export ORCID_API_DOMAIN={{ .Data.ORCID_API_DOMAIN }} - export DPID_URL_OVERRIDE={{ .Data.DPID_URL_OVERRIDE }} export ORCID_CLIENT_ID={{ .Data.ORCID_CLIENT_ID }} export ORCID_CLIENT_SECRET={{ .Data.ORCID_CLIENT_SECRET }} export ARWEAVE_ENABLED=0 diff --git a/desci-server/kubernetes/deployment_prod.yaml b/desci-server/kubernetes/deployment_prod.yaml index 02c1398a..8cc357a2 100755 --- a/desci-server/kubernetes/deployment_prod.yaml +++ b/desci-server/kubernetes/deployment_prod.yaml @@ -43,7 +43,6 @@ spec: export ORCID_API_DOMAIN={{ .Data.ORCID_API_DOMAIN }} export ORCID_CLIENT_ID={{ .Data.ORCID_CLIENT_ID }} export ORCID_CLIENT_SECRET={{ .Data.ORCID_CLIENT_SECRET }} - export DPID_URL_OVERRIDE={{ .Data.DPID_URL_OVERRIDE }} export ARWEAVE_ENABLED=0 export ARWEAVE_HOST= export ARWEAVE_PORT=1984 diff --git a/desci-server/kubernetes/deployment_staging.yaml b/desci-server/kubernetes/deployment_staging.yaml index 47fd50c9..10b77a57 100644 --- a/desci-server/kubernetes/deployment_staging.yaml +++ b/desci-server/kubernetes/deployment_staging.yaml @@ -55,7 +55,6 @@ spec: export ORCID_API_DOMAIN={{ .Data.ORCID_API_DOMAIN }} export ORCID_CLIENT_ID={{ .Data.ORCID_CLIENT_ID }} export ORCID_CLIENT_SECRET={{ .Data.ORCID_CLIENT_SECRET }} - export DPID_URL_OVERRIDE={{ .Data.DPID_URL_OVERRIDE }} export ARWEAVE_ENABLED=0 export ARWEAVE_HOST= export ARWEAVE_PORT=1984 diff --git a/desci-server/src/services/orcid.ts b/desci-server/src/services/orcid.ts index 05a1cd19..6944393c 100644 --- a/desci-server/src/services/orcid.ts +++ b/desci-server/src/services/orcid.ts @@ -10,7 +10,7 @@ import { getManifestByCid } from './data/processing.js'; // const PUTCODE_REGEX = /put-code=.*?(?\d+)/m; -const DPID_URL_OVERRIDE = process.env.DPID_URL_OVERRIDE || 'https://beta.dpid.org'; +const DPID_URL_OVERRIDE = process.env.DPID_URL_OVERRIDE || 'https://dev-beta.dpid.org'; const ORCID_DOMAIN = process.env.ORCID_API_DOMAIN || 'sandbox.orcid.org'; type Claim = Awaited>[number]; const logger = parentLogger.child({ module: 'ORCIDApiService' }); From 9aba64dd75009a9d2a53683681bc36cf2f59fd4c Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Mon, 27 May 2024 16:59:25 +0200 Subject: [PATCH 043/278] fix: broken tests --- desci-server/src/services/Attestation.ts | 3 +- .../test/integration/Attestation.test.ts | 29 ++++++++++++------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/desci-server/src/services/Attestation.ts b/desci-server/src/services/Attestation.ts index d288c175..c00bd376 100644 --- a/desci-server/src/services/Attestation.ts +++ b/desci-server/src/services/Attestation.ts @@ -2,7 +2,6 @@ import assert from 'assert'; import { HighlightBlock } from '@desci-labs/desci-models'; import { AnnotationType, Attestation, Prisma } from '@prisma/client'; -import { logger } from 'ethers'; import _ from 'lodash'; import { prisma } from '../client.js'; @@ -19,6 +18,7 @@ import { NoAccessError, VerificationError, VerificationNotFoundError, + logger, } from '../internal.js'; import { communityService } from '../internal.js'; @@ -107,6 +107,7 @@ export class AttestationService { const member = await prisma.communityMember.findUnique({ where: { userId_communityId: { userId, communityId } }, }); + logger.error({ member, userId, communityId }, 'Check community member'); if (!member) throw new NoAccessError('Only Community members are allowed'); return true; diff --git a/desci-server/test/integration/Attestation.test.ts b/desci-server/test/integration/Attestation.test.ts index 31ed8777..da7efad8 100644 --- a/desci-server/test/integration/Attestation.test.ts +++ b/desci-server/test/integration/Attestation.test.ts @@ -2181,7 +2181,7 @@ describe('Attestations Service', async () => { }); }); - describe.only('Protected Attestation Review', async () => { + describe('Protected Attestation Review', async () => { let openCodeClaim: NodeAttestation; let openDataClaim: NodeAttestation; let node: Node; @@ -2238,18 +2238,23 @@ describe('Attestations Service', async () => { }); it('should allow only community members review/comment a claimed attestation', async () => { - let res = await request(app).post(`/v1/attestations/comment`).set('authorization', memberAuthHeaderVal1).send({ - author: members[0].id, + let body = { + authorId: members[0].userId, claimId: openCodeClaim.id, body: 'review 1', - }); + }; + let res = await request(app) + .post(`/v1/attestations/comment`) + .set('authorization', memberAuthHeaderVal1) + .send(body); expect(res.statusCode).to.equal(200); - res = await request(app).post(`/v1/attestations/comment`).set('authorization', memberAuthHeaderVal2).send({ + body = { + authorId: members[1].userId, claimId: openCodeClaim.id, - author: members[1].id, body: 'review 2', - }); + }; + res = await request(app).post(`/v1/attestations/comment`).set('authorization', memberAuthHeaderVal2).send(body); expect(res.statusCode).to.equal(200); const comments = await attestationService.getAllClaimComments({ nodeAttestationId: openCodeClaim.id }); @@ -2258,17 +2263,19 @@ describe('Attestations Service', async () => { expect(comments.some((v) => v.authorId === members[1].userId)).to.equal(true); }); - it('should prevent non-authorized users from reviewing a protected attestation(claim)', async () => { + it('should prevent non community members from reviewing a protected attestation(claim)', async () => { const apiResponse = await request(app) .post(`/v1/attestations/comment`) .set('authorization', UserAuthHeaderVal) .send({ - claimId: openDataClaim.id, + authorId: users[1].id, + claimId: openCodeClaim.id, + body: 'review 1', }); expect(apiResponse.statusCode).to.equal(401); - const comments = await attestationService.getAllClaimComments({ nodeAttestationId: openDataClaim.id }); - expect(comments.length).to.equal(0); + const comments = await attestationService.getAllClaimComments({ nodeAttestationId: openCodeClaim.id }); + expect(comments.length).to.equal(2); }); }); }); From c9b52cacbe6a3c2c563370eba4ad2494209f5681 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Tue, 28 May 2024 10:54:46 +0200 Subject: [PATCH 044/278] chore: clean up stale code --- .../src/controllers/attestations/verification.ts | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/desci-server/src/controllers/attestations/verification.ts b/desci-server/src/controllers/attestations/verification.ts index 19a2ace0..f2c2b425 100644 --- a/desci-server/src/controllers/attestations/verification.ts +++ b/desci-server/src/controllers/attestations/verification.ts @@ -125,18 +125,3 @@ export const getAttestationVerifications = async (req: Request, res: Response, n return new SuccessResponse(data).send(res); }; - -// export const canVerifyClaim = async (req: RequestWithUser, res: Response) => { -// const logger = parentLogger.child({ -// module: 'ATTESTATIONS::canVerify', -// }); -// const userId = req.user.id; -// const claimId = parseInt(req.params.claimId); - -// const claim = await attestationService.findClaimById(claimId); -// const isMember = await communityService.findMemberByUserId(claim.desciCommunityId, userId); - -// logger.info({ userId: req.user.id, claimId, community: claim.desciCommunityId }, 'Claim Verification check'); -// if (!isMember) new SuccessResponse({ ok: false }).send(res); -// else new SuccessResponse({ ok: true }).send(res); -// }; From 3391e4ab9afe2d82fa2352992524226c87711941 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20H=C3=BCbinette?= Date: Tue, 28 May 2024 13:48:15 +0200 Subject: [PATCH 045/278] Revert "Revert "DPID url config "" --- desci-server/kubernetes/deployment_dev.yaml | 1 + desci-server/kubernetes/deployment_prod.yaml | 1 + desci-server/kubernetes/deployment_staging.yaml | 1 + desci-server/src/services/orcid.ts | 2 +- 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/desci-server/kubernetes/deployment_dev.yaml b/desci-server/kubernetes/deployment_dev.yaml index 4349fc74..878233b0 100644 --- a/desci-server/kubernetes/deployment_dev.yaml +++ b/desci-server/kubernetes/deployment_dev.yaml @@ -41,6 +41,7 @@ spec: export SESSION_KEY={{ .Data.SESSION_KEY }} export COOKIE_DOMAIN={{ .Data.COOKIE_DOMAIN }} export ORCID_API_DOMAIN={{ .Data.ORCID_API_DOMAIN }} + export DPID_URL_OVERRIDE={{ .Data.DPID_URL_OVERRIDE }} export ORCID_CLIENT_ID={{ .Data.ORCID_CLIENT_ID }} export ORCID_CLIENT_SECRET={{ .Data.ORCID_CLIENT_SECRET }} export ARWEAVE_ENABLED=0 diff --git a/desci-server/kubernetes/deployment_prod.yaml b/desci-server/kubernetes/deployment_prod.yaml index 8cc357a2..02c1398a 100755 --- a/desci-server/kubernetes/deployment_prod.yaml +++ b/desci-server/kubernetes/deployment_prod.yaml @@ -43,6 +43,7 @@ spec: export ORCID_API_DOMAIN={{ .Data.ORCID_API_DOMAIN }} export ORCID_CLIENT_ID={{ .Data.ORCID_CLIENT_ID }} export ORCID_CLIENT_SECRET={{ .Data.ORCID_CLIENT_SECRET }} + export DPID_URL_OVERRIDE={{ .Data.DPID_URL_OVERRIDE }} export ARWEAVE_ENABLED=0 export ARWEAVE_HOST= export ARWEAVE_PORT=1984 diff --git a/desci-server/kubernetes/deployment_staging.yaml b/desci-server/kubernetes/deployment_staging.yaml index 10b77a57..47fd50c9 100644 --- a/desci-server/kubernetes/deployment_staging.yaml +++ b/desci-server/kubernetes/deployment_staging.yaml @@ -55,6 +55,7 @@ spec: export ORCID_API_DOMAIN={{ .Data.ORCID_API_DOMAIN }} export ORCID_CLIENT_ID={{ .Data.ORCID_CLIENT_ID }} export ORCID_CLIENT_SECRET={{ .Data.ORCID_CLIENT_SECRET }} + export DPID_URL_OVERRIDE={{ .Data.DPID_URL_OVERRIDE }} export ARWEAVE_ENABLED=0 export ARWEAVE_HOST= export ARWEAVE_PORT=1984 diff --git a/desci-server/src/services/orcid.ts b/desci-server/src/services/orcid.ts index 6944393c..05a1cd19 100644 --- a/desci-server/src/services/orcid.ts +++ b/desci-server/src/services/orcid.ts @@ -10,7 +10,7 @@ import { getManifestByCid } from './data/processing.js'; // const PUTCODE_REGEX = /put-code=.*?(?\d+)/m; -const DPID_URL_OVERRIDE = process.env.DPID_URL_OVERRIDE || 'https://dev-beta.dpid.org'; +const DPID_URL_OVERRIDE = process.env.DPID_URL_OVERRIDE || 'https://beta.dpid.org'; const ORCID_DOMAIN = process.env.ORCID_API_DOMAIN || 'sandbox.orcid.org'; type Claim = Awaited>[number]; const logger = parentLogger.child({ module: 'ORCIDApiService' }); From 5d884aa8a842f46593e8d96f835a77a2613ec58a Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Tue, 28 May 2024 13:54:17 +0200 Subject: [PATCH 046/278] fix: member guard assert logic --- desci-server/src/services/Attestation.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/desci-server/src/services/Attestation.ts b/desci-server/src/services/Attestation.ts index c00bd376..b416511c 100644 --- a/desci-server/src/services/Attestation.ts +++ b/desci-server/src/services/Attestation.ts @@ -102,15 +102,15 @@ export class AttestationService { }; } - async checkUserIsMember(userId: number, communityId: number) { - // const attestation = await this.findAttestationById(claim.attestationId); + async assertUserIsMember(userId: number, communityId: number) { const member = await prisma.communityMember.findUnique({ where: { userId_communityId: { userId, communityId } }, }); - logger.error({ member, userId, communityId }, 'Check community member'); - if (!member) throw new NoAccessError('Only Community members are allowed'); - return true; + if (!member) { + logger.error({ userId, communityId }, 'UnAuthorized Verify Attestation Call'); + throw new NoAccessError('Only Community members are allowed'); + } } async #publishVersion(attestationVersion: Prisma.AttestationVersionUncheckedCreateInput) { @@ -459,7 +459,7 @@ export class AttestationService { const attestation = await this.findAttestationById(claim.attestationId); if (attestation.protected) { - await this.checkUserIsMember(userId, claim.desciCommunityId); + await this.assertUserIsMember(userId, claim.desciCommunityId); } const node = await prisma.node.findFirst({ where: { uuid: claim.nodeUuid } }); @@ -516,7 +516,7 @@ export class AttestationService { const attestation = await this.findAttestationById(claim.attestationId); if (attestation.protected) { - await this.checkUserIsMember(authorId, claim.desciCommunityId); + await this.assertUserIsMember(authorId, claim.desciCommunityId); } return prisma.nodeAttestationReaction.create({ data: { authorId, reaction, nodeAttestationId: claimId } }); @@ -556,7 +556,7 @@ export class AttestationService { const attestation = await this.findAttestationById(claim.attestationId); if (attestation.protected) { - await this.checkUserIsMember(authorId, attestation.communityId); + await this.assertUserIsMember(authorId, attestation.communityId); } const data: Prisma.AnnotationUncheckedCreateInput = { @@ -590,7 +590,7 @@ export class AttestationService { const attestation = await this.findAttestationById(claim.attestationId); if (attestation.protected) { - await this.checkUserIsMember(authorId, attestation.communityId); + await this.assertUserIsMember(authorId, attestation.communityId); } const data: Prisma.AnnotationUncheckedCreateInput = { From b9f7447651a2ba758864bdf95ef82801285e22ce Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Tue, 28 May 2024 15:18:26 +0200 Subject: [PATCH 047/278] add more action types to interaction logs, save interactions where needed --- desci-server/prisma/schema.prisma | 10 ++ .../src/controllers/attestations/claims.ts | 15 ++- .../src/controllers/attestations/comments.ts | 11 +- .../controllers/attestations/verification.ts | 17 ++- desci-server/src/services/orcid.ts | 104 +++++++++++++----- 5 files changed, 124 insertions(+), 33 deletions(-) diff --git a/desci-server/prisma/schema.prisma b/desci-server/prisma/schema.prisma index 790372d9..159b1bbe 100755 --- a/desci-server/prisma/schema.prisma +++ b/desci-server/prisma/schema.prisma @@ -869,6 +869,16 @@ enum ActionType { NEW_REFERRAL ACCEPTED_REFERRAL USER_PUBLISH_CONSENT + CLAIM_ATTESTATION + REVOKE_CLAIM + CLAIM_ENTRY_ATTESTATIONS + ADD_COMMENT + REMOVE_COMMENT + VERIFY_ATTESTATION + UNVERIFY_ATTESTATION + UPDATE_ORCID_RECORD + REMOVE_ORCID_WORK_RECORD + ORCID_API_ERROR } enum ChainTransactionType { diff --git a/desci-server/src/controllers/attestations/claims.ts b/desci-server/src/controllers/attestations/claims.ts index d499fc35..f790dbb6 100644 --- a/desci-server/src/controllers/attestations/claims.ts +++ b/desci-server/src/controllers/attestations/claims.ts @@ -1,4 +1,4 @@ -import { CommunityEntryAttestation } from '@prisma/client'; +import { ActionType, CommunityEntryAttestation } from '@prisma/client'; import sgMail from '@sendgrid/mail'; import { NextFunction, Request, Response } from 'express'; import _ from 'lodash'; @@ -16,6 +16,7 @@ import { } from '../../internal.js'; import { RequestWithUser } from '../../middleware/authorisation.js'; import { removeClaimSchema } from '../../routes/v1/attestations/schema.js'; +import { saveInteraction } from '../../services/interactionLog.js'; import { AttestationClaimedEmailHtml } from '../../templates/emails/utils/emailRenderer.js'; sgMail.setApiKey(process.env.SENDGRID_API_KEY); @@ -52,7 +53,7 @@ export const claimAttestation = async (req: RequestWithUser, res: Response, _nex nodeUuid: uuid, attestationVersion: attestationVersion.id, }); - + await saveInteraction(req, ActionType.CLAIM_ATTESTATION, { ...body, claimId: nodeClaim.id }); // notifiy community members if attestation is protected // new attestations should be trigger notification of org members if protected const attestation = await attestationService.findAttestationById(body.attestationId); @@ -114,8 +115,10 @@ export const removeClaim = async (req: RequestWithUser, res: Response, _next: Ne ? await attestationService.revokeAttestation(claim.id) : await attestationService.unClaimAttestation(claim.id); + await saveInteraction(req, ActionType.REVOKE_CLAIM, body); + logger.info({ removeOrRevoke, totalSignal, claimSignal }, 'Claim Removed|Revoked'); - return new SuccessMessageResponse('Attestation unclaimed').send(res); + new SuccessMessageResponse('Attestation unclaimed').send(res); }; export const claimEntryRequirements = async (req: Request, res: Response, _next: NextFunction) => { @@ -168,5 +171,11 @@ export const claimEntryRequirements = async (req: Request, res: Response, _next: attestations: claims, }); + await saveInteraction(req, ActionType.CLAIM_ENTRY_ATTESTATIONS, { + communityId, + nodeDpid, + claimerId, + claims: attestations.map((att) => att.id), + }); return new SuccessResponse(attestations).send(res); }; diff --git a/desci-server/src/controllers/attestations/comments.ts b/desci-server/src/controllers/attestations/comments.ts index 8f7b3ac5..7949fe8c 100644 --- a/desci-server/src/controllers/attestations/comments.ts +++ b/desci-server/src/controllers/attestations/comments.ts @@ -1,5 +1,5 @@ import { HighlightBlock } from '@desci-labs/desci-models'; -import { Annotation } from '@prisma/client'; +import { ActionType, Annotation } from '@prisma/client'; import { NextFunction, Request, Response } from 'express'; import _ from 'lodash'; import zod from 'zod'; @@ -15,6 +15,7 @@ import { createCommentSchema, logger as parentLogger, } from '../../internal.js'; +import { saveInteraction } from '../../services/interactionLog.js'; import { client } from '../../services/ipfs.js'; import { base64ToBlob } from '../../utils/upload.js'; @@ -64,6 +65,12 @@ export const removeComment = async (req: Request, r } else { if (comment.authorId !== user.id) throw new ForbiddenError(); await attestationService.removeComment(parseInt(commentId)); + await saveInteraction(req, ActionType.REMOVE_COMMENT, { + commentId, + claimId: comment.nodeAttestationId, + authorId: comment.authorId, + userId: user.id, + }); new SuccessMessageResponse().send(res); } }; @@ -101,6 +108,7 @@ export const addComment = async (req: Request, links, highlights: processedHighlights as unknown as HighlightBlock[], }); + await saveInteraction(req, ActionType.ADD_COMMENT, { annotationId: annotation.id, claimId, authorId }); } else { annotation = await attestationService.createComment({ claimId: parseInt(claimId.toString()), @@ -108,6 +116,7 @@ export const addComment = async (req: Request, comment: body, links, }); + await saveInteraction(req, ActionType.ADD_COMMENT, { annotationId: annotation.id, claimId, authorId }); } new SuccessResponse({ diff --git a/desci-server/src/controllers/attestations/verification.ts b/desci-server/src/controllers/attestations/verification.ts index a791f28f..b1ca54b0 100644 --- a/desci-server/src/controllers/attestations/verification.ts +++ b/desci-server/src/controllers/attestations/verification.ts @@ -1,12 +1,10 @@ +import { ActionType } from '@prisma/client'; import { NextFunction, Request, Response } from 'express'; // import { Attestation, NodeAttestation } from '@prisma/client'; import _ from 'lodash'; import { - AuthFailureResponse, - BadRequestError, ForbiddenError, - NotFoundError, RequestWithUser, SuccessMessageResponse, SuccessResponse, @@ -16,6 +14,7 @@ import { prisma, } from '../../internal.js'; import { logger as parentLogger } from '../../logger.js'; +import { saveInteraction, saveInteractionWithoutReq } from '../../services/interactionLog.js'; import orcidApiService from '../../services/orcid.js'; type RemoveVerificationBody = { @@ -51,7 +50,10 @@ export const removeVerification = async ( new SuccessMessageResponse().send(res); } else { await attestationService.removeVerification(verification.id, user.id); - + await saveInteraction(req, ActionType.UNVERIFY_ATTESTATION, { + claimId: verification.nodeAttestationId, + userId: user.id, + }); new SuccessMessageResponse().send(res); const claim = await attestationService.findClaimById(verification.nodeAttestationId); @@ -96,6 +98,7 @@ export const addVerification = async ( const claim = await attestationService.findClaimById(parseInt(claimId)); await attestationService.verifyClaim(parseInt(claimId), user.id); + await saveInteraction(req, ActionType.VERIFY_ATTESTATION, { claimId: claimId, userId: user.id }); const attestation = await attestationService.findAttestationById(claim.attestationId); @@ -108,6 +111,12 @@ export const addVerification = async ( const node = await prisma.node.findFirst({ where: { uuid: ensureUuidEndsWithDot(claim.nodeUuid) } }); const owner = await prisma.user.findFirst({ where: { id: node.ownerId } }); if (owner.orcid) await orcidApiService.postWorkRecord(node.uuid, owner.orcid); + await saveInteractionWithoutReq(ActionType.UPDATE_ORCID_RECORD, { + ownerId: owner.id, + orcid: owner.orcid, + uuid: node.uuid, + claimId, + }); } }; diff --git a/desci-server/src/services/orcid.ts b/desci-server/src/services/orcid.ts index 6944393c..5a4fb757 100644 --- a/desci-server/src/services/orcid.ts +++ b/desci-server/src/services/orcid.ts @@ -1,5 +1,5 @@ import { ResearchObjectV1, ResearchObjectV1Author } from '@desci-labs/desci-models'; -import { AuthTokenSource, ORCIDRecord, OrcidPutCodes, PutcodeReference } from '@prisma/client'; +import { ActionType, AuthTokenSource, ORCIDRecord, OrcidPutCodes, PutcodeReference } from '@prisma/client'; import { logger as parentLogger, prisma } from '../internal.js'; import { IndexedResearchObject, getIndexedResearchObjects } from '../theGraph.js'; @@ -7,6 +7,7 @@ import { hexToCid } from '../utils.js'; import { attestationService } from './Attestation.js'; import { getManifestByCid } from './data/processing.js'; +import { saveInteractionWithoutReq } from './interactionLog.js'; // const PUTCODE_REGEX = /put-code=.*?(?\d+)/m; @@ -186,6 +187,7 @@ class OrcidApiService { }, 'ORCID API DELETE RECORD', ); + // todo: simulate an error case and handle properly const response = await fetch(url, { method: 'DELETE', headers: { @@ -196,24 +198,38 @@ class OrcidApiService { }, }); - await prisma.orcidPutCodes.delete({ - where: { - id: putCode.id, - }, - }); - - logger.info( - { - status: response.status, - statusText: response.statusText, + if (response.ok) { + await saveInteractionWithoutReq(ActionType.REMOVE_ORCID_WORK_RECORD, { orcid, - putCode: { - code: putCode.putcode, - reference: putCode.reference, + }); + + await prisma.orcidPutCodes.delete({ + where: { + id: putCode.id, }, - }, - 'ORCID RECORD DELETED', - ); + }); + + logger.info( + { + status: response.status, + statusText: response.statusText, + orcid, + putCode: { + code: putCode.putcode, + reference: putCode.reference, + }, + }, + 'ORCID RECORD DELETED', + ); + } else { + await saveInteractionWithoutReq(ActionType.ORCID_API_ERROR, { + orcid, + putCode, + status: response.status, + error: await response.json(), + }); + logger.error({ orcid, putCode, status: response.status }, 'Error: REMOVE ORCID WORK RECORD'); + } } /** @@ -370,17 +386,35 @@ class OrcidApiService { }, }); } + await saveInteractionWithoutReq(ActionType.UPDATE_ORCID_RECORD, { + userId, + orcid, + uuid, + putCode: returnedCode, + }); + logger.info( { uuid, userId, status: response.status, returnedCode, reference: PutcodeReference.PREPRINT }, '[ORCID_API_SERVICE]:: Node Record UPDATED', ); } else { - logger.info( - { status: response.status, response, body: await response.text() }, - '[ORCID_API_SERVICE]::ORCID NODE API ERROR', - ); + const body = await response.text(); + await saveInteractionWithoutReq(ActionType.ORCID_API_ERROR, { + userId, + orcid, + uuid, + statusCode: response.status, + error: body, + }); + logger.info({ status: response.status, response, body }, '[ORCID_API_SERVICE]::ORCID NODE API ERROR'); } } catch (err) { + await saveInteractionWithoutReq(ActionType.ORCID_API_ERROR, { + userId, + orcid, + uuid, + error: err, + }); logger.info({ err }, '[ORCID_API_SERVICE]::NODE API Error Response'); } } @@ -495,19 +529,39 @@ class OrcidApiService { }, }); } + await saveInteractionWithoutReq(ActionType.UPDATE_ORCID_RECORD, { + userId, + orcid, + uuid, + claimId: claim.id, + putCode: returnedCode, + }); logger.info( { uuid, claimId: claim.id, userId, status: response.status, returnedCode, reference: putCodeReference }, 'ORCID CLAIM RECORD UPDATED', ); } else { - logger.info( - { status: response.status, response, body: await response.text() }, - '[ORCID_API_SERVICE]::ORCID CLAIM API ERROR', - ); + const body = await response.text(); + await saveInteractionWithoutReq(ActionType.ORCID_API_ERROR, { + userId, + orcid, + uuid, + claimId: claim.id, + statusCode: response.status, + error: body, + }); + logger.info({ status: response.status, response, body }, '[ORCID_API_SERVICE]::ORCID CLAIM API ERROR'); } } catch (err) { logger.info({ err }, '[ORCID_API_SERVICE]::CLAIM API Error Response'); + await saveInteractionWithoutReq(ActionType.ORCID_API_ERROR, { + userId, + orcid, + uuid, + claimId: claim.id, + error: err, + }); } } } From 8d4ae6ccf3a02864b3c62ddbf00533db69a946ee Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Wed, 29 May 2024 14:03:47 +0200 Subject: [PATCH 048/278] refactor doi workflow validator api logic, restrict doiAttestations to desci-foundation --- desci-server/src/controllers/doi/check.ts | 11 ++++++++--- desci-server/src/services/Doi.ts | 7 ++++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/desci-server/src/controllers/doi/check.ts b/desci-server/src/controllers/doi/check.ts index a282239d..b616b4aa 100644 --- a/desci-server/src/controllers/doi/check.ts +++ b/desci-server/src/controllers/doi/check.ts @@ -1,12 +1,17 @@ import { Request, Response } from 'express'; -import { BadRequestError, SuccessMessageResponse, SuccessResponse, doiService } from '../../internal.js'; +import { BadRequestError, SuccessMessageResponse, SuccessResponse, doiService, logger } from '../../internal.js'; export const checkMintability = async (req: Request, res: Response) => { const { uuid } = req.params; if (!uuid) throw new BadRequestError(); - await doiService.checkMintability(uuid); - new SuccessMessageResponse().send(res); + try { + await doiService.checkMintability(uuid); + new SuccessResponse(true).send(res); + } catch (err) { + logger.error(err, 'module:: checkMintability'); + new SuccessResponse(false).send(res); + } }; export const getDoi = async (req: Request, res: Response) => { diff --git a/desci-server/src/services/Doi.ts b/desci-server/src/services/Doi.ts index 71dfe7ef..635945be 100644 --- a/desci-server/src/services/Doi.ts +++ b/desci-server/src/services/Doi.ts @@ -12,6 +12,7 @@ import { IndexedResearchObject, getIndexedResearchObjects } from '../theGraph.js import { ensureUuidEndsWithDot, hexToCid } from '../utils.js'; import { attestationService } from './Attestation.js'; +import { communityService } from './Communities.js'; import { getManifestByCid } from './data/processing.js'; export class DoiService { @@ -35,7 +36,11 @@ export class DoiService { researchObject.versions.reverse(); // const nodeVersion = researchObject.versions.length; - const doiAttestations = await attestationService.getProtectedAttestations({ protected: true }); + const doiAttestations = await attestationService.getProtectedAttestations({ + protected: true, + community: { slug: 'desci-foundation' }, + }); + logger.info(doiAttestations, 'DOI Requirements'); let claims = await attestationService.getProtectedNodeClaims(latestManifest.dpid.id); claims = claims.filter((claim) => claim.verifications > 0); const hasDataOrCode = claims.length > 0; From dc9af9c640233cfac60176f03883451356a06746 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Thu, 30 May 2024 12:25:53 +0200 Subject: [PATCH 049/278] refactor and clean ups --- .env.example | 2 + .env.test | 3 +- desci-server/kubernetes/deployment_dev.yaml | 1 + desci-server/kubernetes/deployment_prod.yaml | 1 + .../kubernetes/deployment_staging.yaml | 1 + desci-server/src/controllers/doi/check.ts | 6 +- desci-server/src/controllers/doi/mint.ts | 5 +- desci-server/src/core/doi/error.ts | 2 +- desci-server/src/services/Doi.ts | 71 ++++++++++++------- 9 files changed, 60 insertions(+), 32 deletions(-) diff --git a/.env.example b/.env.example index 13f1c488..5b68ecc6 100755 --- a/.env.example +++ b/.env.example @@ -123,3 +123,5 @@ DPID_URL_OVERRIDE=https://dev-beta.dpid.org MUTE_PUBLISH_WORKER=false # SingleNodeLockServce MAX_LOCK_TIME=3600 # 1 hour + +DOI_PREFIX=https://doi.org/10.555 \ No newline at end of file diff --git a/.env.test b/.env.test index a20e598d..b4b35547 100644 --- a/.env.test +++ b/.env.test @@ -72,4 +72,5 @@ VSCODE_ACCESS_TOKEN= NODES_MEDIA_SERVER_URL=http://host.docker.internal:5454 REPO_SERVICE_SECRET_KEY="m8sIy5BPygBcX3+ZmMVuAA10k6w59BSCZd+Z5+VLYm4=" -REPO_SERVER_URL=http://host.docker.internal:5485 \ No newline at end of file +REPO_SERVER_URL=http://host.docker.internal:5485 +DOI_PREFIX=https://doi.org/10.555 \ No newline at end of file diff --git a/desci-server/kubernetes/deployment_dev.yaml b/desci-server/kubernetes/deployment_dev.yaml index 878233b0..831a978b 100644 --- a/desci-server/kubernetes/deployment_dev.yaml +++ b/desci-server/kubernetes/deployment_dev.yaml @@ -79,6 +79,7 @@ spec: export IPFS_READ_ONLY_GATEWAY_SERVER_URL={{ .Data.IPFS_READ_ONLY_GATEWAY_SERVER_URL }} export ETHEREUM_RPC_URL={{ .Data.ETHEREUM_RPC_URL }} export GOOGLE_CLIENT_ID={{ .Data.GOOGLE_CLIENT_ID }} + export DOI_PREFIX={{ .Data.DOI_PREFIX }} export DEBUG_TEST=0; echo "appfinish"; {{- end -}} diff --git a/desci-server/kubernetes/deployment_prod.yaml b/desci-server/kubernetes/deployment_prod.yaml index 02c1398a..40783e88 100755 --- a/desci-server/kubernetes/deployment_prod.yaml +++ b/desci-server/kubernetes/deployment_prod.yaml @@ -79,6 +79,7 @@ spec: export IPFS_READ_ONLY_GATEWAY_SERVER_URL={{ .Data.IPFS_READ_ONLY_GATEWAY_SERVER_URL }} export ETHEREUM_RPC_URL={{ .Data.ETHEREUM_RPC_URL }} export GOOGLE_CLIENT_ID={{ .Data.GOOGLE_CLIENT_ID }} + export DOI_PREFIX={{ .Data.DOI_PREFIX }} export IGNORE_LINE=0; export DEBUG_TEST=0; echo "appfinish"; diff --git a/desci-server/kubernetes/deployment_staging.yaml b/desci-server/kubernetes/deployment_staging.yaml index 47fd50c9..1ea7cb38 100644 --- a/desci-server/kubernetes/deployment_staging.yaml +++ b/desci-server/kubernetes/deployment_staging.yaml @@ -91,6 +91,7 @@ spec: export IPFS_READ_ONLY_GATEWAY_SERVER_URL={{ .Data.IPFS_READ_ONLY_GATEWAY_SERVER_URL }} export ETHEREUM_RPC_URL={{ .Data.ETHEREUM_RPC_URL }} export GOOGLE_CLIENT_ID={{ .Data.GOOGLE_CLIENT_ID }} + export DOI_PREFIX={{ .Data.DOI_PREFIX }} export DEBUG_TEST=0; echo "appfinish"; {{- end -}} diff --git a/desci-server/src/controllers/doi/check.ts b/desci-server/src/controllers/doi/check.ts index b616b4aa..e644ca8f 100644 --- a/desci-server/src/controllers/doi/check.ts +++ b/desci-server/src/controllers/doi/check.ts @@ -1,6 +1,7 @@ import { Request, Response } from 'express'; -import { BadRequestError, SuccessMessageResponse, SuccessResponse, doiService, logger } from '../../internal.js'; +import { DoiError } from '../../core/doi/error.js'; +import { BadRequestError, SuccessResponse, doiService, logger } from '../../internal.js'; export const checkMintability = async (req: Request, res: Response) => { const { uuid } = req.params; @@ -10,6 +11,9 @@ export const checkMintability = async (req: Request, res: Response) => { new SuccessResponse(true).send(res); } catch (err) { logger.error(err, 'module:: checkMintability'); + if (!(err instanceof DoiError)) { + // TODO: Sentry error reporting + } new SuccessResponse(false).send(res); } }; diff --git a/desci-server/src/controllers/doi/mint.ts b/desci-server/src/controllers/doi/mint.ts index 492c309e..9852d495 100644 --- a/desci-server/src/controllers/doi/mint.ts +++ b/desci-server/src/controllers/doi/mint.ts @@ -1,10 +1,11 @@ import { Request, Response, NextFunction } from 'express'; -import { BadRequestError, SuccessResponse, doiService } from '../../internal.js'; +import { BadRequestError, SuccessResponse, doiService, ensureUuidEndsWithDot } from '../../internal.js'; export const mintDoi = async (req: Request, res: Response, next: NextFunction) => { const { uuid } = req.params; if (!uuid) throw new BadRequestError(); - const doi = await doiService.mintDoi(uuid); + const sanitizedUuid = ensureUuidEndsWithDot(uuid); + const doi = await doiService.mintDoi(sanitizedUuid); new SuccessResponse(doi).send(res); }; diff --git a/desci-server/src/core/doi/error.ts b/desci-server/src/core/doi/error.ts index 1b2ad6f4..613079f2 100644 --- a/desci-server/src/core/doi/error.ts +++ b/desci-server/src/core/doi/error.ts @@ -29,7 +29,7 @@ export class NoManuscriptError extends DoiError { } export class AttestationsError extends DoiError { - constructor(message = 'All required attestations are not claimed or verified!') { + constructor(message = 'All required attestations are not claimed or verified') { super(DoiErrorType.INCOMPLETE_ATTESTATIONS, message); } } diff --git a/desci-server/src/services/Doi.ts b/desci-server/src/services/Doi.ts index 635945be..4af485fb 100644 --- a/desci-server/src/services/Doi.ts +++ b/desci-server/src/services/Doi.ts @@ -2,6 +2,7 @@ import { PdfComponent, ResearchObjectComponentDocumentSubtype, ResearchObjectComponentType, + ResearchObjectV1, } from '@desci-labs/desci-models'; import { PrismaClient } from '@prisma/client'; import { v4 } from 'uuid'; @@ -12,9 +13,11 @@ import { IndexedResearchObject, getIndexedResearchObjects } from '../theGraph.js import { ensureUuidEndsWithDot, hexToCid } from '../utils.js'; import { attestationService } from './Attestation.js'; -import { communityService } from './Communities.js'; import { getManifestByCid } from './data/processing.js'; +const DOI_PREFIX = process.env.DOI_PREFIX; + +if (!DOI_PREFIX) throw new Error('env DOI_PREFIX is missing!'); export class DoiService { dbClient: PrismaClient; @@ -22,51 +25,65 @@ export class DoiService { this.dbClient = prismaClient; } - async checkMintability(nodeUuid: string) { - const uuid = ensureUuidEndsWithDot(nodeUuid); - // check if node has claimed doi already + async assertIsFirstDoi(uuid: string) { const exists = await this.dbClient.doiRecord.findUnique({ where: { uuid } }); if (exists) throw new DuplicateMintError(); + } - // retrieve node manifest/metadata - const { researchObjects } = await getIndexedResearchObjects([uuid]); - const researchObject = researchObjects[0] as IndexedResearchObject; - const manifestCid = hexToCid(researchObject.recentCid); - const latestManifest = await getManifestByCid(manifestCid); - researchObject.versions.reverse(); - // const nodeVersion = researchObject.versions.length; - + async assertHasValidatedAttestations(manifest: ResearchObjectV1) { const doiAttestations = await attestationService.getProtectedAttestations({ protected: true, community: { slug: 'desci-foundation' }, }); logger.info(doiAttestations, 'DOI Requirements'); - let claims = await attestationService.getProtectedNodeClaims(latestManifest.dpid.id); + let claims = await attestationService.getProtectedNodeClaims(manifest.dpid.id); claims = claims.filter((claim) => claim.verifications > 0); - const hasDataOrCode = claims.length > 0; - // check if manuscript is included + const hasClaimedRequiredAttestations = doiAttestations.every((attestation) => + claims.find((claim) => claim.attestationId === attestation.id), + ); + if (!hasClaimedRequiredAttestations) throw new AttestationsError(); + } + + assertHasValidManuscript(manifest: ResearchObjectV1) { const manuscript = - latestManifest && - latestManifest.components.find( + manifest && + manifest.components.find( (component) => component.type === ResearchObjectComponentType.PDF && (component as PdfComponent).subtype === ResearchObjectComponentDocumentSubtype.MANUSCRIPT, ); - if (!manuscript && !hasDataOrCode) { + if (!manuscript) { throw new NoManuscriptError(); } + } - // validate title, abstract and contributors - const hasTitle = latestManifest.title.trim().length > 0; - const hasAbstract = latestManifest.description.trim().length > 0; - const hasContributors = latestManifest.authors.length > 0; + assertValidManifest(manifest: ResearchObjectV1) { + const hasTitle = manifest.title.trim().length > 0; + const hasAbstract = manifest.description.trim().length > 0; + const hasContributors = manifest.authors.length > 0; if (!hasTitle || !hasAbstract || !hasContributors) throw new BadManifestError(); + } - const hasClaimedRequiredAttestations = doiAttestations.every((attestation) => - claims.find((claim) => claim.attestationId === attestation.id), - ); - if (!hasClaimedRequiredAttestations) throw new AttestationsError(); + async checkMintability(nodeUuid: string) { + const uuid = ensureUuidEndsWithDot(nodeUuid); + // check if node has claimed doi already + await this.assertIsFirstDoi(uuid); + + // retrieve node manifest/metadata + const { researchObjects } = await getIndexedResearchObjects([uuid]); + const researchObject = researchObjects[0] as IndexedResearchObject; + const manifestCid = hexToCid(researchObject.recentCid); + const latestManifest = await getManifestByCid(manifestCid); + researchObject.versions.reverse(); + + // check if manuscript is included + this.assertHasValidManuscript(latestManifest); + + // validate title, abstract and contributors + this.assertValidManifest(latestManifest); + + await this.assertHasValidatedAttestations(latestManifest); return { dpid: latestManifest.dpid.id, uuid }; } @@ -76,7 +93,7 @@ export class DoiService { // todo: handle over logic to cross-ref api service for minting DOIs // mint new doi const doiSuffix = v4().substring(0, 8); - const doi = `https://doi.org/10.555/${doiSuffix}`; + const doi = `${DOI_PREFIX}/${doiSuffix}`; logger.info({ doiSuffix, doi, uuid }, 'MINT DOI'); return await this.dbClient.doiRecord.create({ data: { From 8ea85d4975bc013e2a7407e5d662500a11dcf654 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Fri, 31 May 2024 04:40:02 -0700 Subject: [PATCH 050/278] Revert "DOI Workflow (Verify and Mint) Initial implementation" --- .env.example | 2 - .env.test | 3 +- desci-server/kubernetes/deployment_dev.yaml | 1 - desci-server/kubernetes/deployment_prod.yaml | 1 - .../kubernetes/deployment_staging.yaml | 1 - desci-server/package.json | 1 - .../migration.sql | 23 ---- desci-server/prisma/schema.prisma | 11 -- .../src/controllers/attestations/claims.ts | 3 - desci-server/src/controllers/doi/check.ts | 27 ----- desci-server/src/controllers/doi/index.ts | 2 - desci-server/src/controllers/doi/mint.ts | 11 -- desci-server/src/core/ApiError.ts | 11 -- desci-server/src/core/ApiResponse.ts | 10 +- desci-server/src/core/doi/error.ts | 41 ------- desci-server/src/internal.ts | 2 - desci-server/src/middleware/authorisation.ts | 1 - desci-server/src/routes/v1/doi.ts | 11 -- desci-server/src/routes/v1/index.ts | 2 - desci-server/src/services/Attestation.ts | 5 - desci-server/src/services/Doi.ts | 112 ------------------ desci-server/src/services/index.ts | 5 - desci-server/yarn.lock | 5 - 23 files changed, 6 insertions(+), 285 deletions(-) delete mode 100644 desci-server/prisma/migrations/20240517110638_add_doi_records_table/migration.sql delete mode 100644 desci-server/src/controllers/doi/check.ts delete mode 100644 desci-server/src/controllers/doi/index.ts delete mode 100644 desci-server/src/controllers/doi/mint.ts delete mode 100644 desci-server/src/core/doi/error.ts delete mode 100644 desci-server/src/routes/v1/doi.ts delete mode 100644 desci-server/src/services/Doi.ts delete mode 100644 desci-server/src/services/index.ts diff --git a/.env.example b/.env.example index 5b68ecc6..13f1c488 100755 --- a/.env.example +++ b/.env.example @@ -123,5 +123,3 @@ DPID_URL_OVERRIDE=https://dev-beta.dpid.org MUTE_PUBLISH_WORKER=false # SingleNodeLockServce MAX_LOCK_TIME=3600 # 1 hour - -DOI_PREFIX=https://doi.org/10.555 \ No newline at end of file diff --git a/.env.test b/.env.test index b4b35547..a20e598d 100644 --- a/.env.test +++ b/.env.test @@ -72,5 +72,4 @@ VSCODE_ACCESS_TOKEN= NODES_MEDIA_SERVER_URL=http://host.docker.internal:5454 REPO_SERVICE_SECRET_KEY="m8sIy5BPygBcX3+ZmMVuAA10k6w59BSCZd+Z5+VLYm4=" -REPO_SERVER_URL=http://host.docker.internal:5485 -DOI_PREFIX=https://doi.org/10.555 \ No newline at end of file +REPO_SERVER_URL=http://host.docker.internal:5485 \ No newline at end of file diff --git a/desci-server/kubernetes/deployment_dev.yaml b/desci-server/kubernetes/deployment_dev.yaml index 831a978b..878233b0 100644 --- a/desci-server/kubernetes/deployment_dev.yaml +++ b/desci-server/kubernetes/deployment_dev.yaml @@ -79,7 +79,6 @@ spec: export IPFS_READ_ONLY_GATEWAY_SERVER_URL={{ .Data.IPFS_READ_ONLY_GATEWAY_SERVER_URL }} export ETHEREUM_RPC_URL={{ .Data.ETHEREUM_RPC_URL }} export GOOGLE_CLIENT_ID={{ .Data.GOOGLE_CLIENT_ID }} - export DOI_PREFIX={{ .Data.DOI_PREFIX }} export DEBUG_TEST=0; echo "appfinish"; {{- end -}} diff --git a/desci-server/kubernetes/deployment_prod.yaml b/desci-server/kubernetes/deployment_prod.yaml index 40783e88..02c1398a 100755 --- a/desci-server/kubernetes/deployment_prod.yaml +++ b/desci-server/kubernetes/deployment_prod.yaml @@ -79,7 +79,6 @@ spec: export IPFS_READ_ONLY_GATEWAY_SERVER_URL={{ .Data.IPFS_READ_ONLY_GATEWAY_SERVER_URL }} export ETHEREUM_RPC_URL={{ .Data.ETHEREUM_RPC_URL }} export GOOGLE_CLIENT_ID={{ .Data.GOOGLE_CLIENT_ID }} - export DOI_PREFIX={{ .Data.DOI_PREFIX }} export IGNORE_LINE=0; export DEBUG_TEST=0; echo "appfinish"; diff --git a/desci-server/kubernetes/deployment_staging.yaml b/desci-server/kubernetes/deployment_staging.yaml index 1ea7cb38..47fd50c9 100644 --- a/desci-server/kubernetes/deployment_staging.yaml +++ b/desci-server/kubernetes/deployment_staging.yaml @@ -91,7 +91,6 @@ spec: export IPFS_READ_ONLY_GATEWAY_SERVER_URL={{ .Data.IPFS_READ_ONLY_GATEWAY_SERVER_URL }} export ETHEREUM_RPC_URL={{ .Data.ETHEREUM_RPC_URL }} export GOOGLE_CLIENT_ID={{ .Data.GOOGLE_CLIENT_ID }} - export DOI_PREFIX={{ .Data.DOI_PREFIX }} export DEBUG_TEST=0; echo "appfinish"; {{- end -}} diff --git a/desci-server/package.json b/desci-server/package.json index a3a40562..86eb086b 100755 --- a/desci-server/package.json +++ b/desci-server/package.json @@ -130,7 +130,6 @@ "@types/multer-s3": "^3.0.1", "@types/node": "^20.10.4", "@types/supertest": "^2.0.12", - "@types/uuid": "^9.0.8", "@types/ws": "^8.5.10", "@types/xmldom": "^0.1.34", "@typescript-eslint/eslint-plugin": "^6.14.0", diff --git a/desci-server/prisma/migrations/20240517110638_add_doi_records_table/migration.sql b/desci-server/prisma/migrations/20240517110638_add_doi_records_table/migration.sql deleted file mode 100644 index 24fc6352..00000000 --- a/desci-server/prisma/migrations/20240517110638_add_doi_records_table/migration.sql +++ /dev/null @@ -1,23 +0,0 @@ --- CreateTable -CREATE TABLE "DoiRecord" ( - "id" SERIAL NOT NULL, - "doi" TEXT NOT NULL, - "dpid" TEXT NOT NULL, - "uuid" TEXT NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "DoiRecord_pkey" PRIMARY KEY ("id") -); - --- CreateIndex -CREATE UNIQUE INDEX "DoiRecord_doi_key" ON "DoiRecord"("doi"); - --- CreateIndex -CREATE UNIQUE INDEX "DoiRecord_dpid_key" ON "DoiRecord"("dpid"); - --- CreateIndex -CREATE UNIQUE INDEX "DoiRecord_uuid_key" ON "DoiRecord"("uuid"); - --- AddForeignKey -ALTER TABLE "DoiRecord" ADD CONSTRAINT "DoiRecord_uuid_fkey" FOREIGN KEY ("uuid") REFERENCES "Node"("uuid") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/desci-server/prisma/schema.prisma b/desci-server/prisma/schema.prisma index 6fc4830c..790372d9 100755 --- a/desci-server/prisma/schema.prisma +++ b/desci-server/prisma/schema.prisma @@ -43,7 +43,6 @@ model Node { NodeContribution NodeContribution[] PrivateShare PrivateShare[] OrcidPutCodes OrcidPutCodes[] - DoiRecord DoiRecord[] @@index([ownerId]) @@index([uuid]) @@ -807,16 +806,6 @@ model OrcidPutCodes { @@unique([orcid, uuid, reference]) } -model DoiRecord { - id Int @id @default(autoincrement()) - doi String @unique - dpid String @unique - uuid String @unique - node Node @relation(fields: [uuid], references: [uuid]) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt -} - enum ORCIDRecord { WORK QUALIFICATION diff --git a/desci-server/src/controllers/attestations/claims.ts b/desci-server/src/controllers/attestations/claims.ts index 6998f81d..d499fc35 100644 --- a/desci-server/src/controllers/attestations/claims.ts +++ b/desci-server/src/controllers/attestations/claims.ts @@ -5,9 +5,6 @@ import _ from 'lodash'; import { AuthFailureError, - ForbiddenError, - ForbiddenResponse, - InternalError, NotFoundError, SuccessMessageResponse, SuccessResponse, diff --git a/desci-server/src/controllers/doi/check.ts b/desci-server/src/controllers/doi/check.ts deleted file mode 100644 index e644ca8f..00000000 --- a/desci-server/src/controllers/doi/check.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Request, Response } from 'express'; - -import { DoiError } from '../../core/doi/error.js'; -import { BadRequestError, SuccessResponse, doiService, logger } from '../../internal.js'; - -export const checkMintability = async (req: Request, res: Response) => { - const { uuid } = req.params; - if (!uuid) throw new BadRequestError(); - try { - await doiService.checkMintability(uuid); - new SuccessResponse(true).send(res); - } catch (err) { - logger.error(err, 'module:: checkMintability'); - if (!(err instanceof DoiError)) { - // TODO: Sentry error reporting - } - new SuccessResponse(false).send(res); - } -}; - -export const getDoi = async (req: Request, res: Response) => { - const { identifier } = req.params; - if (!identifier) throw new BadRequestError(); - - const doi = await doiService.getDoiByDpidOrUuid(identifier); - new SuccessResponse(doi).send(res); -}; diff --git a/desci-server/src/controllers/doi/index.ts b/desci-server/src/controllers/doi/index.ts deleted file mode 100644 index 3313418d..00000000 --- a/desci-server/src/controllers/doi/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './check.js'; -export * from './mint.js'; diff --git a/desci-server/src/controllers/doi/mint.ts b/desci-server/src/controllers/doi/mint.ts deleted file mode 100644 index 9852d495..00000000 --- a/desci-server/src/controllers/doi/mint.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Request, Response, NextFunction } from 'express'; - -import { BadRequestError, SuccessResponse, doiService, ensureUuidEndsWithDot } from '../../internal.js'; - -export const mintDoi = async (req: Request, res: Response, next: NextFunction) => { - const { uuid } = req.params; - if (!uuid) throw new BadRequestError(); - const sanitizedUuid = ensureUuidEndsWithDot(uuid); - const doi = await doiService.mintDoi(sanitizedUuid); - new SuccessResponse(doi).send(res); -}; diff --git a/desci-server/src/core/ApiError.ts b/desci-server/src/core/ApiError.ts index ded98099..b66ddca1 100644 --- a/desci-server/src/core/ApiError.ts +++ b/desci-server/src/core/ApiError.ts @@ -9,7 +9,6 @@ import { InternalErrorResponse, NotFoundResponse, } from './ApiResponse.js'; -import { DoiError, DoiErrorType } from './doi/error.js'; export enum ApiErrorType { BAD_REQUEST = 'BadRequestError', @@ -61,16 +60,6 @@ export abstract class ApiError extends Error { default: return new InternalErrorResponse(err.message).send(res); } - } else if (err instanceof DoiError) { - switch (err.type) { - case DoiErrorType.BAD_METADATA: - case DoiErrorType.NO_MANUSCRIPT: - case DoiErrorType.INCOMPLETE_ATTESTATIONS: - case DoiErrorType.DUPLICATE_MINT: - return new BadRequestResponse(err.message, err).send(res); - default: - return new InternalErrorResponse(err.message).send(res); - } } return new InternalErrorResponse(err.message).send(res); } diff --git a/desci-server/src/core/ApiResponse.ts b/desci-server/src/core/ApiResponse.ts index 20b5fccf..188c3b3c 100644 --- a/desci-server/src/core/ApiResponse.ts +++ b/desci-server/src/core/ApiResponse.ts @@ -18,7 +18,7 @@ export interface ToApiResponse { export abstract class ApiResponse { constructor( private status: ResponseStatus, - private message: string, + message: string, ) {} protected prepare(res: Response, response: T, headers: { [key: string]: string }): Response { @@ -40,17 +40,17 @@ export abstract class ApiResponse { } export class SuccessMessageResponse extends ApiResponse { - constructor(_message = '') { - super(ResponseStatus.SUCCESS, undefined); + constructor(message = 'Success') { + super(ResponseStatus.SUCCESS, message); } } export class SuccessResponse extends ApiResponse { constructor( private data: T, - _message = '', + message = 'Success', ) { - super(ResponseStatus.SUCCESS, undefined); + super(ResponseStatus.SUCCESS, message); } send(res: Response, headers?: Headers): Response { diff --git a/desci-server/src/core/doi/error.ts b/desci-server/src/core/doi/error.ts deleted file mode 100644 index 613079f2..00000000 --- a/desci-server/src/core/doi/error.ts +++ /dev/null @@ -1,41 +0,0 @@ -export enum DoiErrorType { - DUPLICATE_MINT = 'DuplicateDoiError', - NO_MANUSCRIPT = 'NoManuscriptError', - BAD_METADATA = 'InvalidManifestError', - INCOMPLETE_ATTESTATIONS = 'ForbiddenError', -} - -export class DoiError extends Error { - name = 'DoiValidationError'; - - constructor( - public type: DoiErrorType, - public message: string = 'Doi Error', - ) { - super(type); - } -} - -export class BadManifestError extends DoiError { - constructor(message = 'Title, Abstract or Contributors is missing') { - super(DoiErrorType.BAD_METADATA, message); - } -} - -export class NoManuscriptError extends DoiError { - constructor(message = 'Node has no manuscript') { - super(DoiErrorType.NO_MANUSCRIPT, message); - } -} - -export class AttestationsError extends DoiError { - constructor(message = 'All required attestations are not claimed or verified') { - super(DoiErrorType.INCOMPLETE_ATTESTATIONS, message); - } -} - -export class DuplicateMintError extends DoiError { - constructor(message = 'DOI already minted for node') { - super(DoiErrorType.DUPLICATE_MINT, message); - } -} diff --git a/desci-server/src/internal.ts b/desci-server/src/internal.ts index dbd9d7e7..d6d252c6 100644 --- a/desci-server/src/internal.ts +++ b/desci-server/src/internal.ts @@ -5,13 +5,11 @@ export * from './core/ApiError.js'; export * from './core/ApiResponse.js'; export * from './middleware/index.js'; export * from './services/Communities.js'; -export * from './services/index.js'; export * from './services/Attestation.js'; export * from './utils/asyncHandler.js'; export * from './routes/v1/attestations/schema.js'; export * from './controllers/communities/index.js'; export * from './controllers/attestations/index.js'; -export * from './controllers/doi/index.js'; export * from './core/ApiResponse.js'; export * from './utils/manifest.js'; export * from './services/repoService.js'; diff --git a/desci-server/src/middleware/authorisation.ts b/desci-server/src/middleware/authorisation.ts index 6913991c..a996295f 100644 --- a/desci-server/src/middleware/authorisation.ts +++ b/desci-server/src/middleware/authorisation.ts @@ -73,7 +73,6 @@ export const ensureNodeAccess = async (req: RequestWithUser, res: Response, next where: { uuid: ensureUuidEndsWithDot(uuid), ownerId: user.id }, }); - logger.info({ uuid, node }, 'NodeAccess'); if (!node) { res.status(400).send({ ok: false, message: `Node: ${uuid} not found` }); return; diff --git a/desci-server/src/routes/v1/doi.ts b/desci-server/src/routes/v1/doi.ts deleted file mode 100644 index d80a6e49..00000000 --- a/desci-server/src/routes/v1/doi.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Router } from 'express'; - -import { asyncHander, checkMintability, ensureNodeAccess, ensureUser, getDoi, mintDoi } from '../../internal.js'; - -const router = Router(); - -router.post('/check/:uuid', [ensureUser, ensureNodeAccess], asyncHander(checkMintability)); -router.post('/mint/:uuid', [ensureUser, ensureNodeAccess], asyncHander(mintDoi)); -router.get('/:identifier', [ensureUser], asyncHander(getDoi)); - -export default router; diff --git a/desci-server/src/routes/v1/index.ts b/desci-server/src/routes/v1/index.ts index 2d9d20d9..e523b6e7 100755 --- a/desci-server/src/routes/v1/index.ts +++ b/desci-server/src/routes/v1/index.ts @@ -14,7 +14,6 @@ import attestations from './attestations/index.js'; import auth from './auth.js'; import communities from './communities/index.js'; import data from './data.js'; -import doi from './doi.js'; import log from './log.js'; import nodes from './nodes.js'; import pub from './pub.js'; @@ -55,7 +54,6 @@ router.use('/log', log); router.use('/services', services); router.use('/communities', communities); router.use('/attestations', attestations); -router.use('/doi', doi); router.get('/nft/:id', nft); router.use('/referral', referral); diff --git a/desci-server/src/services/Attestation.ts b/desci-server/src/services/Attestation.ts index fb6a8b0c..b416511c 100644 --- a/desci-server/src/services/Attestation.ts +++ b/desci-server/src/services/Attestation.ts @@ -266,7 +266,6 @@ export class AttestationService { image_url: claim.attestationVersion.image_url, verifications: claim._count.NodeAttestationVerification, community: claim.community.name, - attestationId: claim.attestationId, nodeVersion: claim.nodeVersion, })) .value(); @@ -274,10 +273,6 @@ export class AttestationService { return protectedClaims; } - async getDoiMintingPrerequisites() { - // todo() - } - async getNodeCommunityAttestations(dpid: string, communityId: number) { return prisma.nodeAttestation.findMany({ where: { nodeDpid10: dpid, desciCommunityId: communityId, revoked: false }, diff --git a/desci-server/src/services/Doi.ts b/desci-server/src/services/Doi.ts deleted file mode 100644 index 4af485fb..00000000 --- a/desci-server/src/services/Doi.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { - PdfComponent, - ResearchObjectComponentDocumentSubtype, - ResearchObjectComponentType, - ResearchObjectV1, -} from '@desci-labs/desci-models'; -import { PrismaClient } from '@prisma/client'; -import { v4 } from 'uuid'; - -import { DuplicateMintError, NoManuscriptError, BadManifestError, AttestationsError } from '../core/doi/error.js'; -import { logger } from '../logger.js'; -import { IndexedResearchObject, getIndexedResearchObjects } from '../theGraph.js'; -import { ensureUuidEndsWithDot, hexToCid } from '../utils.js'; - -import { attestationService } from './Attestation.js'; -import { getManifestByCid } from './data/processing.js'; - -const DOI_PREFIX = process.env.DOI_PREFIX; - -if (!DOI_PREFIX) throw new Error('env DOI_PREFIX is missing!'); -export class DoiService { - dbClient: PrismaClient; - - constructor(prismaClient: PrismaClient) { - this.dbClient = prismaClient; - } - - async assertIsFirstDoi(uuid: string) { - const exists = await this.dbClient.doiRecord.findUnique({ where: { uuid } }); - if (exists) throw new DuplicateMintError(); - } - - async assertHasValidatedAttestations(manifest: ResearchObjectV1) { - const doiAttestations = await attestationService.getProtectedAttestations({ - protected: true, - community: { slug: 'desci-foundation' }, - }); - logger.info(doiAttestations, 'DOI Requirements'); - let claims = await attestationService.getProtectedNodeClaims(manifest.dpid.id); - claims = claims.filter((claim) => claim.verifications > 0); - - const hasClaimedRequiredAttestations = doiAttestations.every((attestation) => - claims.find((claim) => claim.attestationId === attestation.id), - ); - if (!hasClaimedRequiredAttestations) throw new AttestationsError(); - } - - assertHasValidManuscript(manifest: ResearchObjectV1) { - const manuscript = - manifest && - manifest.components.find( - (component) => - component.type === ResearchObjectComponentType.PDF && - (component as PdfComponent).subtype === ResearchObjectComponentDocumentSubtype.MANUSCRIPT, - ); - if (!manuscript) { - throw new NoManuscriptError(); - } - } - - assertValidManifest(manifest: ResearchObjectV1) { - const hasTitle = manifest.title.trim().length > 0; - const hasAbstract = manifest.description.trim().length > 0; - const hasContributors = manifest.authors.length > 0; - if (!hasTitle || !hasAbstract || !hasContributors) throw new BadManifestError(); - } - - async checkMintability(nodeUuid: string) { - const uuid = ensureUuidEndsWithDot(nodeUuid); - // check if node has claimed doi already - await this.assertIsFirstDoi(uuid); - - // retrieve node manifest/metadata - const { researchObjects } = await getIndexedResearchObjects([uuid]); - const researchObject = researchObjects[0] as IndexedResearchObject; - const manifestCid = hexToCid(researchObject.recentCid); - const latestManifest = await getManifestByCid(manifestCid); - researchObject.versions.reverse(); - - // check if manuscript is included - this.assertHasValidManuscript(latestManifest); - - // validate title, abstract and contributors - this.assertValidManifest(latestManifest); - - await this.assertHasValidatedAttestations(latestManifest); - - return { dpid: latestManifest.dpid.id, uuid }; - } - - async mintDoi(nodeUuid: string) { - const { dpid, uuid } = await this.checkMintability(nodeUuid); - // todo: handle over logic to cross-ref api service for minting DOIs - // mint new doi - const doiSuffix = v4().substring(0, 8); - const doi = `${DOI_PREFIX}/${doiSuffix}`; - logger.info({ doiSuffix, doi, uuid }, 'MINT DOI'); - return await this.dbClient.doiRecord.create({ - data: { - uuid, - dpid, - doi, - }, - }); - } - - async getDoiByDpidOrUuid(identifier: string) { - return this.dbClient.doiRecord.findFirst({ - where: { OR: [{ dpid: identifier }, { uuid: ensureUuidEndsWithDot(identifier) }] }, - }); - } -} diff --git a/desci-server/src/services/index.ts b/desci-server/src/services/index.ts deleted file mode 100644 index c3f27e6b..00000000 --- a/desci-server/src/services/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { prisma } from '../client.js'; - -import { DoiService } from './Doi.js'; - -export const doiService = new DoiService(prisma); diff --git a/desci-server/yarn.lock b/desci-server/yarn.lock index 2fd91603..60f309f2 100644 --- a/desci-server/yarn.lock +++ b/desci-server/yarn.lock @@ -5826,11 +5826,6 @@ dependencies: "@types/node" "*" -"@types/uuid@^9.0.8": - version "9.0.8" - resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.8.tgz#7545ba4fc3c003d6c756f651f3bf163d8f0f29ba" - integrity sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA== - "@types/webpack@5.28.5": version "5.28.5" resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-5.28.5.tgz#0e9d9a15efa09bbda2cef41356ca4ac2031ea9a2" From 901aa15b7cbf60d6ef1e4ebbaec4b61465f125d4 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Fri, 31 May 2024 14:50:58 +0200 Subject: [PATCH 051/278] sort by least engagement signal --- .../src/controllers/communities/feed.ts | 34 ++++++++++++------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/desci-server/src/controllers/communities/feed.ts b/desci-server/src/controllers/communities/feed.ts index 3386f479..0c014209 100644 --- a/desci-server/src/controllers/communities/feed.ts +++ b/desci-server/src/controllers/communities/feed.ts @@ -39,11 +39,13 @@ export const getCommunityFeed = async (req: Request, res: Response, next: NextFu }); let data = await Promise.all(nodes.map(resolveLatestNode)); - data = data.sort((c1, c2) => { - const key1 = c1.engagements.verifications + c1.engagements.annotations + c1.engagements.reactions; - const key2 = c2.engagements.verifications + c2.engagements.annotations + c2.engagements.reactions; - return key2 - key1; - }); + data = data + .sort((c1, c2) => { + const key1 = c1.engagements.verifications + c1.engagements.annotations + c1.engagements.reactions; + const key2 = c2.engagements.verifications + c2.engagements.annotations + c2.engagements.reactions; + return key2 - key1; + }) + .reverse(); return new SuccessResponse(data).send(res); }; @@ -85,15 +87,21 @@ export const getAllFeeds = async (req: Request, res: Response, next: NextFunctio * or * fallback to last submission/attestation claim date */ - data = data.sort((entryA, entryB) => { - const key1 = entryA.engagements.verifications + entryA.engagements.annotations + entryA.engagements.reactions; - const key2 = entryB.engagements.verifications + entryB.engagements.annotations + entryB.engagements.reactions; - if (key1 !== key2) return key2 - key1; + data = data + .sort((entryA, entryB) => { + const key1 = entryA.engagements.verifications + entryA.engagements.annotations + entryA.engagements.reactions; + const key2 = entryB.engagements.verifications + entryB.engagements.annotations + entryB.engagements.reactions; + if (key1 !== key2) return key2 - key1; - const entryALastClaimedAt = new Date(entryA.NodeAttestation[entryA.NodeAttestation.length - 1].claimedAt).getTime(); - const entryBlastClaimedAt = new Date(entryB.NodeAttestation[entryB.NodeAttestation.length - 1].claimedAt).getTime(); - return entryBlastClaimedAt - entryALastClaimedAt; - }); + const entryALastClaimedAt = new Date( + entryA.NodeAttestation[entryA.NodeAttestation.length - 1].claimedAt, + ).getTime(); + const entryBlastClaimedAt = new Date( + entryB.NodeAttestation[entryB.NodeAttestation.length - 1].claimedAt, + ).getTime(); + return entryBlastClaimedAt - entryALastClaimedAt; + }) + .reverse(); return new SuccessResponse(data).send(res); }; From 44dce8ed3baf7b802878b9190b860be7c9e0cdd3 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Fri, 31 May 2024 16:53:13 +0000 Subject: [PATCH 052/278] add preview caching table migration --- .../migration.sql | 22 ++++++++++++++++ desci-server/prisma/schema.prisma | 25 ++++++++++++++----- 2 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 desci-server/prisma/migrations/20240531165246_add_pdf_preview_cache_table/migration.sql diff --git a/desci-server/prisma/migrations/20240531165246_add_pdf_preview_cache_table/migration.sql b/desci-server/prisma/migrations/20240531165246_add_pdf_preview_cache_table/migration.sql new file mode 100644 index 00000000..382a66ac --- /dev/null +++ b/desci-server/prisma/migrations/20240531165246_add_pdf_preview_cache_table/migration.sql @@ -0,0 +1,22 @@ +-- AlterTable +ALTER TABLE "DistributionPdfs" ADD COLUMN "contentPagePreviewCid" TEXT, +ADD COLUMN "frontmatterPagePreviewCid" TEXT; + +-- CreateTable +CREATE TABLE "PdfPreviews" ( + "id" SERIAL NOT NULL, + "nodeUuid" TEXT NOT NULL, + "pdfCid" TEXT NOT NULL, + "previewMap" JSONB NOT NULL, + + CONSTRAINT "PdfPreviews_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "PdfPreviews_pdfCid_key" ON "PdfPreviews"("pdfCid"); + +-- CreateIndex +CREATE UNIQUE INDEX "PdfPreviews_nodeUuid_pdfCid_key" ON "PdfPreviews"("nodeUuid", "pdfCid"); + +-- AddForeignKey +ALTER TABLE "PdfPreviews" ADD CONSTRAINT "PdfPreviews_nodeUuid_fkey" FOREIGN KEY ("nodeUuid") REFERENCES "Node"("uuid") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/desci-server/prisma/schema.prisma b/desci-server/prisma/schema.prisma index eafd4f4b..a20504b4 100755 --- a/desci-server/prisma/schema.prisma +++ b/desci-server/prisma/schema.prisma @@ -44,6 +44,7 @@ model Node { PrivateShare PrivateShare[] OrcidPutCodes OrcidPutCodes[] DistributionPdfs DistributionPdfs[] + PdfPreviews PdfPreviews[] @@index([ownerId]) @@index([uuid]) @@ -478,16 +479,28 @@ model NodeThumbnails { } model DistributionPdfs { - id Int @id @default(autoincrement()) - originalPdfCid String - manifestCid String - nodeUuid String - distPdfCid String - node Node @relation(fields: [nodeUuid], references: [uuid]) + id Int @id @default(autoincrement()) + originalPdfCid String + manifestCid String + nodeUuid String + distPdfCid String + contentPagePreviewCid String? + frontmatterPagePreviewCid String? + node Node @relation(fields: [nodeUuid], references: [uuid]) @@unique([nodeUuid, originalPdfCid, manifestCid]) } +model PdfPreviews { + id Int @id @default(autoincrement()) + nodeUuid String + pdfCid String @unique + previewMap Json + node Node @relation(fields: [nodeUuid], references: [uuid]) + + @@unique([nodeUuid, pdfCid]) +} + // The glue between a manifest contributor entry and a nodes profile model NodeContribution { id Int @id @default(autoincrement()) From 5d040807bf087212762142959c3a75769a892e7a Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Mon, 3 Jun 2024 11:39:05 +0200 Subject: [PATCH 053/278] refactor workflow and add comments --- desci-server/src/services/Doi.ts | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/desci-server/src/services/Doi.ts b/desci-server/src/services/Doi.ts index 4af485fb..183e0ab7 100644 --- a/desci-server/src/services/Doi.ts +++ b/desci-server/src/services/Doi.ts @@ -30,6 +30,12 @@ export class DoiService { if (exists) throw new DuplicateMintError(); } + async isFirstDoi(uuid: string) { + const exists = await this.dbClient.doiRecord.findUnique({ where: { uuid } }); + // if (exists) throw new DuplicateMintError(); + return !exists; + } + async assertHasValidatedAttestations(manifest: ResearchObjectV1) { const doiAttestations = await attestationService.getProtectedAttestations({ protected: true, @@ -65,10 +71,9 @@ export class DoiService { if (!hasTitle || !hasAbstract || !hasContributors) throw new BadManifestError(); } + // check mintability for either root node or manuscript async checkMintability(nodeUuid: string) { const uuid = ensureUuidEndsWithDot(nodeUuid); - // check if node has claimed doi already - await this.assertIsFirstDoi(uuid); // retrieve node manifest/metadata const { researchObjects } = await getIndexedResearchObjects([uuid]); @@ -77,6 +82,24 @@ export class DoiService { const latestManifest = await getManifestByCid(manifestCid); researchObject.versions.reverse(); + // check if node has claimed doi already + // check with dpid instead or dpid/path/to/manuscript or dpid/path/to/file + await this.assertIsFirstDoi(latestManifest.dpid.id || uuid); + + // extract manuscripts + + // check if manuscripts have doi assigned already + // * if none has doi + // * - check if root node has validatedAttestations + // * - if not return silently + // * - return { dpid } + + // manuscript has doi + // check validated attributes + // * if yes + // ** assertValidManifest + // * return { dpid } + // check if manuscript is included this.assertHasValidManuscript(latestManifest); From f635d689cb3f9e0dd81db796f45d8bb6304707be Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Mon, 3 Jun 2024 11:39:55 +0200 Subject: [PATCH 054/278] wip: cross ref api --- desci-server/src/services/CrossRefClient.ts | 111 ++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 desci-server/src/services/CrossRefClient.ts diff --git a/desci-server/src/services/CrossRefClient.ts b/desci-server/src/services/CrossRefClient.ts new file mode 100644 index 00000000..7df4cd0e --- /dev/null +++ b/desci-server/src/services/CrossRefClient.ts @@ -0,0 +1,111 @@ +export type CrossRefHttpResponse = ({ ok: true; content: T } & Response) | { ok: false; content: undefined }; + +export interface Item { + status: string; + 'message-type': string; + 'message-version': string; + message: T; +} + +export interface Items { + status: string; + messageType: string; + messageVersion: string; + message: { + itemsPerPage: number; + query: { + startIndex: number; + searchTerms: string | null; + }; + totalResults: number; + items: T[]; + }; +} + +export interface Work { + author: Author[]; + DOI: string; + prefix: string; + title: string; +} + +export interface Author { + given: string; + family: string; + sequence: string; + affiliation: unknown[]; + ORCID?: string; + authenticatedOrcid?: boolean; +} + +interface SearchQueryParams { + offset: number; + // mailto: string; + query: string; + filter?: string; + rows: number; +} + +export interface QueryWorkParams { + offset: number; + query: string; + queryAuthor?: string; + queryTitle?: string; + rows?: number; + select?: WorkSelectOptions; +} + +enum WorkSelectOptions { + DOI = 'DOI', + PREFIX = 'prefix', + TITLE = 'title', + AUTHOR = 'author', +} + +class CrossRefClient { + baseurl: string; + // private apiToken: string; + // private mailto: string; + + constructor( + baseUrl: string, + private _plusToken?: string, + private _mailto?: string, + ) { + this.baseurl = baseUrl; + // this.apiToken = plusToken; + // this.mailto = mailto; + } + + async listWorks(query: QueryWorkParams = undefined) { + let params: { [k: string]: any } = query; + const url = `${this.baseurl}/works?`; + const config = { + method: 'GET', + mode: 'cors', + headers: {}, + }; + + // add plus token if available + if (this._plusToken) { + config.headers['Crossref-Plus-API-Token'] = `Bearer ${this._plusToken}`; + } + + // polite api + if (this._mailto) { + if (typeof params === 'object') { + params['mailto'] = this._mailto; + } else { + params = { + mailto: this._mailto, + }; + } + } + } + + async performFetch() {} +} + +export default CrossRefClient; + +// const formatKeys From 32400101ba26d4f19d401f39a35d72fe1cbd3ec3 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Mon, 3 Jun 2024 10:46:46 +0000 Subject: [PATCH 055/278] added route and endpoint for returning multiple pdf previews --- .../src/controllers/pdf/preview.ts | 55 +++++++++++++++++++ desci-media-isolated/src/routes/v1/pdf.ts | 2 + 2 files changed, 57 insertions(+) create mode 100644 desci-media-isolated/src/controllers/pdf/preview.ts diff --git a/desci-media-isolated/src/controllers/pdf/preview.ts b/desci-media-isolated/src/controllers/pdf/preview.ts new file mode 100644 index 00000000..1db9c155 --- /dev/null +++ b/desci-media-isolated/src/controllers/pdf/preview.ts @@ -0,0 +1,55 @@ +import type { Request, Response } from 'express'; +import { ThumbnailsService } from '../../services/thumbnails.js'; +import path from 'path'; +import { fileURLToPath } from 'url'; +import fs from 'fs'; +import { TEMP_DIR, THUMBNAIL_OUTPUT_DIR } from '../../config/index.js'; +import { BadRequestError, NotFoundError } from '../../utils/customErrors.js'; + +export type GeneratePreviewRequestBody = { + cid: string; + pages: number[]; +}; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const BASE_TEMP_DIR = path.resolve(__dirname, '../../..', TEMP_DIR); + +export const generatePreview = async ( + req: Request, + res: Response, +) => { + const { cid, pages } = req.body; + const { height = 1000 } = req.query; + + if (!cid) throw new BadRequestError('Missing cid in request body'); + if (!pages) throw new BadRequestError('Missing pages number array in request body'); + + try { + const previewStreams: fs.ReadStream[] = []; + + for (const pageNum of pages) { + const thumbnailPath = await ThumbnailsService.generateThumbnail(cid, `${cid}_${pageNum}.png`, height); + const fullThumbnailPath = path.join(BASE_TEMP_DIR, THUMBNAIL_OUTPUT_DIR, thumbnailPath); + + // Check if the file exists before attempting to stream it + await new Promise((resolve, reject) => { + fs.access(fullThumbnailPath, fs.constants.F_OK, (err) => { + if (err) { + reject(new NotFoundError(`Thumbnail not found for file with cid: ${cid}, page: ${pageNum}`)); + } else { + resolve(); + } + }); + }); + + const readStream = fs.createReadStream(fullThumbnailPath); + previewStreams.push(readStream); + } + + res.setHeader('Content-Type', 'application/json'); + res.status(200).json(previewStreams); + } catch (err: any) { + return res.status(500).json({ message: err.message }); + } +}; diff --git a/desci-media-isolated/src/routes/v1/pdf.ts b/desci-media-isolated/src/routes/v1/pdf.ts index c01e903a..b670ec67 100644 --- a/desci-media-isolated/src/routes/v1/pdf.ts +++ b/desci-media-isolated/src/routes/v1/pdf.ts @@ -1,8 +1,10 @@ import { Router } from 'express'; import { generatePdfCover } from '../../controllers/pdf/createCover.js'; +import { generatePreview } from '../../controllers/pdf/preview.js'; const router = Router(); router.post('/addCover', generatePdfCover); +router.post('/previews', generatePreview); export default router; From abd988859efbc4bb8a36a6063b479faa143fa2ee Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Mon, 3 Jun 2024 10:52:04 +0000 Subject: [PATCH 056/278] service created for generating prepub distro package previews --- desci-server/prisma/schema.prisma | 2 + desci-server/src/services/PublishPackage.ts | 66 +++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/desci-server/prisma/schema.prisma b/desci-server/prisma/schema.prisma index a20504b4..5497f3c8 100755 --- a/desci-server/prisma/schema.prisma +++ b/desci-server/prisma/schema.prisma @@ -478,6 +478,7 @@ model NodeThumbnails { @@unique([nodeUuid, componentCid]) } +// PDFs generated in prepub flow model DistributionPdfs { id Int @id @default(autoincrement()) originalPdfCid String @@ -491,6 +492,7 @@ model DistributionPdfs { @@unique([nodeUuid, originalPdfCid, manifestCid]) } +// Preview images of distribution PDFs created in prepub flow (first and second pages) model PdfPreviews { id Int @id @default(autoincrement()) nodeUuid String diff --git a/desci-server/src/services/PublishPackage.ts b/desci-server/src/services/PublishPackage.ts index a061c6d9..9122dbe4 100644 --- a/desci-server/src/services/PublishPackage.ts +++ b/desci-server/src/services/PublishPackage.ts @@ -4,10 +4,12 @@ import axios from 'axios'; import { prisma } from '../client.js'; import { logger as parentLogger } from '../logger.js'; +import { ensureUuidEndsWithDot } from '../utils.js'; import { attestationService } from './Attestation.js'; import { pinFile } from './ipfs.js'; import { publishServices } from './PublishServices.js'; +import { CidString, HeightPx } from './Thumbnails.js'; export type PrepareDistributionPdfParams = { pdfCid: string; @@ -109,6 +111,62 @@ class PublishPackageService { ); return manuscriptComponent?.payload?.licenseType ?? manifest.defaultLicense; } + + async generatePdfPreview( + pdfCid: CidString, + heightPx: HeightPx, + pageNums: PageNumber[], + nodeUuid: string, + ): Promise { + if (process.env.ISOLATED_MEDIA_SERVER_URL === undefined) { + this.logger.error('process.env.ISOLATED_MEDIA_SERVER_URL is not defined'); + return null; + } + + // Generate the preview + const previewResponse = await axios.post( + `${process.env.ISOLATED_MEDIA_SERVER_URL}/v1/pdf/preview?height=${heightPx}`, + { pdfCid: pdfCid, pageNums }, + { + responseType: 'json', + }, + ); + + const previewStreams = previewResponse.data; + + const previews: { pageNumber: number; cid: string }[] = []; + const previewMap: PreviewMap = {}; + + for (let i = 0; i < previewStreams.length; i++) { + const pageNumber = pageNums[i]; + const previewStream = previewStreams[i]; + + // Save it on IPFS + const pinned = await pinFile(previewStream); + + previews.push({ pageNumber, cid: pinned.cid }); + previewMap[pageNumber] = pinned.cid; + } + + // Save it to the database + const existingPreviews = await prisma.pdfPreviews.findFirst({ + where: { pdfCid, nodeUuid }, + }); + + if (existingPreviews) { + await prisma.pdfPreviews.update({ + where: { id: existingPreviews.id }, + data: { previewMap }, + }); + } else { + await prisma.pdfPreviews.create({ + data: { nodeUuid: ensureUuidEndsWithDot(nodeUuid), pdfCid, previewMap }, + }); + } + + // LATER: Add data ref + return previewMap; + } } export const publishPackageService = new PublishPackageService(); @@ -124,3 +182,11 @@ export type GeneratePdfCoverRequestBody = { license: string; publishDate: string; }; + +export enum PREVIEW_TYPE { + FRONTMATTER = 'frontmatter', + CONTENT = 'content', +} + +export type PageNumber = number; +export type PreviewMap = Record; From f5a4fab0555554f4a0513c9e3b1c7b4ffb6de198 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Mon, 3 Jun 2024 11:01:22 +0000 Subject: [PATCH 057/278] nodes backend controller/route added for distribution pdf previews --- .../controllers/nodes/frontmatterPreview.ts | 71 +++++++++++++++++++ desci-server/src/routes/v1/nodes.ts | 2 + 2 files changed, 73 insertions(+) create mode 100644 desci-server/src/controllers/nodes/frontmatterPreview.ts diff --git a/desci-server/src/controllers/nodes/frontmatterPreview.ts b/desci-server/src/controllers/nodes/frontmatterPreview.ts new file mode 100644 index 00000000..c93ed3fe --- /dev/null +++ b/desci-server/src/controllers/nodes/frontmatterPreview.ts @@ -0,0 +1,71 @@ +import type { Request, Response } from 'express'; + +import { prisma } from '../../client.js'; +import { logger as parentLogger } from '../../logger.js'; +import { publishPackageService } from '../../services/PublishPackage.js'; +import { ensureUuidEndsWithDot } from '../../utils.js'; + +type FrontmatterPreviewQueryParams = { + contentPageOnly?: boolean; +}; + +type FrontmatterPreviewReqBodyParams = { + uuid: string; + originalPdfCid: string; +}; + +type FrontmatterPreviewResponse = { + ok: true; + frontmatterPageCid: string; + contentPageCid: string; +}; + +type FrontmatterPreviewErrorResponse = { + ok: false; + error: string; + status?: number; +}; + +/** + * Generates previews for the frontmatter and first content page of a PDF + * @param req.params.contentPageOnly will only generate the first content page preview (Used before frontmatter is generated) + */ +export const frontmatterPreview = async ( + req: Request, + res: Response, +) => { + const user = (req as any).user; + const { uuid, originalPdfCid } = req.body; + const { contentPageOnly } = req.params; + const logger = parentLogger.child({ + module: 'NODES::FrontmatterPreview', + uuid, + contentPageOnly, + userId: user?.id, + }); + logger.trace({ fn: 'Retrieving frontmatter previews' }); + + if (!uuid) return res.status(400).json({ ok: false, error: 'UUID is required.' }); + if (!originalPdfCid) return res.status(400).json({ ok: false, error: 'originalPdfCid is required.' }); + + if (user) { + // Check if user owns node, if requesting previews + const node = await prisma.node.findFirst({ + where: { + ownerId: user.id, + uuid: ensureUuidEndsWithDot(uuid), + }, + }); + + if (!node) return res.status(401).json({ ok: false, error: 'Unauthorized' }); + } + + const previewMap = publishPackageService.generatePdfPreview( + originalPdfCid, + 1000, + [1, 2], + ensureUuidEndsWithDot(uuid), + ); + + return res.status(200).json({ ok: true, frontmatterPageCid: previewMap[1], contentPageCid: previewMap[2] }); +}; diff --git a/desci-server/src/routes/v1/nodes.ts b/desci-server/src/routes/v1/nodes.ts index f1cf7fed..57268d9d 100755 --- a/desci-server/src/routes/v1/nodes.ts +++ b/desci-server/src/routes/v1/nodes.ts @@ -9,6 +9,7 @@ import { updateContributor } from '../../controllers/nodes/contributions/update. import { verifyContribution } from '../../controllers/nodes/contributions/verify.js'; import { dispatchDocumentChange, getNodeDocument } from '../../controllers/nodes/documents.js'; import { feed } from '../../controllers/nodes/feed.js'; +import { frontmatterPreview } from '../../controllers/nodes/frontmatterPreview.js'; import { show, draftUpdate, @@ -79,6 +80,7 @@ router.delete('/contributions/:uuid', [ensureUser, ensureWriteNodeAccess], delet router.get('/contributions/user/:userId', [], getUserContributions); router.get('/contributions/user', [ensureUser], getUserContributionsAuthed); router.post('/distribution', preparePublishPackage); +router.post('/distribution/preview', [ensureUser], frontmatterPreview); router.delete('/:uuid', [ensureUser], deleteNode); From 55afa66399dba2a862992e75cf158381056db67d Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Mon, 3 Jun 2024 13:48:47 +0200 Subject: [PATCH 058/278] Cross ref client integration and testing --- .env.example | 7 +- .vscode/settings.json | 2 +- desci-server/src/services/CrossRefClient.ts | 111 ------------------ desci-server/src/services/Doi.ts | 15 ++- desci-server/src/services/crossRef/client.ts | 107 +++++++++++++++++ .../src/services/crossRef/definitions.ts | 63 ++++++++++ desci-server/src/services/crossRef/utils.ts | 21 ++++ desci-server/src/services/index.ts | 6 + desci-server/src/types/ProcessEnv.d.ts | 3 + 9 files changed, 220 insertions(+), 115 deletions(-) delete mode 100644 desci-server/src/services/CrossRefClient.ts create mode 100644 desci-server/src/services/crossRef/client.ts create mode 100644 desci-server/src/services/crossRef/definitions.ts create mode 100644 desci-server/src/services/crossRef/utils.ts diff --git a/.env.example b/.env.example index 5b68ecc6..7f554363 100755 --- a/.env.example +++ b/.env.example @@ -124,4 +124,9 @@ MUTE_PUBLISH_WORKER=false # SingleNodeLockServce MAX_LOCK_TIME=3600 # 1 hour -DOI_PREFIX=https://doi.org/10.555 \ No newline at end of file +DOI_PREFIX=https://doi.org/10.555 + +# Cross ref api +CROSS_REF_API=https://api.crossref.org +CROSS_REF_API_KEY= +CROSS_REF_EMAIL= \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 317272b1..ec6e6899 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,7 @@ { "explorer.compactFolders": false, "files.exclude": { - "**/node_modules/**": true + "**/node_modules/**": false }, "editor.formatOnSave": true, // Tell VSCode to format files on save "editor.defaultFormatter": "esbenp.prettier-vscode", diff --git a/desci-server/src/services/CrossRefClient.ts b/desci-server/src/services/CrossRefClient.ts deleted file mode 100644 index 7df4cd0e..00000000 --- a/desci-server/src/services/CrossRefClient.ts +++ /dev/null @@ -1,111 +0,0 @@ -export type CrossRefHttpResponse = ({ ok: true; content: T } & Response) | { ok: false; content: undefined }; - -export interface Item { - status: string; - 'message-type': string; - 'message-version': string; - message: T; -} - -export interface Items { - status: string; - messageType: string; - messageVersion: string; - message: { - itemsPerPage: number; - query: { - startIndex: number; - searchTerms: string | null; - }; - totalResults: number; - items: T[]; - }; -} - -export interface Work { - author: Author[]; - DOI: string; - prefix: string; - title: string; -} - -export interface Author { - given: string; - family: string; - sequence: string; - affiliation: unknown[]; - ORCID?: string; - authenticatedOrcid?: boolean; -} - -interface SearchQueryParams { - offset: number; - // mailto: string; - query: string; - filter?: string; - rows: number; -} - -export interface QueryWorkParams { - offset: number; - query: string; - queryAuthor?: string; - queryTitle?: string; - rows?: number; - select?: WorkSelectOptions; -} - -enum WorkSelectOptions { - DOI = 'DOI', - PREFIX = 'prefix', - TITLE = 'title', - AUTHOR = 'author', -} - -class CrossRefClient { - baseurl: string; - // private apiToken: string; - // private mailto: string; - - constructor( - baseUrl: string, - private _plusToken?: string, - private _mailto?: string, - ) { - this.baseurl = baseUrl; - // this.apiToken = plusToken; - // this.mailto = mailto; - } - - async listWorks(query: QueryWorkParams = undefined) { - let params: { [k: string]: any } = query; - const url = `${this.baseurl}/works?`; - const config = { - method: 'GET', - mode: 'cors', - headers: {}, - }; - - // add plus token if available - if (this._plusToken) { - config.headers['Crossref-Plus-API-Token'] = `Bearer ${this._plusToken}`; - } - - // polite api - if (this._mailto) { - if (typeof params === 'object') { - params['mailto'] = this._mailto; - } else { - params = { - mailto: this._mailto, - }; - } - } - } - - async performFetch() {} -} - -export default CrossRefClient; - -// const formatKeys diff --git a/desci-server/src/services/Doi.ts b/desci-server/src/services/Doi.ts index 183e0ab7..1b6be482 100644 --- a/desci-server/src/services/Doi.ts +++ b/desci-server/src/services/Doi.ts @@ -13,8 +13,11 @@ import { IndexedResearchObject, getIndexedResearchObjects } from '../theGraph.js import { ensureUuidEndsWithDot, hexToCid } from '../utils.js'; import { attestationService } from './Attestation.js'; +import { WorkSelectOptions } from './crossRef/definitions.js'; import { getManifestByCid } from './data/processing.js'; +import { crossRefClient } from './index.js'; + const DOI_PREFIX = process.env.DOI_PREFIX; if (!DOI_PREFIX) throw new Error('env DOI_PREFIX is missing!'); @@ -41,7 +44,7 @@ export class DoiService { protected: true, community: { slug: 'desci-foundation' }, }); - logger.info(doiAttestations, 'DOI Requirements'); + // logger.info(doiAttestations, 'DOI Requirements'); let claims = await attestationService.getProtectedNodeClaims(manifest.dpid.id); claims = claims.filter((claim) => claim.verifications > 0); @@ -87,8 +90,16 @@ export class DoiService { await this.assertIsFirstDoi(latestManifest.dpid.id || uuid); // extract manuscripts - + const manuscriptTitle = 'Guidelines for Evaluating the Comparability of Down-Sampled GWAS Summary Statistics'; // check if manuscripts have doi assigned already + const works = await crossRefClient.listWorks({ + rows: 1, + select: [WorkSelectOptions.DOI, WorkSelectOptions.TITLE, WorkSelectOptions.AUTHOR], + queryTitle: manuscriptTitle, + }); + const doi = works?.data?.message?.items.find((item) => item.title === manuscriptTitle); + logger.info(works, 'Search Manuscript'); + logger.info(doi, 'Existing DOI'); // * if none has doi // * - check if root node has validatedAttestations // * - if not return silently diff --git a/desci-server/src/services/crossRef/client.ts b/desci-server/src/services/crossRef/client.ts new file mode 100644 index 00000000..2f0b0616 --- /dev/null +++ b/desci-server/src/services/crossRef/client.ts @@ -0,0 +1,107 @@ +import { logger as parentLogger } from '../../logger.js'; + +import { CrossRefHttpResponse, Items, QueryWorkParams, Work } from './definitions.js'; +import { keysToDotsAndDashses } from './utils.js'; + +const logger = parentLogger.child({ module: '[CrossRefClient' }); + +export const delay = async (timeMs: number) => { + return new Promise((resolve) => setTimeout(resolve, timeMs)); +}; + +class CrossRefClient { + baseurl: string; + // private apiToken: string; + // private mailto: string; + + constructor( + baseUrl: string, + private _plusToken?: string, + private _mailto?: string, + ) { + if (!baseUrl) { + logger.error('Pass Cross ref api as argument to CrossRefClient'); + throw Error('Pass Cross ref api as argument to CrossRefClient'); + } + this.baseurl = baseUrl; + } + + async listWorks(query: QueryWorkParams = undefined) { + let params: { [k: string]: any } = query; + let url = `${this.baseurl}/works?`; + const config: RequestInit = { + method: 'GET', + mode: 'cors', + headers: {}, + }; + + // add plus token if available + if (this._plusToken) { + config.headers['Crossref-Plus-API-Token'] = `Bearer ${this._plusToken}`; + } + + // polite api + if (this._mailto) { + if (typeof params === 'object') { + params['mailto'] = this._mailto; + } else { + params = { + mailto: this._mailto, + }; + } + } + + logger.info(params, 'API INFO'); + + if (typeof params === 'object') { + params = keysToDotsAndDashses(params); + logger.info(params, 'parsed params'); + } + + for (const [key, value] of Object.entries(params)) { + switch (typeof value) { + case 'string': + url += `${key}=${value}&`; + break; + case 'number': + url += `${key}=${value}&`; + break; + case 'object': + url += `${key}=${value.join(',')}&`; + break; + default: + break; + } + } + + url = url.slice(0, -1); + url = encodeURI(url); + logger.info(url, 'url params'); + const request = new Request(url, config); + try { + return await this.performFetch>(request); + } catch (error) { + logger.error(error, 'LIST WORKS API ERROR'); + + // retry after 1 second + await delay(1000); + logger.info('Retrying API Request'); + return await this.performFetch>(request); + } + } + + async performFetch(request: Request) { + const response = (await fetch(request)) as CrossRefHttpResponse; + response.data = undefined; + if (response.ok && response.status === 200) { + if (response.headers.get('content-type').includes('application/json')) { + response.data = (await response.json()) as T; + } + } + return response; + } +} + +export default CrossRefClient; + +// const formatKeys diff --git a/desci-server/src/services/crossRef/definitions.ts b/desci-server/src/services/crossRef/definitions.ts new file mode 100644 index 00000000..09f4c35c --- /dev/null +++ b/desci-server/src/services/crossRef/definitions.ts @@ -0,0 +1,63 @@ +export type CrossRefHttpResponse = ({ ok: true; data: T } & Response) | { ok: false; data: undefined }; + +export interface Item { + status: string; + 'message-type': string; + 'message-version': string; + message: T; +} + +export interface Items { + status: string; + messageType: string; + messageVersion: string; + message: { + itemsPerPage: number; + query: { + startIndex: number; + searchTerms: string | null; + }; + totalResults: number; + items: T[]; + }; +} + +export interface Work { + author: Author[]; + DOI: string; + prefix: string; + title: string; +} + +export interface Author { + given: string; + family: string; + sequence: string; + affiliation: unknown[]; + ORCID?: string; + authenticatedOrcid?: boolean; +} + +interface SearchQueryParams { + offset: number; + // mailto: string; + query: string; + filter?: string; + rows: number; +} + +export interface QueryWorkParams { + offset?: number; + query?: string; + queryAuthor?: string; + queryTitle?: string; + rows?: number; + select?: WorkSelectOptions[]; +} + +export enum WorkSelectOptions { + DOI = 'DOI', + PREFIX = 'prefix', + TITLE = 'title', + AUTHOR = 'author', +} diff --git a/desci-server/src/services/crossRef/utils.ts b/desci-server/src/services/crossRef/utils.ts new file mode 100644 index 00000000..97e12018 --- /dev/null +++ b/desci-server/src/services/crossRef/utils.ts @@ -0,0 +1,21 @@ +export function keysToDotsAndDashses(param: any) { + if (isObject(param)) { + const r = {}; + Object.keys(param).forEach((key) => { + r[toDotsAndDashes(key)] = keysToDotsAndDashses(param[key]); + }); + return r; + } else if (Array.isArray(param)) { + return param.map((param) => keysToDotsAndDashses(param)); + } + + return param; +} + +const isObject = (o: any) => Object(o) === o && !Array.isArray(o) && typeof o !== 'function'; + +const toDotsAndDashes = (str: string) => { + str = str.replace(/query[A-Z]/, (match) => `query.${match.slice(-1)}`); + str = str.replace(/[A-Z]/g, (match) => match.toLowerCase()); + return str; +}; diff --git a/desci-server/src/services/index.ts b/desci-server/src/services/index.ts index c3f27e6b..53632886 100644 --- a/desci-server/src/services/index.ts +++ b/desci-server/src/services/index.ts @@ -1,5 +1,11 @@ import { prisma } from '../client.js'; +import CrossRefClient from './crossRef/client.js'; import { DoiService } from './Doi.js'; export const doiService = new DoiService(prisma); +export const crossRefClient = new CrossRefClient( + process.env.CROSS_REF_API, + process.env.CROSS_REF_API_KEY, + process.env.CROSS_REF_EMAIL, +); diff --git a/desci-server/src/types/ProcessEnv.d.ts b/desci-server/src/types/ProcessEnv.d.ts index 1baa0a7f..b42acef7 100755 --- a/desci-server/src/types/ProcessEnv.d.ts +++ b/desci-server/src/types/ProcessEnv.d.ts @@ -10,5 +10,8 @@ declare namespace NodeJS { JWT_SECRET: string; JWT_EXPIRATION: string; MAX_LOCK_TIME: string; + CROSS_REF_API: string; + CROSS_REF_EMAIL: string; + CROSS_REF_API_KEY: string; } } From ff349b0e779c832876a09afb4647b03a01fa869b Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Mon, 3 Jun 2024 15:48:39 +0200 Subject: [PATCH 059/278] Cross ref api, caching of cross ref response, etc --- desci-server/src/redisClient.ts | 1 + desci-server/src/services/Doi.ts | 102 +++++++++---------- desci-server/src/services/crossRef/client.ts | 7 ++ 3 files changed, 59 insertions(+), 51 deletions(-) diff --git a/desci-server/src/redisClient.ts b/desci-server/src/redisClient.ts index 817b45cf..50ff4eda 100644 --- a/desci-server/src/redisClient.ts +++ b/desci-server/src/redisClient.ts @@ -56,6 +56,7 @@ redisClient.on('error', (err) => { export default redisClient; const DEFAULT_TTL = 60 * 60 * 24 * 7; // 1 week +export const ONE_DAY_TTL = 60 * 60 * 24; // 1 week export async function getFromCache(key: string): Promise { let clientAvailable = true; diff --git a/desci-server/src/services/Doi.ts b/desci-server/src/services/Doi.ts index 1b6be482..a4d6e892 100644 --- a/desci-server/src/services/Doi.ts +++ b/desci-server/src/services/Doi.ts @@ -1,16 +1,11 @@ -import { - PdfComponent, - ResearchObjectComponentDocumentSubtype, - ResearchObjectComponentType, - ResearchObjectV1, -} from '@desci-labs/desci-models'; +import { PdfComponent, ResearchObjectComponentType, ResearchObjectV1 } from '@desci-labs/desci-models'; import { PrismaClient } from '@prisma/client'; import { v4 } from 'uuid'; -import { DuplicateMintError, NoManuscriptError, BadManifestError, AttestationsError } from '../core/doi/error.js'; +import { DuplicateMintError, BadManifestError, AttestationsError } from '../core/doi/error.js'; import { logger } from '../logger.js'; import { IndexedResearchObject, getIndexedResearchObjects } from '../theGraph.js'; -import { ensureUuidEndsWithDot, hexToCid } from '../utils.js'; +import { asyncMap, ensureUuidEndsWithDot, hexToCid } from '../utils.js'; import { attestationService } from './Attestation.js'; import { WorkSelectOptions } from './crossRef/definitions.js'; @@ -28,14 +23,13 @@ export class DoiService { this.dbClient = prismaClient; } - async assertIsFirstDoi(uuid: string) { - const exists = await this.dbClient.doiRecord.findUnique({ where: { uuid } }); - if (exists) throw new DuplicateMintError(); + async assertIsFirstDoi(dpid: string) { + const isFirstDoi = await this.isFirstDoi(dpid); // await this.dbClient.doiRecord.findUnique({ where: { doi } }); + if (!isFirstDoi) throw new DuplicateMintError(); } - async isFirstDoi(uuid: string) { - const exists = await this.dbClient.doiRecord.findUnique({ where: { uuid } }); - // if (exists) throw new DuplicateMintError(); + async isFirstDoi(dpid: string) { + const exists = await this.dbClient.doiRecord.findUnique({ where: { dpid } }); return !exists; } @@ -54,17 +48,26 @@ export class DoiService { if (!hasClaimedRequiredAttestations) throw new AttestationsError(); } - assertHasValidManuscript(manifest: ResearchObjectV1) { - const manuscript = - manifest && - manifest.components.find( - (component) => - component.type === ResearchObjectComponentType.PDF && - (component as PdfComponent).subtype === ResearchObjectComponentDocumentSubtype.MANUSCRIPT, - ); - if (!manuscript) { - throw new NoManuscriptError(); - } + async extractManuscriptDoi(manuscripts: PdfComponent[]) { + const manuscriptDois = await asyncMap(manuscripts, async (component) => { + const manuscriptTitle = + component.name.replace(/\.pdf/g, '') || + component.payload.title || + component.payload.path.split('/').pop().replace(/\.pdf/g, ''); + // check if manuscripts have doi assigned already + const works = await crossRefClient.listWorks({ + rows: 5, + select: [WorkSelectOptions.DOI, WorkSelectOptions.TITLE, WorkSelectOptions.AUTHOR], + queryTitle: manuscriptTitle, + }); + const doi = works?.data?.message?.items.find((item) => item.title === manuscriptTitle); + logger.info({ status: works.ok, manuscript: manuscriptTitle, doi }, 'Search Manuscripts'); + + if (!doi) return null; + return { doi, component }; + }); + + return manuscriptDois.filter(Boolean); } assertValidManifest(manifest: ResearchObjectV1) { @@ -87,38 +90,35 @@ export class DoiService { // check if node has claimed doi already // check with dpid instead or dpid/path/to/manuscript or dpid/path/to/file - await this.assertIsFirstDoi(latestManifest.dpid.id || uuid); + await this.assertIsFirstDoi(latestManifest.dpid.id); // extract manuscripts - const manuscriptTitle = 'Guidelines for Evaluating the Comparability of Down-Sampled GWAS Summary Statistics'; - // check if manuscripts have doi assigned already - const works = await crossRefClient.listWorks({ - rows: 1, - select: [WorkSelectOptions.DOI, WorkSelectOptions.TITLE, WorkSelectOptions.AUTHOR], - queryTitle: manuscriptTitle, - }); - const doi = works?.data?.message?.items.find((item) => item.title === manuscriptTitle); - logger.info(works, 'Search Manuscript'); - logger.info(doi, 'Existing DOI'); - // * if none has doi - // * - check if root node has validatedAttestations - // * - if not return silently - // * - return { dpid } - - // manuscript has doi - // check validated attributes - // * if yes - // ** assertValidManifest - // * return { dpid } - - // check if manuscript is included - this.assertHasValidManuscript(latestManifest); + const manuscripts = latestManifest.components.filter( + (component) => + component.type === ResearchObjectComponentType.PDF || + component.name.endsWith('.pdf') || + component.payload?.path?.endsWith('.pdf'), + ) as PdfComponent[]; + logger.info(manuscripts, 'MANUSCRIPTS'); + + if (manuscripts.length > 0) { + const existingDois = await this.extractManuscriptDoi(manuscripts); + + logger.info(existingDois, 'Existing DOI'); + if (existingDois.length) { + throw new DuplicateMintError( + 'Duplicate Manuscript DOI: ' + + existingDois.map((entry) => `${entry.component.name} - DOI: ${entry.doi}`).join(), + ); + } + } + + // Validate node has claimed all necessary attestations + await this.assertHasValidatedAttestations(latestManifest); // validate title, abstract and contributors this.assertValidManifest(latestManifest); - await this.assertHasValidatedAttestations(latestManifest); - return { dpid: latestManifest.dpid.id, uuid }; } diff --git a/desci-server/src/services/crossRef/client.ts b/desci-server/src/services/crossRef/client.ts index 2f0b0616..3b682cee 100644 --- a/desci-server/src/services/crossRef/client.ts +++ b/desci-server/src/services/crossRef/client.ts @@ -1,4 +1,5 @@ import { logger as parentLogger } from '../../logger.js'; +import { ONE_DAY_TTL, getFromCache, setToCache } from '../../redisClient.js'; import { CrossRefHttpResponse, Items, QueryWorkParams, Work } from './definitions.js'; import { keysToDotsAndDashses } from './utils.js'; @@ -91,11 +92,17 @@ class CrossRefClient { } async performFetch(request: Request) { + const responseFromCache = await getFromCache(request.url); + logger.info(responseFromCache, 'DOI From Cache'); + if (responseFromCache) return { ok: true, status: 200, data: responseFromCache }; + const response = (await fetch(request)) as CrossRefHttpResponse; response.data = undefined; if (response.ok && response.status === 200) { if (response.headers.get('content-type').includes('application/json')) { response.data = (await response.json()) as T; + logger.info(response.ok, 'SET TO CACHE'); + await setToCache(request.url, response.data, ONE_DAY_TTL); } } return response; From 410f4864de65d3d3b826fdedc0711700ef7a9d88 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Mon, 3 Jun 2024 18:58:31 +0000 Subject: [PATCH 060/278] debug wip --- .../src/controllers/pdf/preview.ts | 1 + .../src/controllers/nodes/frontmatterPreview.ts | 16 ++++++---------- desci-server/src/services/PublishPackage.ts | 5 +++-- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/desci-media-isolated/src/controllers/pdf/preview.ts b/desci-media-isolated/src/controllers/pdf/preview.ts index 1db9c155..735674f2 100644 --- a/desci-media-isolated/src/controllers/pdf/preview.ts +++ b/desci-media-isolated/src/controllers/pdf/preview.ts @@ -19,6 +19,7 @@ export const generatePreview = async ( req: Request, res: Response, ) => { + debugger; const { cid, pages } = req.body; const { height = 1000 } = req.query; diff --git a/desci-server/src/controllers/nodes/frontmatterPreview.ts b/desci-server/src/controllers/nodes/frontmatterPreview.ts index c93ed3fe..3d021056 100644 --- a/desci-server/src/controllers/nodes/frontmatterPreview.ts +++ b/desci-server/src/controllers/nodes/frontmatterPreview.ts @@ -11,7 +11,7 @@ type FrontmatterPreviewQueryParams = { type FrontmatterPreviewReqBodyParams = { uuid: string; - originalPdfCid: string; + pdfCid: string; }; type FrontmatterPreviewResponse = { @@ -35,7 +35,7 @@ export const frontmatterPreview = async ( res: Response, ) => { const user = (req as any).user; - const { uuid, originalPdfCid } = req.body; + const { uuid, pdfCid } = req.body; const { contentPageOnly } = req.params; const logger = parentLogger.child({ module: 'NODES::FrontmatterPreview', @@ -46,7 +46,7 @@ export const frontmatterPreview = async ( logger.trace({ fn: 'Retrieving frontmatter previews' }); if (!uuid) return res.status(400).json({ ok: false, error: 'UUID is required.' }); - if (!originalPdfCid) return res.status(400).json({ ok: false, error: 'originalPdfCid is required.' }); + if (!pdfCid) return res.status(400).json({ ok: false, error: 'pdfCid is required.' }); if (user) { // Check if user owns node, if requesting previews @@ -60,12 +60,8 @@ export const frontmatterPreview = async ( if (!node) return res.status(401).json({ ok: false, error: 'Unauthorized' }); } - const previewMap = publishPackageService.generatePdfPreview( - originalPdfCid, - 1000, - [1, 2], - ensureUuidEndsWithDot(uuid), - ); - + debugger; + const previewMap = await publishPackageService.generatePdfPreview(pdfCid, 1000, [1, 2], ensureUuidEndsWithDot(uuid)); + // debugger; return res.status(200).json({ ok: true, frontmatterPageCid: previewMap[1], contentPageCid: previewMap[2] }); }; diff --git a/desci-server/src/services/PublishPackage.ts b/desci-server/src/services/PublishPackage.ts index 9122dbe4..9d64a254 100644 --- a/desci-server/src/services/PublishPackage.ts +++ b/desci-server/src/services/PublishPackage.ts @@ -123,10 +123,11 @@ class PublishPackageService { return null; } + debugger; // Generate the preview const previewResponse = await axios.post( - `${process.env.ISOLATED_MEDIA_SERVER_URL}/v1/pdf/preview?height=${heightPx}`, - { pdfCid: pdfCid, pageNums }, + `${process.env.ISOLATED_MEDIA_SERVER_URL}/v1/pdf/previews?height=${heightPx}`, + { cid: pdfCid, pages: pageNums }, { responseType: 'json', }, From 7aa82dc8130517dbd751c66ba40725bd5ce174cf Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Tue, 4 Jun 2024 12:05:15 +0200 Subject: [PATCH 061/278] refactor: DOI check workflow --- desci-server/src/services/Doi.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/desci-server/src/services/Doi.ts b/desci-server/src/services/Doi.ts index a4d6e892..3013e863 100644 --- a/desci-server/src/services/Doi.ts +++ b/desci-server/src/services/Doi.ts @@ -105,17 +105,16 @@ export class DoiService { const existingDois = await this.extractManuscriptDoi(manuscripts); logger.info(existingDois, 'Existing DOI'); + // does manuscript(s) already have a DOI if (existingDois.length) { - throw new DuplicateMintError( - 'Duplicate Manuscript DOI: ' + - existingDois.map((entry) => `${entry.component.name} - DOI: ${entry.doi}`).join(), - ); + // Validate node has claimed all necessary attestations + await this.assertHasValidatedAttestations(latestManifest); } + } else { + // Validate node has claimed all necessary attestations + await this.assertHasValidatedAttestations(latestManifest); } - // Validate node has claimed all necessary attestations - await this.assertHasValidatedAttestations(latestManifest); - // validate title, abstract and contributors this.assertValidManifest(latestManifest); From c4adb9b594db530f4e9c3b27967d90b4b69573ca Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Tue, 4 Jun 2024 12:25:09 +0200 Subject: [PATCH 062/278] add docs to cross ref client --- .vscode/settings.json | 2 +- desci-server/src/services/crossRef/client.ts | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index ec6e6899..317272b1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,7 @@ { "explorer.compactFolders": false, "files.exclude": { - "**/node_modules/**": false + "**/node_modules/**": true }, "editor.formatOnSave": true, // Tell VSCode to format files on save "editor.defaultFormatter": "esbenp.prettier-vscode", diff --git a/desci-server/src/services/crossRef/client.ts b/desci-server/src/services/crossRef/client.ts index 3b682cee..deb362ff 100644 --- a/desci-server/src/services/crossRef/client.ts +++ b/desci-server/src/services/crossRef/client.ts @@ -4,16 +4,19 @@ import { ONE_DAY_TTL, getFromCache, setToCache } from '../../redisClient.js'; import { CrossRefHttpResponse, Items, QueryWorkParams, Work } from './definitions.js'; import { keysToDotsAndDashses } from './utils.js'; -const logger = parentLogger.child({ module: '[CrossRefClient' }); +const logger = parentLogger.child({ module: '[CrossRefClient]' }); export const delay = async (timeMs: number) => { return new Promise((resolve) => setTimeout(resolve, timeMs)); }; +/** + * A wrapper http client for querying, caching and parsing requests + * from the CrossRef Rest Api https://www.crossref.org/documentation/retrieve-metadata/rest-api/ + * Initialize constructor with CrossRef Api url https://api.crossref.org, Api token and a polite Mail + */ class CrossRefClient { baseurl: string; - // private apiToken: string; - // private mailto: string; constructor( baseUrl: string, @@ -27,6 +30,10 @@ class CrossRefClient { this.baseurl = baseUrl; } + /** + * Returns a list of all works (journal articles, + * conference proceedings, books, components, etc), + */ async listWorks(query: QueryWorkParams = undefined) { let params: { [k: string]: any } = query; let url = `${this.baseurl}/works?`; @@ -110,5 +117,3 @@ class CrossRefClient { } export default CrossRefClient; - -// const formatKeys From 8387ea8ebcf5424f8ee03e47103e65a61f4cbb64 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Tue, 4 Jun 2024 12:29:57 +0200 Subject: [PATCH 063/278] clean up --- desci-server/src/services/orcid.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/desci-server/src/services/orcid.ts b/desci-server/src/services/orcid.ts index 363beb5d..529b00d9 100644 --- a/desci-server/src/services/orcid.ts +++ b/desci-server/src/services/orcid.ts @@ -507,7 +507,6 @@ class OrcidApiService { if ([200, 201].includes(response.status)) { const location = response.headers.get('Location')?.split('/'); const returnedCode = location?.[location.length - 1]; - // response.headers.forEach((header, key) => logger.info({ key, header }, 'Response header')); logger.info({ location }, 'RESPONSE HEADER Location'); if (returnedCode) { From 6afc36f4d5807a8611d9751a2a7e0b8bac1022bf Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Tue, 4 Jun 2024 14:33:05 +0200 Subject: [PATCH 064/278] doi record migration --- .../migrations/20240604115330_doi_record_table/migration.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 desci-server/prisma/migrations/20240604115330_doi_record_table/migration.sql diff --git a/desci-server/prisma/migrations/20240604115330_doi_record_table/migration.sql b/desci-server/prisma/migrations/20240604115330_doi_record_table/migration.sql new file mode 100644 index 00000000..58adc834 --- /dev/null +++ b/desci-server/prisma/migrations/20240604115330_doi_record_table/migration.sql @@ -0,0 +1,2 @@ +-- DropIndex +DROP INDEX "DoiRecord_uuid_key"; From 08eda459e36d9f3a0ea7cbd217f41951efed80b5 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Tue, 4 Jun 2024 15:04:45 +0200 Subject: [PATCH 065/278] doi migration --- .vscode/settings.json | 2 +- .../migration.sql | 2 -- .../migration.sql | 20 +++++++++++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) delete mode 100644 desci-server/prisma/migrations/20240604115330_doi_record_table/migration.sql create mode 100644 desci-server/prisma/migrations/20240604123832_add_doi_records_table/migration.sql diff --git a/.vscode/settings.json b/.vscode/settings.json index 317272b1..ec6e6899 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,7 @@ { "explorer.compactFolders": false, "files.exclude": { - "**/node_modules/**": true + "**/node_modules/**": false }, "editor.formatOnSave": true, // Tell VSCode to format files on save "editor.defaultFormatter": "esbenp.prettier-vscode", diff --git a/desci-server/prisma/migrations/20240604115330_doi_record_table/migration.sql b/desci-server/prisma/migrations/20240604115330_doi_record_table/migration.sql deleted file mode 100644 index 58adc834..00000000 --- a/desci-server/prisma/migrations/20240604115330_doi_record_table/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ --- DropIndex -DROP INDEX "DoiRecord_uuid_key"; diff --git a/desci-server/prisma/migrations/20240604123832_add_doi_records_table/migration.sql b/desci-server/prisma/migrations/20240604123832_add_doi_records_table/migration.sql new file mode 100644 index 00000000..3e12b474 --- /dev/null +++ b/desci-server/prisma/migrations/20240604123832_add_doi_records_table/migration.sql @@ -0,0 +1,20 @@ +-- CreateTable +CREATE TABLE "DoiRecord" ( + "id" SERIAL NOT NULL, + "doi" TEXT NOT NULL, + "dpid" TEXT NOT NULL, + "uuid" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "DoiRecord_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "DoiRecord_doi_key" ON "DoiRecord"("doi"); + +-- CreateIndex +CREATE UNIQUE INDEX "DoiRecord_dpid_key" ON "DoiRecord"("dpid"); + +-- AddForeignKey +ALTER TABLE "DoiRecord" ADD CONSTRAINT "DoiRecord_uuid_fkey" FOREIGN KEY ("uuid") REFERENCES "Node"("uuid") ON DELETE RESTRICT ON UPDATE CASCADE; From def83e9b9696f2363fecd50128f677438bebcc15 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Tue, 4 Jun 2024 15:59:50 +0200 Subject: [PATCH 066/278] fix: error transform --- desci-server/src/core/ApiError.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/desci-server/src/core/ApiError.ts b/desci-server/src/core/ApiError.ts index dc7e3182..c5379097 100644 --- a/desci-server/src/core/ApiError.ts +++ b/desci-server/src/core/ApiError.ts @@ -47,7 +47,7 @@ export abstract class ApiError extends Error { } } - public static transform(err: Error, res): Response { + public static transform(err: Error, res: Response): Response { if (err instanceof AttestationError) { switch (err.type) { case AttestationErrorType.DUPLICATE: @@ -72,6 +72,7 @@ export abstract class ApiError extends Error { return new InternalErrorResponse(err.message).send(res); } } + return new InternalErrorResponse(err.message).send(res); } } From fe35e7231fb636ccff67d1b4ec08c0d545d6e6b8 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Tue, 4 Jun 2024 16:35:30 +0000 Subject: [PATCH 067/278] replace preview generating lib, fix bugs --- desci-media-isolated/Dockerfile | 2 +- desci-media-isolated/package-lock.json | 95 ++++++++++++++++++- desci-media-isolated/package.json | 1 + .../src/controllers/pdf/preview.ts | 14 +-- desci-media-isolated/src/services/pdf.ts | 53 ++++++++++- 5 files changed, 153 insertions(+), 12 deletions(-) diff --git a/desci-media-isolated/Dockerfile b/desci-media-isolated/Dockerfile index 35779547..faba2f8d 100644 --- a/desci-media-isolated/Dockerfile +++ b/desci-media-isolated/Dockerfile @@ -3,7 +3,7 @@ FROM docker.io/node:20.9.0 as base # Install dumb-init so we can use it as PID 1 -RUN apt-get update && apt-get install -y dumb-init ghostscript unoconv ffmpeg imagemagick curl && \ +RUN apt-get update && apt-get install -y dumb-init ghostscript unoconv ffmpeg imagemagick graphicsmagick curl && \ rm -rf /var/lib/apt/lists/* # Modify ImageMagick policy to allow PDF processing diff --git a/desci-media-isolated/package-lock.json b/desci-media-isolated/package-lock.json index 2dee82cc..b31f36ba 100644 --- a/desci-media-isolated/package-lock.json +++ b/desci-media-isolated/package-lock.json @@ -14,6 +14,7 @@ "filepreview_ts": "^1.0.0", "helmet": "^7.1.0", "pdf-lib": "^1.17.1", + "pdf2pic": "^3.1.1", "pdflib-fontkit": "^1.8.11", "tsx": "^4.7.1" }, @@ -854,6 +855,16 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, + "node_modules/array-parallel": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/array-parallel/-/array-parallel-0.1.3.tgz", + "integrity": "sha512-TDPTwSWW5E4oiFiKmz6RGJ/a80Y91GuLgUYuLd49+XBS75tYo8PNgaT2K/OxuQYqkoI852MDGBorg9OcUSTQ8w==" + }, + "node_modules/array-series": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/array-series/-/array-series-0.1.5.tgz", + "integrity": "sha512-L0XlBwfx9QetHOsbLDrE/vh2t018w9462HM3iaFfxRiK83aJjAt/Ja3NMkOW7FICwWTlQBa3ZbL5FKhuQWkDrg==" + }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", @@ -1813,6 +1824,67 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/gm": { + "version": "1.25.0", + "resolved": "https://registry.npmjs.org/gm/-/gm-1.25.0.tgz", + "integrity": "sha512-4kKdWXTtgQ4biIo7hZA396HT062nDVVHPjQcurNZ3o/voYN+o5FUC5kOwuORbpExp3XbTJ3SU7iRipiIhQtovw==", + "dependencies": { + "array-parallel": "~0.1.3", + "array-series": "~0.1.5", + "cross-spawn": "^4.0.0", + "debug": "^3.1.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/gm/node_modules/cross-spawn": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", + "integrity": "sha512-yAXz/pA1tD8Gtg2S98Ekf/sewp3Lcp3YoFKJ4Hkp5h5yLWnKVTDU0kwjKJ8NDCYcfTLfyGkzTikst+jWypT1iA==", + "dependencies": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "node_modules/gm/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/gm/node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/gm/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/gm/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/gm/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -2040,8 +2112,7 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/js-yaml": { "version": "4.1.0", @@ -2426,6 +2497,21 @@ "tslib": "^1.11.1" } }, + "node_modules/pdf2pic": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/pdf2pic/-/pdf2pic-3.1.1.tgz", + "integrity": "sha512-AHXsYi9EcYlSm3uUANz7h5WSktHiyTnUeHqdWmyRdjdMhgq9LgZ8pggl9FOUGuCLVfe+NKxp2k9sEMCH3tHIEg==", + "dependencies": { + "gm": "^1.25.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "paypal", + "url": "https://www.paypal.me/yakovmeister" + } + }, "node_modules/pdflib-fontkit": { "version": "1.8.11", "resolved": "https://registry.npmjs.org/pdflib-fontkit/-/pdflib-fontkit-1.8.11.tgz", @@ -2472,6 +2558,11 @@ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", diff --git a/desci-media-isolated/package.json b/desci-media-isolated/package.json index 13f8babc..410743b2 100644 --- a/desci-media-isolated/package.json +++ b/desci-media-isolated/package.json @@ -18,6 +18,7 @@ "filepreview_ts": "^1.0.0", "helmet": "^7.1.0", "pdf-lib": "^1.17.1", + "pdf2pic": "^3.1.1", "pdflib-fontkit": "^1.8.11", "tsx": "^4.7.1" }, diff --git a/desci-media-isolated/src/controllers/pdf/preview.ts b/desci-media-isolated/src/controllers/pdf/preview.ts index 735674f2..e032bc9e 100644 --- a/desci-media-isolated/src/controllers/pdf/preview.ts +++ b/desci-media-isolated/src/controllers/pdf/preview.ts @@ -5,6 +5,7 @@ import { fileURLToPath } from 'url'; import fs from 'fs'; import { TEMP_DIR, THUMBNAIL_OUTPUT_DIR } from '../../config/index.js'; import { BadRequestError, NotFoundError } from '../../utils/customErrors.js'; +import { PdfManipulationService } from '../../services/pdf.js'; export type GeneratePreviewRequestBody = { cid: string; @@ -19,7 +20,6 @@ export const generatePreview = async ( req: Request, res: Response, ) => { - debugger; const { cid, pages } = req.body; const { height = 1000 } = req.query; @@ -27,24 +27,24 @@ export const generatePreview = async ( if (!pages) throw new BadRequestError('Missing pages number array in request body'); try { + const previewPaths = await PdfManipulationService.generatePdfPreviews(cid, `${cid}.pdf`, pages, height); const previewStreams: fs.ReadStream[] = []; - for (const pageNum of pages) { - const thumbnailPath = await ThumbnailsService.generateThumbnail(cid, `${cid}_${pageNum}.png`, height); - const fullThumbnailPath = path.join(BASE_TEMP_DIR, THUMBNAIL_OUTPUT_DIR, thumbnailPath); + for (const previewPath of previewPaths) { + const fullPreviewPath = path.join(BASE_TEMP_DIR, THUMBNAIL_OUTPUT_DIR, previewPath); // Check if the file exists before attempting to stream it await new Promise((resolve, reject) => { - fs.access(fullThumbnailPath, fs.constants.F_OK, (err) => { + fs.access(fullPreviewPath, fs.constants.F_OK, (err) => { if (err) { - reject(new NotFoundError(`Thumbnail not found for file with cid: ${cid}, page: ${pageNum}`)); + reject(new NotFoundError(`Preview not found for file with cid: ${cid}, path: ${previewPath}`)); } else { resolve(); } }); }); - const readStream = fs.createReadStream(fullThumbnailPath); + const readStream = fs.createReadStream(fullPreviewPath); previewStreams.push(readStream); } diff --git a/desci-media-isolated/src/services/pdf.ts b/desci-media-isolated/src/services/pdf.ts index 217f8708..ca14f3f5 100644 --- a/desci-media-isolated/src/services/pdf.ts +++ b/desci-media-isolated/src/services/pdf.ts @@ -1,8 +1,9 @@ -import { PDF_FILES_DIR, PDF_OUTPUT_DIR, TEMP_DIR } from '../config/index.js'; +import { PDF_FILES_DIR, PDF_OUTPUT_DIR, TEMP_DIR, THUMBNAIL_FILES_DIR, THUMBNAIL_OUTPUT_DIR } from '../config/index.js'; import { IpfsService } from './ipfs.js'; -import { UnhandledError } from '../utils/customErrors.js'; +import { BadRequestError, UnhandledError } from '../utils/customErrors.js'; import path from 'path'; import fs from 'fs'; +import { fromPath } from 'pdf2pic'; import * as fsp from 'fs/promises'; import { fileURLToPath } from 'url'; import { PDFArray, PDFDict, PDFDocument, PDFName, PDFString, StandardFonts, rgb } from 'pdf-lib'; @@ -492,4 +493,52 @@ export class PdfManipulationService { return exceedsLimit ? `${formattedAuthors.join(', ')}, et al.` : formattedAuthors.join(', '); } + + static async generatePdfPreviews(pdfCid: string, fileName: string, pageNumbers: number[], heightPx: number) { + const extension = '.' + fileName.split('.').pop(); + if (!extension) throw new BadRequestError('Invalid file name, requires extension'); + const tempFilePath = path.join(BASE_TEMP_DIR, THUMBNAIL_FILES_DIR, `${pdfCid + extension}`); + const previewPaths: string[] = []; + + await IpfsService.saveFile(pdfCid, tempFilePath); + + try { + const converter = fromPath(tempFilePath, { + saveFilename: `${pdfCid}_preview`, + savePath: path.join(BASE_TEMP_DIR, THUMBNAIL_OUTPUT_DIR), + format: 'jpg', + height: heightPx, + preserveAspectRatio: true, + }); + + for (const pageNumber of pageNumbers) { + const previewPath = this.getPreviewPath(pdfCid, pageNumber, heightPx); + await converter(pageNumber).then((result) => { + if (result.path) { + fs.renameSync(result.path, path.join(BASE_TEMP_DIR, THUMBNAIL_OUTPUT_DIR, previewPath)); + } else { + throw new Error(`Preview path is undefined for page ${pageNumber}`); + } + }); + previewPaths.push(previewPath); + } + + console.log('Previews generated successfully:', previewPaths); + return previewPaths; + } catch (e) { + console.error(e); + throw new UnhandledError(`Failed generating previews for file with pdfCid: ${pdfCid}`); + } finally { + // The initially saved file is removed, however the generated previews remain. Further cleanup can be done for the generated previews. + try { + await fs.promises.unlink(tempFilePath); + console.log(`Temporary file ${tempFilePath} deleted successfully.`); + } catch (cleanupError) { + console.error(`Failed to delete temporary file ${tempFilePath}:`, cleanupError); + } + } + } + static getPreviewPath(cid: string, pageNumber: number, height: number) { + return `h-${height}px_${cid}_${pageNumber}.jpg`; + } } From a003730cbf404bf484f099f1dde0832811aaeb04 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Tue, 4 Jun 2024 19:15:24 +0000 Subject: [PATCH 068/278] change preview api on media server to return buffers --- .../src/controllers/pdf/preview.ts | 28 +++++++------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/desci-media-isolated/src/controllers/pdf/preview.ts b/desci-media-isolated/src/controllers/pdf/preview.ts index e032bc9e..c076e5db 100644 --- a/desci-media-isolated/src/controllers/pdf/preview.ts +++ b/desci-media-isolated/src/controllers/pdf/preview.ts @@ -1,8 +1,7 @@ import type { Request, Response } from 'express'; -import { ThumbnailsService } from '../../services/thumbnails.js'; import path from 'path'; import { fileURLToPath } from 'url'; -import fs from 'fs'; +import fs from 'fs/promises'; import { TEMP_DIR, THUMBNAIL_OUTPUT_DIR } from '../../config/index.js'; import { BadRequestError, NotFoundError } from '../../utils/customErrors.js'; import { PdfManipulationService } from '../../services/pdf.js'; @@ -27,29 +26,22 @@ export const generatePreview = async ( if (!pages) throw new BadRequestError('Missing pages number array in request body'); try { + // debugger; const previewPaths = await PdfManipulationService.generatePdfPreviews(cid, `${cid}.pdf`, pages, height); - const previewStreams: fs.ReadStream[] = []; - + const previewBuffers: Buffer[] = []; for (const previewPath of previewPaths) { const fullPreviewPath = path.join(BASE_TEMP_DIR, THUMBNAIL_OUTPUT_DIR, previewPath); - // Check if the file exists before attempting to stream it - await new Promise((resolve, reject) => { - fs.access(fullPreviewPath, fs.constants.F_OK, (err) => { - if (err) { - reject(new NotFoundError(`Preview not found for file with cid: ${cid}, path: ${previewPath}`)); - } else { - resolve(); - } - }); - }); - - const readStream = fs.createReadStream(fullPreviewPath); - previewStreams.push(readStream); + try { + const previewBuffer = await fs.readFile(fullPreviewPath); + previewBuffers.push(previewBuffer); + } catch (err) { + throw new NotFoundError(`Preview not found for file with cid: ${cid}, path: ${previewPath}`); + } } res.setHeader('Content-Type', 'application/json'); - res.status(200).json(previewStreams); + res.status(200).json(previewBuffers); } catch (err: any) { return res.status(500).json({ message: err.message }); } From 06078d140729bd9c88fe0737a5bee905f6edab81 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Tue, 4 Jun 2024 19:15:46 +0000 Subject: [PATCH 069/278] fixes for preview api --- desci-server/src/services/PublishPackage.ts | 4 ++-- desci-server/src/services/ipfs.ts | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/desci-server/src/services/PublishPackage.ts b/desci-server/src/services/PublishPackage.ts index 9d64a254..18410ddf 100644 --- a/desci-server/src/services/PublishPackage.ts +++ b/desci-server/src/services/PublishPackage.ts @@ -123,7 +123,7 @@ class PublishPackageService { return null; } - debugger; + // debugger; // Generate the preview const previewResponse = await axios.post( `${process.env.ISOLATED_MEDIA_SERVER_URL}/v1/pdf/previews?height=${heightPx}`, @@ -141,7 +141,7 @@ class PublishPackageService { for (let i = 0; i < previewStreams.length; i++) { const pageNumber = pageNums[i]; const previewStream = previewStreams[i]; - + debugger; // Save it on IPFS const pinned = await pinFile(previewStream); diff --git a/desci-server/src/services/ipfs.ts b/desci-server/src/services/ipfs.ts index 87c945ff..4c9e6771 100644 --- a/desci-server/src/services/ipfs.ts +++ b/desci-server/src/services/ipfs.ts @@ -8,15 +8,15 @@ import { type ResearchObjectV1Component, } from '@desci-labs/desci-models'; import type { PBNode } from '@ipld/dag-pb'; -import * as dagPb from "@ipld/dag-pb"; +import * as dagPb from '@ipld/dag-pb'; import { DataReference, DataType, NodeVersion } from '@prisma/client'; import axios from 'axios'; +import { UnixFS } from 'ipfs-unixfs'; import toBuffer from 'it-to-buffer'; +import { create, CID, globSource } from 'kubo-rpc-client'; import { flatten, uniq } from 'lodash-es'; import * as multiformats from 'multiformats'; import { code as rawCode } from 'multiformats/codecs/raw'; -import { create, CID, globSource } from 'kubo-rpc-client' -import { UnixFS } from 'ipfs-unixfs'; import { prisma } from '../client.js'; import { PUBLIC_IPFS_PATH } from '../config/index.js'; @@ -300,8 +300,8 @@ export const pinFile = async (file: Buffer | Readable | ReadableStream): Promise const isOnline = await client.isOnline(); logger.debug({ fn: 'pinFile' }, `isOnline: ${isOnline}`); - const uploaded = await client.add(file, { cidVersion: 1, pin: true }); - return { ...uploaded, cid: uploaded.cid.toString() }; + const uploadedFile = await client.add(file, { cidVersion: 1, pin: true }); + return { ...uploadedFile, cid: uploadedFile.cid.toString() }; }; export interface RecursiveLsResult extends IpfsPinnedResult { @@ -1005,7 +1005,7 @@ export async function getExternalCidSizeAndType(cid: string) { size = fSize; } else { size = unixFs.blockSizes.reduce((a, b) => a + b, BigInt(0)); - }; + } } if (isDirectory !== undefined && size !== undefined) return { isDirectory, size }; throw new Error(`Failed to resolve CID or determine file size/type for cid: ${cid}`); From 736d69e274c45d2fcb8c96a6a32934672268427d Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Wed, 5 Jun 2024 08:47:31 +0000 Subject: [PATCH 070/278] backend dbg port changed to 9228 to prevent collision issues --- .vscode/launch.json | 2 +- desci-server/nodemon.json | 2 +- docker-compose.dev.yml | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 99647a2a..f6b0be3f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,7 +9,7 @@ "type": "node", "request": "attach", "restart": true, - "port": 9229, + "port": 9228, "address": "localhost", "localRoot": "${workspaceFolder}", "remoteRoot": "/app" diff --git a/desci-server/nodemon.json b/desci-server/nodemon.json index b343dff9..c24de8fa 100644 --- a/desci-server/nodemon.json +++ b/desci-server/nodemon.json @@ -7,7 +7,7 @@ "log/server.log" ], "verbose": true, - "exec": "node -r ts-node/register --inspect=0.0.0.0", + "exec": "node -r ts-node/register --inspect=0.0.0.0:9228", "delay": 300, "signal": "SIGTERM" } \ No newline at end of file diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 064418bd..ce3f958e 100755 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -54,6 +54,7 @@ services: - "5420:5420" - "9229:9229" - "9277:9277" + - "9228:9228" - "5555:5555" extra_hosts: - host.docker.internal:host-gateway From 32b8ec3b1697e6b6805f4e34a2845d76a1be3c6b Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Wed, 5 Jun 2024 10:53:54 +0200 Subject: [PATCH 071/278] refactor: format cross ref env variables --- .env.example | 6 +++--- .env.test | 6 +++--- desci-server/kubernetes/deployment_dev.yaml | 3 +++ desci-server/kubernetes/deployment_prod.yaml | 3 +++ desci-server/kubernetes/deployment_staging.yaml | 3 +++ desci-server/src/services/index.ts | 6 +++--- desci-server/src/types/ProcessEnv.d.ts | 6 +++--- 7 files changed, 21 insertions(+), 12 deletions(-) diff --git a/.env.example b/.env.example index 108d5ec6..9d7ca1b3 100755 --- a/.env.example +++ b/.env.example @@ -127,6 +127,6 @@ MAX_LOCK_TIME=3600 # 1 hour DOI_PREFIX=https://doi.org/10.555 # Cross ref api -CROSS_REF_API=https://api.crossref.org -CROSS_REF_API_KEY= -CROSS_REF_EMAIL= +CROSSREF_API=https://api.crossref.org +CROSSREF_API_KEY= +CROSSREF_EMAIL= diff --git a/.env.test b/.env.test index ddf5505f..17e0a837 100644 --- a/.env.test +++ b/.env.test @@ -77,6 +77,6 @@ REPO_SERVER_URL=http://host.docker.internal:5485 DOI_PREFIX=https://doi.org/10.555 # Cross ref api -CROSS_REF_API=https://api.crossref.org -CROSS_REF_API_KEY= -CROSS_REF_EMAIL= \ No newline at end of file +CROSSREF_API=https://api.crossref.org +CROSSREF_API_KEY= +CROSSREF_EMAIL= \ No newline at end of file diff --git a/desci-server/kubernetes/deployment_dev.yaml b/desci-server/kubernetes/deployment_dev.yaml index 831a978b..a9dec132 100644 --- a/desci-server/kubernetes/deployment_dev.yaml +++ b/desci-server/kubernetes/deployment_dev.yaml @@ -80,6 +80,9 @@ spec: export ETHEREUM_RPC_URL={{ .Data.ETHEREUM_RPC_URL }} export GOOGLE_CLIENT_ID={{ .Data.GOOGLE_CLIENT_ID }} export DOI_PREFIX={{ .Data.DOI_PREFIX }} + export CROSSREF_API={{ .Data.CROSSREF_API }} + export CROSSREF_API_KEY={{ .Data.CROSSREF_API_KEY }} + export CROSSREF_EMAIL={{ .Data.CROSSREF_EMAIL }} export DEBUG_TEST=0; echo "appfinish"; {{- end -}} diff --git a/desci-server/kubernetes/deployment_prod.yaml b/desci-server/kubernetes/deployment_prod.yaml index 40783e88..433c06e9 100755 --- a/desci-server/kubernetes/deployment_prod.yaml +++ b/desci-server/kubernetes/deployment_prod.yaml @@ -80,6 +80,9 @@ spec: export ETHEREUM_RPC_URL={{ .Data.ETHEREUM_RPC_URL }} export GOOGLE_CLIENT_ID={{ .Data.GOOGLE_CLIENT_ID }} export DOI_PREFIX={{ .Data.DOI_PREFIX }} + export CROSSREF_API={{ .Data.CROSSREF_API }} + export CROSSREF_API_KEY={{ .Data.CROSSREF_API_KEY }} + export CROSSREF_EMAIL={{ .Data.CROSSREF_EMAIL }} export IGNORE_LINE=0; export DEBUG_TEST=0; echo "appfinish"; diff --git a/desci-server/kubernetes/deployment_staging.yaml b/desci-server/kubernetes/deployment_staging.yaml index 1ea7cb38..37f173ed 100644 --- a/desci-server/kubernetes/deployment_staging.yaml +++ b/desci-server/kubernetes/deployment_staging.yaml @@ -92,6 +92,9 @@ spec: export ETHEREUM_RPC_URL={{ .Data.ETHEREUM_RPC_URL }} export GOOGLE_CLIENT_ID={{ .Data.GOOGLE_CLIENT_ID }} export DOI_PREFIX={{ .Data.DOI_PREFIX }} + export CROSSREF_API={{ .Data.CROSSREF_API }} + export CROSSREF_API_KEY={{ .Data.CROSSREF_API_KEY }} + export CROSSREF_EMAIL={{ .Data.CROSSREF_EMAIL }} export DEBUG_TEST=0; echo "appfinish"; {{- end -}} diff --git a/desci-server/src/services/index.ts b/desci-server/src/services/index.ts index 53632886..8c84dbfb 100644 --- a/desci-server/src/services/index.ts +++ b/desci-server/src/services/index.ts @@ -5,7 +5,7 @@ import { DoiService } from './Doi.js'; export const doiService = new DoiService(prisma); export const crossRefClient = new CrossRefClient( - process.env.CROSS_REF_API, - process.env.CROSS_REF_API_KEY, - process.env.CROSS_REF_EMAIL, + process.env.CROSSREF_API, + process.env.CROSSREF_API_KEY, + process.env.CROSSREF_EMAIL, ); diff --git a/desci-server/src/types/ProcessEnv.d.ts b/desci-server/src/types/ProcessEnv.d.ts index b42acef7..b7bbcda1 100755 --- a/desci-server/src/types/ProcessEnv.d.ts +++ b/desci-server/src/types/ProcessEnv.d.ts @@ -10,8 +10,8 @@ declare namespace NodeJS { JWT_SECRET: string; JWT_EXPIRATION: string; MAX_LOCK_TIME: string; - CROSS_REF_API: string; - CROSS_REF_EMAIL: string; - CROSS_REF_API_KEY: string; + CROSSREF_API: string; + CROSSREF_EMAIL: string; + CROSSREF_API_KEY: string; } } From 070d4bafc46c95ec53a4492c39f2bde5731009d8 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Wed, 5 Jun 2024 09:20:01 +0000 Subject: [PATCH 072/278] fix prev api --- desci-media-isolated/src/services/pdf.ts | 1 + desci-server/src/controllers/nodes/frontmatterPreview.ts | 2 +- desci-server/src/services/PublishPackage.ts | 6 ++---- desci-server/src/services/ipfs.ts | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/desci-media-isolated/src/services/pdf.ts b/desci-media-isolated/src/services/pdf.ts index ca14f3f5..d17d74ce 100644 --- a/desci-media-isolated/src/services/pdf.ts +++ b/desci-media-isolated/src/services/pdf.ts @@ -509,6 +509,7 @@ export class PdfManipulationService { format: 'jpg', height: heightPx, preserveAspectRatio: true, + density: 300, }); for (const pageNumber of pageNumbers) { diff --git a/desci-server/src/controllers/nodes/frontmatterPreview.ts b/desci-server/src/controllers/nodes/frontmatterPreview.ts index 3d021056..1898fed4 100644 --- a/desci-server/src/controllers/nodes/frontmatterPreview.ts +++ b/desci-server/src/controllers/nodes/frontmatterPreview.ts @@ -60,7 +60,7 @@ export const frontmatterPreview = async ( if (!node) return res.status(401).json({ ok: false, error: 'Unauthorized' }); } - debugger; + // debugger; const previewMap = await publishPackageService.generatePdfPreview(pdfCid, 1000, [1, 2], ensureUuidEndsWithDot(uuid)); // debugger; return res.status(200).json({ ok: true, frontmatterPageCid: previewMap[1], contentPageCid: previewMap[2] }); diff --git a/desci-server/src/services/PublishPackage.ts b/desci-server/src/services/PublishPackage.ts index 18410ddf..19ced63d 100644 --- a/desci-server/src/services/PublishPackage.ts +++ b/desci-server/src/services/PublishPackage.ts @@ -135,17 +135,15 @@ class PublishPackageService { const previewStreams = previewResponse.data; - const previews: { pageNumber: number; cid: string }[] = []; const previewMap: PreviewMap = {}; for (let i = 0; i < previewStreams.length; i++) { const pageNumber = pageNums[i]; + // debugger; const previewStream = previewStreams[i]; - debugger; // Save it on IPFS - const pinned = await pinFile(previewStream); + const pinned = await pinFile(previewStream.data); - previews.push({ pageNumber, cid: pinned.cid }); previewMap[pageNumber] = pinned.cid; } diff --git a/desci-server/src/services/ipfs.ts b/desci-server/src/services/ipfs.ts index 4c9e6771..5d385a6a 100644 --- a/desci-server/src/services/ipfs.ts +++ b/desci-server/src/services/ipfs.ts @@ -298,8 +298,8 @@ export async function pinExternalDags(cids: string[]): Promise { export const pinFile = async (file: Buffer | Readable | ReadableStream): Promise => { const isOnline = await client.isOnline(); + // debugger; logger.debug({ fn: 'pinFile' }, `isOnline: ${isOnline}`); - const uploadedFile = await client.add(file, { cidVersion: 1, pin: true }); return { ...uploadedFile, cid: uploadedFile.cid.toString() }; }; From 527b174c2f7181ce2b14e9ce9afae91267092f00 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Wed, 5 Jun 2024 12:27:19 +0200 Subject: [PATCH 073/278] update env var --- .env.example | 2 +- .env.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index 9d7ca1b3..37ff994f 100755 --- a/.env.example +++ b/.env.example @@ -124,7 +124,7 @@ MUTE_PUBLISH_WORKER=false # SingleNodeLockServce MAX_LOCK_TIME=3600 # 1 hour -DOI_PREFIX=https://doi.org/10.555 +DOI_PREFIX=https://doi.org/10.62891 # Cross ref api CROSSREF_API=https://api.crossref.org diff --git a/.env.test b/.env.test index 17e0a837..8e78ffe8 100644 --- a/.env.test +++ b/.env.test @@ -74,7 +74,7 @@ NODES_MEDIA_SERVER_URL=http://host.docker.internal:5454 REPO_SERVICE_SECRET_KEY="m8sIy5BPygBcX3+ZmMVuAA10k6w59BSCZd+Z5+VLYm4=" REPO_SERVER_URL=http://host.docker.internal:5485 -DOI_PREFIX=https://doi.org/10.555 +DOI_PREFIX=https://doi.org/10.62891 # Cross ref api CROSSREF_API=https://api.crossref.org From c9c29325e6943b5a8e9ebb398ea3380cd655348b Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Wed, 5 Jun 2024 13:15:00 +0200 Subject: [PATCH 074/278] feat: Add doi to pdf component payload and bump desci-model version --- desci-models/package.json | 2 +- desci-models/src/ResearchObject.ts | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/desci-models/package.json b/desci-models/package.json index d8cc13d9..71abb3d0 100644 --- a/desci-models/package.json +++ b/desci-models/package.json @@ -1,6 +1,6 @@ { "name": "@desci-labs/desci-models", - "version": "0.2.6-rc1", + "version": "0.2.7-rc1", "description": "Data models for DeSci Nodes", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/desci-models/src/ResearchObject.ts b/desci-models/src/ResearchObject.ts index 66084c01..77a9a539 100644 --- a/desci-models/src/ResearchObject.ts +++ b/desci-models/src/ResearchObject.ts @@ -244,6 +244,8 @@ export interface PdfComponentPayload { cid: string; /** Annotations on the document */ annotations?: PdfAnnotation[]; + /** DOI of the pdf or manuscript */ + doi?: string; } export interface ExternalLinkComponentPayload { From 258cbfd0477f955d0aeb6f91e673f91915638581 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Wed, 5 Jun 2024 17:31:41 +0200 Subject: [PATCH 075/278] feat: implement Api to attach doi to manuscripts in draft mode (reuseable in prepub flow) --- desci-repo/src/services/manifestRepo.ts | 8 -- desci-server/src/controllers/doi/check.ts | 79 ++++++++++++++++++- desci-server/src/controllers/doi/index.ts | 1 + desci-server/src/controllers/doi/schema.ts | 8 ++ desci-server/src/routes/v1/doi.ts | 14 +++- desci-server/src/services/Doi.ts | 2 +- desci-server/src/services/crossRef/client.ts | 2 +- .../src/services/crossRef/definitions.ts | 10 +-- desci-server/src/services/repoService.ts | 4 +- 9 files changed, 104 insertions(+), 24 deletions(-) create mode 100644 desci-server/src/controllers/doi/schema.ts diff --git a/desci-repo/src/services/manifestRepo.ts b/desci-repo/src/services/manifestRepo.ts index 7f8ae945..a5e2ef2c 100644 --- a/desci-repo/src/services/manifestRepo.ts +++ b/desci-repo/src/services/manifestRepo.ts @@ -201,14 +201,6 @@ export const getDocumentUpdater = (documentId: DocumentId) => { { time: Date.now(), message: action.type }, ); break; - case 'Update Component': - handle.change( - (document) => { - updateManifestComponent(document, action.component, action.componentIndex); - }, - { time: Date.now(), message: action.type }, - ); - break; case 'Publish Dpid': handle.change( (document) => { diff --git a/desci-server/src/controllers/doi/check.ts b/desci-server/src/controllers/doi/check.ts index 88a459a0..95bda635 100644 --- a/desci-server/src/controllers/doi/check.ts +++ b/desci-server/src/controllers/doi/check.ts @@ -1,11 +1,30 @@ +import { DocumentId } from '@automerge/automerge-repo'; +import { CommonComponentPayload, PdfComponent, ResearchObjectComponentType } from '@desci-labs/desci-models'; import { NextFunction, Request, Response } from 'express'; import { DoiError } from '../../core/doi/error.js'; -import { BadRequestError, SuccessResponse, doiService, logger } from '../../internal.js'; +import { + BadRequestError, + ForbiddenError, + NotFoundError, + RequestWithNode, + SuccessResponse, + crossRefClient, + doiService, + getLatestManifestFromNode, + logger as parentLogger, +} from '../../internal.js'; +import { WorkSelectOptions } from '../../services/crossRef/definitions.js'; +import repoService from '../../services/repoService.js'; export const checkMintability = async (req: Request, res: Response, _next: NextFunction) => { const { uuid } = req.params; if (!uuid) throw new BadRequestError(); + + const logger = parentLogger.child({ + module: 'DOI::checkMintability', + }); + try { await doiService.checkMintability(uuid); new SuccessResponse(true).send(res); @@ -25,3 +44,61 @@ export const getDoi = async (req: Request, res: Response, next: NextFunction) => const doi = await doiService.getDoiByDpidOrUuid(identifier); new SuccessResponse(doi).send(res); }; + +export const attachDoi = async (req: RequestWithNode, res: Response, _next: NextFunction) => { + const { uuid, path } = req.body; + + const logger = parentLogger.child({ + module: 'DOI::AttachDOI', + }); + + const node = req.node; + + const latestManifest = await getLatestManifestFromNode(node); + const componentIndex = latestManifest.components.findIndex( + (component) => + component.type === ResearchObjectComponentType.PDF && (component.payload as CommonComponentPayload).path === path, + ); + + if (componentIndex === -1) throw new BadRequestError('Component to attach DOI not a valid pdf'); + + const component = latestManifest.components[componentIndex] as PdfComponent; + + if (component.payload.doi) throw new ForbiddenError(`${component.subtype || component.type} already has a DOI`); + + const queryTitle = + component.payload.path.split('/').pop().replace(/\.pdf/g, '') || + component.name.replace(/\.pdf/g, '') || + component.payload.title; + + const works = await crossRefClient.listWorks({ + queryTitle, + rows: 5, + select: [WorkSelectOptions.DOI, WorkSelectOptions.TITLE, WorkSelectOptions.AUTHOR], + }); + + const doi = works?.data?.message?.items.find((item) => item.title.some((t) => t === queryTitle)); + + logger.info({ doi, queryTitle }, 'DOI Response'); + + if (!(doi && works.ok)) { + logger.info({ data: works?.data?.message?.items }, 'DOI Not Found'); + throw new NotFoundError('DOI not found'); + } + + const response = await repoService.dispatchAction({ + uuid, + documentId: node.manifestDocumentId as DocumentId, + actions: [ + { + type: 'Update Component', + component: { ...component, payload: { ...component.payload, doi: doi.DOI } }, + componentIndex, + }, + ], + }); + + logger.info(response.manifest.components[componentIndex], 'component updated'); + + new SuccessResponse(true).send(res); +}; diff --git a/desci-server/src/controllers/doi/index.ts b/desci-server/src/controllers/doi/index.ts index 3313418d..81e6b392 100644 --- a/desci-server/src/controllers/doi/index.ts +++ b/desci-server/src/controllers/doi/index.ts @@ -1,2 +1,3 @@ export * from './check.js'; export * from './mint.js'; +export * from './schema.js'; diff --git a/desci-server/src/controllers/doi/schema.ts b/desci-server/src/controllers/doi/schema.ts new file mode 100644 index 00000000..1220604c --- /dev/null +++ b/desci-server/src/controllers/doi/schema.ts @@ -0,0 +1,8 @@ +import { z } from 'zod'; + +export const attachDoiSchema = z.object({ + body: z.object({ + uuid: z.string(), + path: z.string().startsWith('root/', 'Invalid component path'), + }), +}); diff --git a/desci-server/src/routes/v1/doi.ts b/desci-server/src/routes/v1/doi.ts index d80a6e49..841597bc 100644 --- a/desci-server/src/routes/v1/doi.ts +++ b/desci-server/src/routes/v1/doi.ts @@ -1,11 +1,21 @@ import { Router } from 'express'; -import { asyncHander, checkMintability, ensureNodeAccess, ensureUser, getDoi, mintDoi } from '../../internal.js'; - +import { + asyncHander, + attachDoi, + attachDoiSchema, + checkMintability, + ensureNodeAccess, + ensureUser, + getDoi, + mintDoi, + validate, +} from '../../internal.js'; const router = Router(); router.post('/check/:uuid', [ensureUser, ensureNodeAccess], asyncHander(checkMintability)); router.post('/mint/:uuid', [ensureUser, ensureNodeAccess], asyncHander(mintDoi)); +router.post('/attach', [ensureUser, ensureNodeAccess, validate(attachDoiSchema)], asyncHander(attachDoi)); router.get('/:identifier', [ensureUser], asyncHander(getDoi)); export default router; diff --git a/desci-server/src/services/Doi.ts b/desci-server/src/services/Doi.ts index 3013e863..a5d72501 100644 --- a/desci-server/src/services/Doi.ts +++ b/desci-server/src/services/Doi.ts @@ -60,7 +60,7 @@ export class DoiService { select: [WorkSelectOptions.DOI, WorkSelectOptions.TITLE, WorkSelectOptions.AUTHOR], queryTitle: manuscriptTitle, }); - const doi = works?.data?.message?.items.find((item) => item.title === manuscriptTitle); + const doi = works?.data?.message?.items.find((item) => item.title.some((t) => t === manuscriptTitle)); logger.info({ status: works.ok, manuscript: manuscriptTitle, doi }, 'Search Manuscripts'); if (!doi) return null; diff --git a/desci-server/src/services/crossRef/client.ts b/desci-server/src/services/crossRef/client.ts index deb362ff..3f993b5a 100644 --- a/desci-server/src/services/crossRef/client.ts +++ b/desci-server/src/services/crossRef/client.ts @@ -100,7 +100,7 @@ class CrossRefClient { async performFetch(request: Request) { const responseFromCache = await getFromCache(request.url); - logger.info(responseFromCache, 'DOI From Cache'); + // logger.info(responseFromCache, 'DOI From Cache'); if (responseFromCache) return { ok: true, status: 200, data: responseFromCache }; const response = (await fetch(request)) as CrossRefHttpResponse; diff --git a/desci-server/src/services/crossRef/definitions.ts b/desci-server/src/services/crossRef/definitions.ts index 09f4c35c..49a2f2f1 100644 --- a/desci-server/src/services/crossRef/definitions.ts +++ b/desci-server/src/services/crossRef/definitions.ts @@ -26,7 +26,7 @@ export interface Work { author: Author[]; DOI: string; prefix: string; - title: string; + title: string[]; } export interface Author { @@ -38,14 +38,6 @@ export interface Author { authenticatedOrcid?: boolean; } -interface SearchQueryParams { - offset: number; - // mailto: string; - query: string; - filter?: string; - rows: number; -} - export interface QueryWorkParams { offset?: number; query?: string; diff --git a/desci-server/src/services/repoService.ts b/desci-server/src/services/repoService.ts index 0d82bd1a..2c9a7555 100644 --- a/desci-server/src/services/repoService.ts +++ b/desci-server/src/services/repoService.ts @@ -39,7 +39,7 @@ class RepoService { `${this.baseUrl}/v1/nodes/documents/dispatch`, arg, ); - logger.info({ arg, response: response.data }, 'Disatch Changes Response'); + logger.info({ arg, ok: response.data.ok }, 'Disatch Changes Response'); if (response.status === 200 && response.data.ok) { return response.data.document; } else { @@ -90,7 +90,7 @@ class RepoService { const response = await this.#client.get>( `${this.baseUrl}/v1/nodes/documents/draft/${arg.uuid}`, ); - logger.info({ response: response.data }, 'Draft Retrieval Response'); + logger.info({ response: response.status }, 'Draft Retrieval Response'); if (response.status === 200 && response.data.ok) { return response.data.document; } else { From 5e2fabd8e316fa4003828eb87017ea5e8d36a261 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Thu, 6 Jun 2024 11:21:45 +0200 Subject: [PATCH 076/278] suspend use of crossref plus token --- desci-server/src/services/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desci-server/src/services/index.ts b/desci-server/src/services/index.ts index 8c84dbfb..28aceb35 100644 --- a/desci-server/src/services/index.ts +++ b/desci-server/src/services/index.ts @@ -6,6 +6,6 @@ import { DoiService } from './Doi.js'; export const doiService = new DoiService(prisma); export const crossRefClient = new CrossRefClient( process.env.CROSSREF_API, - process.env.CROSSREF_API_KEY, + '', // process.env.CROSSREF_API_KEY, process.env.CROSSREF_EMAIL, ); From 6175bd3dde2a6cfc9281015742daab138f6674e8 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Thu, 6 Jun 2024 12:10:03 +0200 Subject: [PATCH 077/278] clean up --- desci-server/src/controllers/nodes/prepublish.ts | 4 ++-- desci-server/src/middleware/authorisation.ts | 6 +++--- desci-server/src/services/Doi.ts | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/desci-server/src/controllers/nodes/prepublish.ts b/desci-server/src/controllers/nodes/prepublish.ts index 56f7df86..4824f4d7 100644 --- a/desci-server/src/controllers/nodes/prepublish.ts +++ b/desci-server/src/controllers/nodes/prepublish.ts @@ -1,6 +1,6 @@ import { ResearchObjectV1 } from '@desci-labs/desci-models'; import { NodeVersion } from '@prisma/client'; -import { Response } from 'express'; +import { NextFunction, Response } from 'express'; import { prisma } from '../../client.js'; import { logger as parentLogger } from '../../logger.js'; @@ -30,7 +30,7 @@ export interface PrepublishErrorResponse { /** * DAGifies the drafts current DB tree state, adds the structure to IPFS (No Files Pinned, Folders staged), and updates the manifest data bucket CID. */ -export const prepublish = async (req: RequestWithNode, res: Response) => { +export const prepublish = async (req: RequestWithNode, res: Response, _next: NextFunction) => { const owner = req.user; const node = req.node; const { uuid } = req.body; diff --git a/desci-server/src/middleware/authorisation.ts b/desci-server/src/middleware/authorisation.ts index 55982ebc..c45b604a 100644 --- a/desci-server/src/middleware/authorisation.ts +++ b/desci-server/src/middleware/authorisation.ts @@ -46,8 +46,8 @@ export const ensureWriteNodeAccess = async (req: RequestWithUser, res: Response, return next(); }; -export const ensureNodeAccess = async (req: Request, res: Response, next: NextFunction) => { - const user = (req as RequestWithUser).user; +export const ensureNodeAccess = async (req: RequestWithUser, res: Response, next: NextFunction) => { + const user = req.user; const uuid = req.body?.uuid || req.query?.uuid || req.params?.uuid; const logger = parentLogger.child({ module: 'MIDDLEWARE::ensureNodeAccess', @@ -60,7 +60,7 @@ export const ensureNodeAccess = async (req: Request, res: Response, next: NextFu res.status(401).send({ ok: false, message: 'Unauthorized' }); return; } - (req as RequestWithUser).user = user; + req.user = user; if (!uuid) { logger.error({ uuid: req.body.uuid, body: req.body }, 'No UUID Found'); diff --git a/desci-server/src/services/Doi.ts b/desci-server/src/services/Doi.ts index 3013e863..b31c9191 100644 --- a/desci-server/src/services/Doi.ts +++ b/desci-server/src/services/Doi.ts @@ -24,7 +24,7 @@ export class DoiService { } async assertIsFirstDoi(dpid: string) { - const isFirstDoi = await this.isFirstDoi(dpid); // await this.dbClient.doiRecord.findUnique({ where: { doi } }); + const isFirstDoi = await this.isFirstDoi(dpid); if (!isFirstDoi) throw new DuplicateMintError(); } From 3e1216236f93f8ad8d4cbcd4ce41fb20eb8271db Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Thu, 6 Jun 2024 11:10:33 +0000 Subject: [PATCH 078/278] models cmodels changes, add upsert component automerge action --- desci-models/package.json | 4 ++-- desci-models/src/ResearchObject.ts | 2 +- desci-models/src/automerge.ts | 12 ++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/desci-models/package.json b/desci-models/package.json index d8cc13d9..e18c7f83 100644 --- a/desci-models/package.json +++ b/desci-models/package.json @@ -1,6 +1,6 @@ { "name": "@desci-labs/desci-models", - "version": "0.2.6-rc1", + "version": "0.2.7-rc1", "description": "Data models for DeSci Nodes", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -38,4 +38,4 @@ "ts-node": "^10.9.1", "typescript": "^4.9.4" } -} +} \ No newline at end of file diff --git a/desci-models/src/ResearchObject.ts b/desci-models/src/ResearchObject.ts index 66084c01..29b83796 100644 --- a/desci-models/src/ResearchObject.ts +++ b/desci-models/src/ResearchObject.ts @@ -92,7 +92,7 @@ export interface ResearchObjectV1Component { * Contributor listing for a research object. */ export interface ResearchObjectV1Author { - /** Random UUID to identify the contributor - optional for compatability with old models + /** Random UUID to identify the contributor - optional for compatibility with old models * Going forwards assignment is best practice. */ id?: string; diff --git a/desci-models/src/automerge.ts b/desci-models/src/automerge.ts index 618f92b7..19edf697 100644 --- a/desci-models/src/automerge.ts +++ b/desci-models/src/automerge.ts @@ -4,14 +4,14 @@ * multi-client application for editing the manifest. * * @package -*/ + */ import { ResearchObjectComponentTypeMap, ResearchObjectV1Author, ResearchObjectV1Component, - ResearchObjectV1Dpid -} from "./ResearchObject"; + ResearchObjectV1Dpid, +} from './ResearchObject'; export type ManifestActions = | { type: 'Add Components'; components: ResearchObjectV1Component[] } @@ -35,6 +35,7 @@ export type ManifestActions = | { type: 'Update License'; defaultLicense: string } | { type: 'Update ResearchFields'; researchFields: string[] } | { type: 'Add Component'; component: ResearchObjectV1Component } + | { type: 'Upsert Component'; component: ResearchObjectV1Component } | { type: 'Delete Component'; path: string } | { type: 'Add Contributor'; author: ResearchObjectV1Author } | { type: 'Remove Contributor'; contributorIndex: number } @@ -50,8 +51,7 @@ export type ManifestActions = dpid: ResearchObjectV1Dpid; } | { type: 'Remove Dpid' } - | - { - type: "Update CoverImage"; + | { + type: 'Update CoverImage'; cid: string | undefined; }; From f9c9c9f5f73b69d294f7e276e3e7ad44f96dea61 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Thu, 6 Jun 2024 11:11:43 +0000 Subject: [PATCH 079/278] add upsert component action functionality to repo --- desci-repo/package.json | 4 +- desci-repo/src/services/manifestRepo.ts | 68 ++++++++++++++----------- desci-repo/yarn.lock | 39 +++++++++++--- 3 files changed, 72 insertions(+), 39 deletions(-) diff --git a/desci-repo/package.json b/desci-repo/package.json index 88d744f7..a64fe9d4 100644 --- a/desci-repo/package.json +++ b/desci-repo/package.json @@ -68,7 +68,7 @@ "typescript": "5.1.6" }, "dependencies": { - "@desci-labs/desci-models": "^0.2.3-rc1", + "@desci-labs/desci-models": "0.2.7-rc1", "@sentry/node": "^7.84.0", "@sentry/tracing": "^7.84.0", "axios": "^1.6.2", @@ -87,4 +87,4 @@ "ws": "^8.14.2", "zod": "^3.22.4" } -} +} \ No newline at end of file diff --git a/desci-repo/src/services/manifestRepo.ts b/desci-repo/src/services/manifestRepo.ts index 7f8ae945..2e841282 100644 --- a/desci-repo/src/services/manifestRepo.ts +++ b/desci-repo/src/services/manifestRepo.ts @@ -31,7 +31,6 @@ export function assertNever(value: never) { throw Error('Not Possible'); } - export const getDocumentUpdater = (documentId: DocumentId) => { const automergeUrl = getAutomergeUrl(documentId); const handle = backendRepo.find(automergeUrl as AutomergeUrl); @@ -209,6 +208,14 @@ export const getDocumentUpdater = (documentId: DocumentId) => { { time: Date.now(), message: action.type }, ); break; + case 'Upsert Component': + handle.change( + (document) => { + upsertManifestComponent(document, action.component); + }, + { time: Date.now(), message: action.type }, + ); + break; case 'Publish Dpid': handle.change( (document) => { @@ -217,12 +224,12 @@ export const getDocumentUpdater = (documentId: DocumentId) => { { time: Date.now(), message: action.type }, ); break; - case "Remove Dpid": + case 'Remove Dpid': handle.change( (document) => { removeDpid(document); }, - { time: Date.now(), message: action.type } + { time: Date.now(), message: action.type }, ); break; case 'Pin Component': @@ -294,9 +301,7 @@ const updateComponentTypeMap = ( path: string, compTypeMap: ResearchObjectComponentTypeMap, ): void => { - const currentComponent = doc.manifest.components.find( - (c) => c.payload?.path === path - ); + const currentComponent = doc.manifest.components.find((c) => c.payload?.path === path); if (!currentComponent) return; const existingType = currentComponent.type; @@ -316,45 +321,29 @@ const updateComponentTypeMap = ( }); }; -const addManifestComponent = ( - doc: Doc, - component: ResearchObjectV1Component -): void => { +const addManifestComponent = (doc: Doc, component: ResearchObjectV1Component): void => { doc.manifest.components.push(component); }; -const deleteComponent = ( - doc: Doc, - path: string -): void => { - const deleteIdx = doc.manifest.components.findIndex( - (component) => component?.payload?.path === path - ); +const deleteComponent = (doc: Doc, path: string): void => { + const deleteIdx = doc.manifest.components.findIndex((component) => component?.payload?.path === path); if (deleteIdx !== -1) doc.manifest.components.splice(deleteIdx, 1); }; -const togglePin = ( - doc: Doc, - componentIndex: number, pin: boolean -): void => { +const togglePin = (doc: Doc, componentIndex: number, pin: boolean): void => { const currentComponent = doc.manifest.components[componentIndex]; currentComponent.starred = pin; }; -const addDpid = ( - doc: Doc, - dpid: ResearchObjectV1Dpid -): void => { +const addDpid = (doc: Doc, dpid: ResearchObjectV1Dpid): void => { if (doc.manifest.dpid) return; doc.manifest.dpid = dpid; }; -/** In an unavilable optimistic dPID was written to the manifest, it must +/** In an unavailable optimistic dPID was written to the manifest, it must * be removed again. -*/ -const removeDpid = ( - doc: Doc -): void => { + */ +const removeDpid = (doc: Doc): void => { delete doc.manifest.dpid; }; @@ -415,6 +404,25 @@ const updateManifestComponent = ( } }; +const upsertManifestComponent = (doc: Doc, component: ResearchObjectV1Component): void => { + // Check for existing component + const existingComponentIndex = doc.manifest.components.findIndex( + (c) => c.id === component.id || c.payload?.path === component.payload?.path, + ); + // Apply changess + if (existingComponentIndex !== -1) { + const existingComponent = doc.manifest.components[existingComponentIndex]; + doc.manifest.components[existingComponentIndex] = { + ...existingComponent, + ...component, + payload: { ...existingComponent.payload, ...component.payload }, + }; + } else { + // Push the component + doc.manifest.components.push(component); + } +}; + type TypeInitialisers = {} | '' | 0 | []; const getTypeDefault = (value: unknown): TypeInitialisers => { diff --git a/desci-repo/yarn.lock b/desci-repo/yarn.lock index cd6974ac..b946d2ed 100644 --- a/desci-repo/yarn.lock +++ b/desci-repo/yarn.lock @@ -131,10 +131,10 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@desci-labs/desci-models@^0.2.3-rc1": - version "0.2.3-rc1" - resolved "https://registry.yarnpkg.com/@desci-labs/desci-models/-/desci-models-0.2.3-rc1.tgz#9583455b59966d9e50bae1c2e2c6701e529e3990" - integrity sha512-FW74CkgfZTNhky0Q6Sk3lCoBZ+Yl5D4KVTTLBv/NG+e8qH9jyT6DVbiXvaThQWZQNulFXJg2UFZm73AVInu3wA== +"@desci-labs/desci-models@^0.2.7": + version "0.2.6-rc1" + resolved "https://registry.yarnpkg.com/@desci-labs/desci-models/-/desci-models-0.2.6-rc1.tgz#aa85ff6ef50985435f68d6674d10fcb70d345f99" + integrity sha512-NrZQ7InitPPSqrSmf85TjAXfss4gfVN5tHJe21YPGZhK5dwyFbMrYCP8atqELA+gaCGaNi+9KH+iEIDpMprM3Q== dependencies: jsonld "^8.1.1" schema-dts "^1.1.2" @@ -3920,7 +3920,16 @@ string-argv@0.3.1: resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0: +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.1.0, string-width@^4.2.0: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -3990,7 +3999,14 @@ stringify-object@^3.3.0: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -4385,7 +4401,7 @@ workerpool@6.2.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -4403,6 +4419,15 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" From c064d9ae1d5dccbecc4faad9bfd47d959321a6c5 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Thu, 6 Jun 2024 13:36:21 +0200 Subject: [PATCH 080/278] run db migrations and test interactions --- .../migration.sql | 18 ++++++++++++++++++ .../src/controllers/attestations/claims.ts | 1 + 2 files changed, 19 insertions(+) create mode 100644 desci-server/prisma/migrations/20240606113003_add_more_action_types/migration.sql diff --git a/desci-server/prisma/migrations/20240606113003_add_more_action_types/migration.sql b/desci-server/prisma/migrations/20240606113003_add_more_action_types/migration.sql new file mode 100644 index 00000000..df9c940a --- /dev/null +++ b/desci-server/prisma/migrations/20240606113003_add_more_action_types/migration.sql @@ -0,0 +1,18 @@ +-- AlterEnum +-- This migration adds more than one value to an enum. +-- With PostgreSQL versions 11 and earlier, this is not possible +-- in a single migration. This can be worked around by creating +-- multiple migrations, each migration adding only one value to +-- the enum. + + +ALTER TYPE "ActionType" ADD VALUE 'CLAIM_ATTESTATION'; +ALTER TYPE "ActionType" ADD VALUE 'REVOKE_CLAIM'; +ALTER TYPE "ActionType" ADD VALUE 'CLAIM_ENTRY_ATTESTATIONS'; +ALTER TYPE "ActionType" ADD VALUE 'ADD_COMMENT'; +ALTER TYPE "ActionType" ADD VALUE 'REMOVE_COMMENT'; +ALTER TYPE "ActionType" ADD VALUE 'VERIFY_ATTESTATION'; +ALTER TYPE "ActionType" ADD VALUE 'UNVERIFY_ATTESTATION'; +ALTER TYPE "ActionType" ADD VALUE 'UPDATE_ORCID_RECORD'; +ALTER TYPE "ActionType" ADD VALUE 'REMOVE_ORCID_WORK_RECORD'; +ALTER TYPE "ActionType" ADD VALUE 'ORCID_API_ERROR'; diff --git a/desci-server/src/controllers/attestations/claims.ts b/desci-server/src/controllers/attestations/claims.ts index f790dbb6..d885b2e2 100644 --- a/desci-server/src/controllers/attestations/claims.ts +++ b/desci-server/src/controllers/attestations/claims.ts @@ -43,6 +43,7 @@ export const claimAttestation = async (req: RequestWithUser, res: Response, _nex if (claim && claim.revoked) { const reclaimed = await attestationService.reClaimAttestation(claim.id); + await saveInteraction(req, ActionType.CLAIM_ATTESTATION, { ...body, claimId: reclaimed.id }); new SuccessResponse(reclaimed).send(res); return; } From 56b0c34be6bb44275a7783902a403e9a1a7e878d Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Thu, 6 Jun 2024 11:48:12 +0000 Subject: [PATCH 081/278] model version bump --- desci-models/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desci-models/package.json b/desci-models/package.json index e18c7f83..70560586 100644 --- a/desci-models/package.json +++ b/desci-models/package.json @@ -1,6 +1,6 @@ { "name": "@desci-labs/desci-models", - "version": "0.2.7-rc1", + "version": "0.2.7-rc1.5", "description": "Data models for DeSci Nodes", "main": "dist/index.js", "types": "dist/index.d.ts", From cee3436743c5e854816c0dcac57da8ff49fdc027 Mon Sep 17 00:00:00 2001 From: Shadrach Temitayo Date: Thu, 6 Jun 2024 15:23:33 +0200 Subject: [PATCH 082/278] Revert "Track more User Actions" --- .../migration.sql | 18 --- desci-server/prisma/schema.prisma | 10 -- .../src/controllers/attestations/claims.ts | 16 +-- .../src/controllers/attestations/comments.ts | 11 +- .../controllers/attestations/verification.ts | 14 +-- desci-server/src/services/orcid.ts | 105 +++++------------- 6 files changed, 31 insertions(+), 143 deletions(-) delete mode 100644 desci-server/prisma/migrations/20240606113003_add_more_action_types/migration.sql diff --git a/desci-server/prisma/migrations/20240606113003_add_more_action_types/migration.sql b/desci-server/prisma/migrations/20240606113003_add_more_action_types/migration.sql deleted file mode 100644 index df9c940a..00000000 --- a/desci-server/prisma/migrations/20240606113003_add_more_action_types/migration.sql +++ /dev/null @@ -1,18 +0,0 @@ --- AlterEnum --- This migration adds more than one value to an enum. --- With PostgreSQL versions 11 and earlier, this is not possible --- in a single migration. This can be worked around by creating --- multiple migrations, each migration adding only one value to --- the enum. - - -ALTER TYPE "ActionType" ADD VALUE 'CLAIM_ATTESTATION'; -ALTER TYPE "ActionType" ADD VALUE 'REVOKE_CLAIM'; -ALTER TYPE "ActionType" ADD VALUE 'CLAIM_ENTRY_ATTESTATIONS'; -ALTER TYPE "ActionType" ADD VALUE 'ADD_COMMENT'; -ALTER TYPE "ActionType" ADD VALUE 'REMOVE_COMMENT'; -ALTER TYPE "ActionType" ADD VALUE 'VERIFY_ATTESTATION'; -ALTER TYPE "ActionType" ADD VALUE 'UNVERIFY_ATTESTATION'; -ALTER TYPE "ActionType" ADD VALUE 'UPDATE_ORCID_RECORD'; -ALTER TYPE "ActionType" ADD VALUE 'REMOVE_ORCID_WORK_RECORD'; -ALTER TYPE "ActionType" ADD VALUE 'ORCID_API_ERROR'; diff --git a/desci-server/prisma/schema.prisma b/desci-server/prisma/schema.prisma index 6902f2bc..8da1292b 100755 --- a/desci-server/prisma/schema.prisma +++ b/desci-server/prisma/schema.prisma @@ -880,16 +880,6 @@ enum ActionType { NEW_REFERRAL ACCEPTED_REFERRAL USER_PUBLISH_CONSENT - CLAIM_ATTESTATION - REVOKE_CLAIM - CLAIM_ENTRY_ATTESTATIONS - ADD_COMMENT - REMOVE_COMMENT - VERIFY_ATTESTATION - UNVERIFY_ATTESTATION - UPDATE_ORCID_RECORD - REMOVE_ORCID_WORK_RECORD - ORCID_API_ERROR } enum ChainTransactionType { diff --git a/desci-server/src/controllers/attestations/claims.ts b/desci-server/src/controllers/attestations/claims.ts index d885b2e2..d499fc35 100644 --- a/desci-server/src/controllers/attestations/claims.ts +++ b/desci-server/src/controllers/attestations/claims.ts @@ -1,4 +1,4 @@ -import { ActionType, CommunityEntryAttestation } from '@prisma/client'; +import { CommunityEntryAttestation } from '@prisma/client'; import sgMail from '@sendgrid/mail'; import { NextFunction, Request, Response } from 'express'; import _ from 'lodash'; @@ -16,7 +16,6 @@ import { } from '../../internal.js'; import { RequestWithUser } from '../../middleware/authorisation.js'; import { removeClaimSchema } from '../../routes/v1/attestations/schema.js'; -import { saveInteraction } from '../../services/interactionLog.js'; import { AttestationClaimedEmailHtml } from '../../templates/emails/utils/emailRenderer.js'; sgMail.setApiKey(process.env.SENDGRID_API_KEY); @@ -43,7 +42,6 @@ export const claimAttestation = async (req: RequestWithUser, res: Response, _nex if (claim && claim.revoked) { const reclaimed = await attestationService.reClaimAttestation(claim.id); - await saveInteraction(req, ActionType.CLAIM_ATTESTATION, { ...body, claimId: reclaimed.id }); new SuccessResponse(reclaimed).send(res); return; } @@ -54,7 +52,7 @@ export const claimAttestation = async (req: RequestWithUser, res: Response, _nex nodeUuid: uuid, attestationVersion: attestationVersion.id, }); - await saveInteraction(req, ActionType.CLAIM_ATTESTATION, { ...body, claimId: nodeClaim.id }); + // notifiy community members if attestation is protected // new attestations should be trigger notification of org members if protected const attestation = await attestationService.findAttestationById(body.attestationId); @@ -116,10 +114,8 @@ export const removeClaim = async (req: RequestWithUser, res: Response, _next: Ne ? await attestationService.revokeAttestation(claim.id) : await attestationService.unClaimAttestation(claim.id); - await saveInteraction(req, ActionType.REVOKE_CLAIM, body); - logger.info({ removeOrRevoke, totalSignal, claimSignal }, 'Claim Removed|Revoked'); - new SuccessMessageResponse('Attestation unclaimed').send(res); + return new SuccessMessageResponse('Attestation unclaimed').send(res); }; export const claimEntryRequirements = async (req: Request, res: Response, _next: NextFunction) => { @@ -172,11 +168,5 @@ export const claimEntryRequirements = async (req: Request, res: Response, _next: attestations: claims, }); - await saveInteraction(req, ActionType.CLAIM_ENTRY_ATTESTATIONS, { - communityId, - nodeDpid, - claimerId, - claims: attestations.map((att) => att.id), - }); return new SuccessResponse(attestations).send(res); }; diff --git a/desci-server/src/controllers/attestations/comments.ts b/desci-server/src/controllers/attestations/comments.ts index 7949fe8c..8f7b3ac5 100644 --- a/desci-server/src/controllers/attestations/comments.ts +++ b/desci-server/src/controllers/attestations/comments.ts @@ -1,5 +1,5 @@ import { HighlightBlock } from '@desci-labs/desci-models'; -import { ActionType, Annotation } from '@prisma/client'; +import { Annotation } from '@prisma/client'; import { NextFunction, Request, Response } from 'express'; import _ from 'lodash'; import zod from 'zod'; @@ -15,7 +15,6 @@ import { createCommentSchema, logger as parentLogger, } from '../../internal.js'; -import { saveInteraction } from '../../services/interactionLog.js'; import { client } from '../../services/ipfs.js'; import { base64ToBlob } from '../../utils/upload.js'; @@ -65,12 +64,6 @@ export const removeComment = async (req: Request, r } else { if (comment.authorId !== user.id) throw new ForbiddenError(); await attestationService.removeComment(parseInt(commentId)); - await saveInteraction(req, ActionType.REMOVE_COMMENT, { - commentId, - claimId: comment.nodeAttestationId, - authorId: comment.authorId, - userId: user.id, - }); new SuccessMessageResponse().send(res); } }; @@ -108,7 +101,6 @@ export const addComment = async (req: Request, links, highlights: processedHighlights as unknown as HighlightBlock[], }); - await saveInteraction(req, ActionType.ADD_COMMENT, { annotationId: annotation.id, claimId, authorId }); } else { annotation = await attestationService.createComment({ claimId: parseInt(claimId.toString()), @@ -116,7 +108,6 @@ export const addComment = async (req: Request, comment: body, links, }); - await saveInteraction(req, ActionType.ADD_COMMENT, { annotationId: annotation.id, claimId, authorId }); } new SuccessResponse({ diff --git a/desci-server/src/controllers/attestations/verification.ts b/desci-server/src/controllers/attestations/verification.ts index 05d4ce4d..f2c2b425 100644 --- a/desci-server/src/controllers/attestations/verification.ts +++ b/desci-server/src/controllers/attestations/verification.ts @@ -1,4 +1,3 @@ -import { ActionType } from '@prisma/client'; import { NextFunction, Request, Response } from 'express'; // import { Attestation, NodeAttestation } from '@prisma/client'; import _ from 'lodash'; @@ -12,7 +11,6 @@ import { prisma, } from '../../internal.js'; import { logger as parentLogger } from '../../logger.js'; -import { saveInteraction, saveInteractionWithoutReq } from '../../services/interactionLog.js'; import orcidApiService from '../../services/orcid.js'; type RemoveVerificationBody = { @@ -48,10 +46,7 @@ export const removeVerification = async ( new SuccessMessageResponse().send(res); } else { await attestationService.removeVerification(verification.id, user.id); - await saveInteraction(req, ActionType.UNVERIFY_ATTESTATION, { - claimId: verification.nodeAttestationId, - userId: user.id, - }); + new SuccessMessageResponse().send(res); const claim = await attestationService.findClaimById(verification.nodeAttestationId); @@ -96,7 +91,6 @@ export const addVerification = async ( const claim = await attestationService.findClaimById(parseInt(claimId)); await attestationService.verifyClaim(parseInt(claimId), user.id); - await saveInteraction(req, ActionType.VERIFY_ATTESTATION, { claimId: claimId, userId: user.id }); const attestation = await attestationService.findAttestationById(claim.attestationId); @@ -109,12 +103,6 @@ export const addVerification = async ( const node = await prisma.node.findFirst({ where: { uuid: ensureUuidEndsWithDot(claim.nodeUuid) } }); const owner = await prisma.user.findFirst({ where: { id: node.ownerId } }); if (owner.orcid) await orcidApiService.postWorkRecord(node.uuid, owner.orcid); - await saveInteractionWithoutReq(ActionType.UPDATE_ORCID_RECORD, { - ownerId: owner.id, - orcid: owner.orcid, - uuid: node.uuid, - claimId, - }); } }; diff --git a/desci-server/src/services/orcid.ts b/desci-server/src/services/orcid.ts index 529b00d9..05a1cd19 100644 --- a/desci-server/src/services/orcid.ts +++ b/desci-server/src/services/orcid.ts @@ -1,5 +1,5 @@ import { ResearchObjectV1, ResearchObjectV1Author } from '@desci-labs/desci-models'; -import { ActionType, AuthTokenSource, ORCIDRecord, OrcidPutCodes, PutcodeReference } from '@prisma/client'; +import { AuthTokenSource, ORCIDRecord, OrcidPutCodes, PutcodeReference } from '@prisma/client'; import { logger as parentLogger, prisma } from '../internal.js'; import { IndexedResearchObject, getIndexedResearchObjects } from '../theGraph.js'; @@ -7,7 +7,6 @@ import { hexToCid } from '../utils.js'; import { attestationService } from './Attestation.js'; import { getManifestByCid } from './data/processing.js'; -import { saveInteractionWithoutReq } from './interactionLog.js'; // const PUTCODE_REGEX = /put-code=.*?(?\d+)/m; @@ -187,7 +186,6 @@ class OrcidApiService { }, 'ORCID API DELETE RECORD', ); - // todo: simulate an error case and handle properly const response = await fetch(url, { method: 'DELETE', headers: { @@ -198,38 +196,24 @@ class OrcidApiService { }, }); - if (response.ok) { - await saveInteractionWithoutReq(ActionType.REMOVE_ORCID_WORK_RECORD, { - orcid, - }); - - await prisma.orcidPutCodes.delete({ - where: { - id: putCode.id, - }, - }); + await prisma.orcidPutCodes.delete({ + where: { + id: putCode.id, + }, + }); - logger.info( - { - status: response.status, - statusText: response.statusText, - orcid, - putCode: { - code: putCode.putcode, - reference: putCode.reference, - }, - }, - 'ORCID RECORD DELETED', - ); - } else { - await saveInteractionWithoutReq(ActionType.ORCID_API_ERROR, { - orcid, - putCode, + logger.info( + { status: response.status, - error: await response.json(), - }); - logger.error({ orcid, putCode, status: response.status }, 'Error: REMOVE ORCID WORK RECORD'); - } + statusText: response.statusText, + orcid, + putCode: { + code: putCode.putcode, + reference: putCode.reference, + }, + }, + 'ORCID RECORD DELETED', + ); } /** @@ -386,35 +370,17 @@ class OrcidApiService { }, }); } - await saveInteractionWithoutReq(ActionType.UPDATE_ORCID_RECORD, { - userId, - orcid, - uuid, - putCode: returnedCode, - }); - logger.info( { uuid, userId, status: response.status, returnedCode, reference: PutcodeReference.PREPRINT }, '[ORCID_API_SERVICE]:: Node Record UPDATED', ); } else { - const body = await response.text(); - await saveInteractionWithoutReq(ActionType.ORCID_API_ERROR, { - userId, - orcid, - uuid, - statusCode: response.status, - error: body, - }); - logger.info({ status: response.status, response, body }, '[ORCID_API_SERVICE]::ORCID NODE API ERROR'); + logger.info( + { status: response.status, response, body: await response.text() }, + '[ORCID_API_SERVICE]::ORCID NODE API ERROR', + ); } } catch (err) { - await saveInteractionWithoutReq(ActionType.ORCID_API_ERROR, { - userId, - orcid, - uuid, - error: err, - }); logger.info({ err }, '[ORCID_API_SERVICE]::NODE API Error Response'); } } @@ -507,6 +473,7 @@ class OrcidApiService { if ([200, 201].includes(response.status)) { const location = response.headers.get('Location')?.split('/'); const returnedCode = location?.[location.length - 1]; + // response.headers.forEach((header, key) => logger.info({ key, header }, 'Response header')); logger.info({ location }, 'RESPONSE HEADER Location'); if (returnedCode) { @@ -528,39 +495,19 @@ class OrcidApiService { }, }); } - await saveInteractionWithoutReq(ActionType.UPDATE_ORCID_RECORD, { - userId, - orcid, - uuid, - claimId: claim.id, - putCode: returnedCode, - }); logger.info( { uuid, claimId: claim.id, userId, status: response.status, returnedCode, reference: putCodeReference }, 'ORCID CLAIM RECORD UPDATED', ); } else { - const body = await response.text(); - await saveInteractionWithoutReq(ActionType.ORCID_API_ERROR, { - userId, - orcid, - uuid, - claimId: claim.id, - statusCode: response.status, - error: body, - }); - logger.info({ status: response.status, response, body }, '[ORCID_API_SERVICE]::ORCID CLAIM API ERROR'); + logger.info( + { status: response.status, response, body: await response.text() }, + '[ORCID_API_SERVICE]::ORCID CLAIM API ERROR', + ); } } catch (err) { logger.info({ err }, '[ORCID_API_SERVICE]::CLAIM API Error Response'); - await saveInteractionWithoutReq(ActionType.ORCID_API_ERROR, { - userId, - orcid, - uuid, - claimId: claim.id, - error: err, - }); } } } From 4b11e9ea08bcc09f01d4b56d65458f4e37df1140 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Thu, 6 Jun 2024 15:57:37 +0200 Subject: [PATCH 083/278] split enum changes into separate migrations --- .../migration.sql | 2 ++ .../20240606134308_add_revoke_claim_action_type/migration.sql | 2 ++ .../migration.sql | 2 ++ .../20240606134406_add_comment_action_type/migration.sql | 2 ++ .../20240606134439_remove_comment_action_type/migration.sql | 2 ++ .../migration.sql | 2 ++ .../migration.sql | 2 ++ .../migration.sql | 2 ++ .../migration.sql | 2 ++ .../migration.sql | 2 ++ desci-server/src/utils/draftTreeUtils.ts | 4 ++-- 11 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 desci-server/prisma/migrations/20240606134228_add_claim_attestation_action_type/migration.sql create mode 100644 desci-server/prisma/migrations/20240606134308_add_revoke_claim_action_type/migration.sql create mode 100644 desci-server/prisma/migrations/20240606134336_add_claim_entry_attestations_action_type/migration.sql create mode 100644 desci-server/prisma/migrations/20240606134406_add_comment_action_type/migration.sql create mode 100644 desci-server/prisma/migrations/20240606134439_remove_comment_action_type/migration.sql create mode 100644 desci-server/prisma/migrations/20240606134558_add_verify_attestation_action_type/migration.sql create mode 100644 desci-server/prisma/migrations/20240606134622_add_unverify_attestation_action_type/migration.sql create mode 100644 desci-server/prisma/migrations/20240606134643_add_update_orcid_record_action_type/migration.sql create mode 100644 desci-server/prisma/migrations/20240606134717_add_remove_orcid_work_record_action_type/migration.sql create mode 100644 desci-server/prisma/migrations/20240606134743_add_orcid_api_error_action_type/migration.sql diff --git a/desci-server/prisma/migrations/20240606134228_add_claim_attestation_action_type/migration.sql b/desci-server/prisma/migrations/20240606134228_add_claim_attestation_action_type/migration.sql new file mode 100644 index 00000000..caf1df15 --- /dev/null +++ b/desci-server/prisma/migrations/20240606134228_add_claim_attestation_action_type/migration.sql @@ -0,0 +1,2 @@ +-- AlterEnum +ALTER TYPE "ActionType" ADD VALUE 'CLAIM_ATTESTATION'; diff --git a/desci-server/prisma/migrations/20240606134308_add_revoke_claim_action_type/migration.sql b/desci-server/prisma/migrations/20240606134308_add_revoke_claim_action_type/migration.sql new file mode 100644 index 00000000..5d7f583c --- /dev/null +++ b/desci-server/prisma/migrations/20240606134308_add_revoke_claim_action_type/migration.sql @@ -0,0 +1,2 @@ +-- AlterEnum +ALTER TYPE "ActionType" ADD VALUE 'REVOKE_CLAIM'; diff --git a/desci-server/prisma/migrations/20240606134336_add_claim_entry_attestations_action_type/migration.sql b/desci-server/prisma/migrations/20240606134336_add_claim_entry_attestations_action_type/migration.sql new file mode 100644 index 00000000..fe813c54 --- /dev/null +++ b/desci-server/prisma/migrations/20240606134336_add_claim_entry_attestations_action_type/migration.sql @@ -0,0 +1,2 @@ +-- AlterEnum +ALTER TYPE "ActionType" ADD VALUE 'CLAIM_ENTRY_ATTESTATIONS'; diff --git a/desci-server/prisma/migrations/20240606134406_add_comment_action_type/migration.sql b/desci-server/prisma/migrations/20240606134406_add_comment_action_type/migration.sql new file mode 100644 index 00000000..e7826777 --- /dev/null +++ b/desci-server/prisma/migrations/20240606134406_add_comment_action_type/migration.sql @@ -0,0 +1,2 @@ +-- AlterEnum +ALTER TYPE "ActionType" ADD VALUE 'ADD_COMMENT'; diff --git a/desci-server/prisma/migrations/20240606134439_remove_comment_action_type/migration.sql b/desci-server/prisma/migrations/20240606134439_remove_comment_action_type/migration.sql new file mode 100644 index 00000000..4f61893a --- /dev/null +++ b/desci-server/prisma/migrations/20240606134439_remove_comment_action_type/migration.sql @@ -0,0 +1,2 @@ +-- AlterEnum +ALTER TYPE "ActionType" ADD VALUE 'REMOVE_COMMENT'; diff --git a/desci-server/prisma/migrations/20240606134558_add_verify_attestation_action_type/migration.sql b/desci-server/prisma/migrations/20240606134558_add_verify_attestation_action_type/migration.sql new file mode 100644 index 00000000..a5d15900 --- /dev/null +++ b/desci-server/prisma/migrations/20240606134558_add_verify_attestation_action_type/migration.sql @@ -0,0 +1,2 @@ +-- AlterEnum +ALTER TYPE "ActionType" ADD VALUE 'VERIFY_ATTESTATION'; diff --git a/desci-server/prisma/migrations/20240606134622_add_unverify_attestation_action_type/migration.sql b/desci-server/prisma/migrations/20240606134622_add_unverify_attestation_action_type/migration.sql new file mode 100644 index 00000000..4c8f25e2 --- /dev/null +++ b/desci-server/prisma/migrations/20240606134622_add_unverify_attestation_action_type/migration.sql @@ -0,0 +1,2 @@ +-- AlterEnum +ALTER TYPE "ActionType" ADD VALUE 'UNVERIFY_ATTESTATION'; diff --git a/desci-server/prisma/migrations/20240606134643_add_update_orcid_record_action_type/migration.sql b/desci-server/prisma/migrations/20240606134643_add_update_orcid_record_action_type/migration.sql new file mode 100644 index 00000000..a722fc93 --- /dev/null +++ b/desci-server/prisma/migrations/20240606134643_add_update_orcid_record_action_type/migration.sql @@ -0,0 +1,2 @@ +-- AlterEnum +ALTER TYPE "ActionType" ADD VALUE 'UPDATE_ORCID_RECORD'; diff --git a/desci-server/prisma/migrations/20240606134717_add_remove_orcid_work_record_action_type/migration.sql b/desci-server/prisma/migrations/20240606134717_add_remove_orcid_work_record_action_type/migration.sql new file mode 100644 index 00000000..767e640c --- /dev/null +++ b/desci-server/prisma/migrations/20240606134717_add_remove_orcid_work_record_action_type/migration.sql @@ -0,0 +1,2 @@ +-- AlterEnum +ALTER TYPE "ActionType" ADD VALUE 'REMOVE_ORCID_WORK_RECORD'; diff --git a/desci-server/prisma/migrations/20240606134743_add_orcid_api_error_action_type/migration.sql b/desci-server/prisma/migrations/20240606134743_add_orcid_api_error_action_type/migration.sql new file mode 100644 index 00000000..896bba4d --- /dev/null +++ b/desci-server/prisma/migrations/20240606134743_add_orcid_api_error_action_type/migration.sql @@ -0,0 +1,2 @@ +-- AlterEnum +ALTER TYPE "ActionType" ADD VALUE 'ORCID_API_ERROR'; diff --git a/desci-server/src/utils/draftTreeUtils.ts b/desci-server/src/utils/draftTreeUtils.ts index 0cdd055b..c99e7184 100644 --- a/desci-server/src/utils/draftTreeUtils.ts +++ b/desci-server/src/utils/draftTreeUtils.ts @@ -9,12 +9,12 @@ import { } from '@desci-labs/desci-models'; import { createLink, createNode, encode, prepare, type PBLink } from '@ipld/dag-pb'; import { DraftNodeTree, Node, Prisma, User } from '@prisma/client'; -import { UnixFS }from 'ipfs-unixfs'; +import { UnixFS } from 'ipfs-unixfs'; +import { CID } from 'multiformats'; import { prisma } from '../client.js'; import { logger as parentLogger } from '../logger.js'; import { client } from '../services/ipfs.js'; -import { CID } from 'multiformats'; const logger = parentLogger.child({ module: 'Utils::DraftTreeUtils', From e2ef95c160ca96300b63041b8719a0323cc3c0c7 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Thu, 6 Jun 2024 16:21:40 +0200 Subject: [PATCH 084/278] restore updates --- desci-server/prisma/schema.prisma | 10 ++ .../src/controllers/attestations/claims.ts | 15 ++- .../src/controllers/attestations/comments.ts | 12 ++- .../controllers/attestations/verification.ts | 17 ++- desci-server/src/services/orcid.ts | 102 +++++++++++++----- 5 files changed, 126 insertions(+), 30 deletions(-) diff --git a/desci-server/prisma/schema.prisma b/desci-server/prisma/schema.prisma index 8da1292b..6902f2bc 100755 --- a/desci-server/prisma/schema.prisma +++ b/desci-server/prisma/schema.prisma @@ -880,6 +880,16 @@ enum ActionType { NEW_REFERRAL ACCEPTED_REFERRAL USER_PUBLISH_CONSENT + CLAIM_ATTESTATION + REVOKE_CLAIM + CLAIM_ENTRY_ATTESTATIONS + ADD_COMMENT + REMOVE_COMMENT + VERIFY_ATTESTATION + UNVERIFY_ATTESTATION + UPDATE_ORCID_RECORD + REMOVE_ORCID_WORK_RECORD + ORCID_API_ERROR } enum ChainTransactionType { diff --git a/desci-server/src/controllers/attestations/claims.ts b/desci-server/src/controllers/attestations/claims.ts index d499fc35..58e5c782 100644 --- a/desci-server/src/controllers/attestations/claims.ts +++ b/desci-server/src/controllers/attestations/claims.ts @@ -1,4 +1,4 @@ -import { CommunityEntryAttestation } from '@prisma/client'; +import { ActionType, CommunityEntryAttestation } from '@prisma/client'; import sgMail from '@sendgrid/mail'; import { NextFunction, Request, Response } from 'express'; import _ from 'lodash'; @@ -16,6 +16,7 @@ import { } from '../../internal.js'; import { RequestWithUser } from '../../middleware/authorisation.js'; import { removeClaimSchema } from '../../routes/v1/attestations/schema.js'; +import { saveInteraction } from '../../services/interactionLog.js'; import { AttestationClaimedEmailHtml } from '../../templates/emails/utils/emailRenderer.js'; sgMail.setApiKey(process.env.SENDGRID_API_KEY); @@ -42,6 +43,7 @@ export const claimAttestation = async (req: RequestWithUser, res: Response, _nex if (claim && claim.revoked) { const reclaimed = await attestationService.reClaimAttestation(claim.id); + await saveInteraction(req, ActionType.CLAIM_ATTESTATION, { ...body, claimId: reclaimed.id }); new SuccessResponse(reclaimed).send(res); return; } @@ -53,6 +55,8 @@ export const claimAttestation = async (req: RequestWithUser, res: Response, _nex attestationVersion: attestationVersion.id, }); + await saveInteraction(req, ActionType.CLAIM_ATTESTATION, { ...body, claimId: nodeClaim.id }); + // notifiy community members if attestation is protected // new attestations should be trigger notification of org members if protected const attestation = await attestationService.findAttestationById(body.attestationId); @@ -114,6 +118,8 @@ export const removeClaim = async (req: RequestWithUser, res: Response, _next: Ne ? await attestationService.revokeAttestation(claim.id) : await attestationService.unClaimAttestation(claim.id); + await saveInteraction(req, ActionType.REVOKE_CLAIM, body); + logger.info({ removeOrRevoke, totalSignal, claimSignal }, 'Claim Removed|Revoked'); return new SuccessMessageResponse('Attestation unclaimed').send(res); }; @@ -168,5 +174,12 @@ export const claimEntryRequirements = async (req: Request, res: Response, _next: attestations: claims, }); + await saveInteraction(req, ActionType.CLAIM_ENTRY_ATTESTATIONS, { + communityId, + nodeDpid, + claimerId, + claims: attestations.map((att) => att.id), + }); + return new SuccessResponse(attestations).send(res); }; diff --git a/desci-server/src/controllers/attestations/comments.ts b/desci-server/src/controllers/attestations/comments.ts index 8f7b3ac5..aebdd6e8 100644 --- a/desci-server/src/controllers/attestations/comments.ts +++ b/desci-server/src/controllers/attestations/comments.ts @@ -1,5 +1,5 @@ import { HighlightBlock } from '@desci-labs/desci-models'; -import { Annotation } from '@prisma/client'; +import { ActionType, Annotation } from '@prisma/client'; import { NextFunction, Request, Response } from 'express'; import _ from 'lodash'; import zod from 'zod'; @@ -15,6 +15,7 @@ import { createCommentSchema, logger as parentLogger, } from '../../internal.js'; +import { saveInteraction } from '../../services/interactionLog.js'; import { client } from '../../services/ipfs.js'; import { base64ToBlob } from '../../utils/upload.js'; @@ -64,6 +65,12 @@ export const removeComment = async (req: Request, r } else { if (comment.authorId !== user.id) throw new ForbiddenError(); await attestationService.removeComment(parseInt(commentId)); + await saveInteraction(req, ActionType.REMOVE_COMMENT, { + commentId, + claimId: comment.nodeAttestationId, + authorId: comment.authorId, + userId: user.id, + }); new SuccessMessageResponse().send(res); } }; @@ -101,6 +108,7 @@ export const addComment = async (req: Request, links, highlights: processedHighlights as unknown as HighlightBlock[], }); + await saveInteraction(req, ActionType.ADD_COMMENT, { annotationId: annotation.id, claimId, authorId }); } else { annotation = await attestationService.createComment({ claimId: parseInt(claimId.toString()), @@ -109,7 +117,7 @@ export const addComment = async (req: Request, links, }); } - + await saveInteraction(req, ActionType.ADD_COMMENT, { annotationId: annotation.id, claimId, authorId }); new SuccessResponse({ ...annotation, highlights: annotation.highlights.map((h) => JSON.parse(h as string)), diff --git a/desci-server/src/controllers/attestations/verification.ts b/desci-server/src/controllers/attestations/verification.ts index f2c2b425..48ce36b2 100644 --- a/desci-server/src/controllers/attestations/verification.ts +++ b/desci-server/src/controllers/attestations/verification.ts @@ -1,3 +1,4 @@ +import { ActionType } from '@prisma/client'; import { NextFunction, Request, Response } from 'express'; // import { Attestation, NodeAttestation } from '@prisma/client'; import _ from 'lodash'; @@ -11,6 +12,7 @@ import { prisma, } from '../../internal.js'; import { logger as parentLogger } from '../../logger.js'; +import { saveInteraction, saveInteractionWithoutReq } from '../../services/interactionLog.js'; import orcidApiService from '../../services/orcid.js'; type RemoveVerificationBody = { @@ -47,6 +49,11 @@ export const removeVerification = async ( } else { await attestationService.removeVerification(verification.id, user.id); + await saveInteraction(req, ActionType.UNVERIFY_ATTESTATION, { + claimId: verification.nodeAttestationId, + userId: user.id, + }); + new SuccessMessageResponse().send(res); const claim = await attestationService.findClaimById(verification.nodeAttestationId); @@ -91,11 +98,11 @@ export const addVerification = async ( const claim = await attestationService.findClaimById(parseInt(claimId)); await attestationService.verifyClaim(parseInt(claimId), user.id); - - const attestation = await attestationService.findAttestationById(claim.attestationId); + await saveInteraction(req, ActionType.VERIFY_ATTESTATION, { claimId: claimId, userId: user.id }); new SuccessMessageResponse().send(res); + const attestation = await attestationService.findAttestationById(claim.attestationId); if (attestation.protected) { /** * Update ORCID Profile @@ -103,6 +110,12 @@ export const addVerification = async ( const node = await prisma.node.findFirst({ where: { uuid: ensureUuidEndsWithDot(claim.nodeUuid) } }); const owner = await prisma.user.findFirst({ where: { id: node.ownerId } }); if (owner.orcid) await orcidApiService.postWorkRecord(node.uuid, owner.orcid); + await saveInteractionWithoutReq(ActionType.UPDATE_ORCID_RECORD, { + ownerId: owner.id, + orcid: owner.orcid, + uuid: node.uuid, + claimId, + }); } }; diff --git a/desci-server/src/services/orcid.ts b/desci-server/src/services/orcid.ts index 05a1cd19..55f8acec 100644 --- a/desci-server/src/services/orcid.ts +++ b/desci-server/src/services/orcid.ts @@ -1,5 +1,5 @@ import { ResearchObjectV1, ResearchObjectV1Author } from '@desci-labs/desci-models'; -import { AuthTokenSource, ORCIDRecord, OrcidPutCodes, PutcodeReference } from '@prisma/client'; +import { ActionType, AuthTokenSource, ORCIDRecord, OrcidPutCodes, PutcodeReference } from '@prisma/client'; import { logger as parentLogger, prisma } from '../internal.js'; import { IndexedResearchObject, getIndexedResearchObjects } from '../theGraph.js'; @@ -7,6 +7,7 @@ import { hexToCid } from '../utils.js'; import { attestationService } from './Attestation.js'; import { getManifestByCid } from './data/processing.js'; +import { saveInteractionWithoutReq } from './interactionLog.js'; // const PUTCODE_REGEX = /put-code=.*?(?\d+)/m; @@ -196,24 +197,37 @@ class OrcidApiService { }, }); - await prisma.orcidPutCodes.delete({ - where: { - id: putCode.id, - }, - }); - - logger.info( - { - status: response.status, - statusText: response.statusText, + if (response.ok) { + await saveInteractionWithoutReq(ActionType.REMOVE_ORCID_WORK_RECORD, { orcid, - putCode: { - code: putCode.putcode, - reference: putCode.reference, + }); + await prisma.orcidPutCodes.delete({ + where: { + id: putCode.id, }, - }, - 'ORCID RECORD DELETED', - ); + }); + + logger.info( + { + status: response.status, + statusText: response.statusText, + orcid, + putCode: { + code: putCode.putcode, + reference: putCode.reference, + }, + }, + 'ORCID RECORD DELETED', + ); + } else { + await saveInteractionWithoutReq(ActionType.ORCID_API_ERROR, { + orcid, + putCode, + status: response.status, + error: await response.json(), + }); + logger.error({ orcid, putCode, status: response.status }, 'Error: REMOVE ORCID WORK RECORD'); + } } /** @@ -370,17 +384,34 @@ class OrcidApiService { }, }); } + await saveInteractionWithoutReq(ActionType.UPDATE_ORCID_RECORD, { + userId, + orcid, + uuid, + putCode: returnedCode, + }); logger.info( { uuid, userId, status: response.status, returnedCode, reference: PutcodeReference.PREPRINT }, '[ORCID_API_SERVICE]:: Node Record UPDATED', ); } else { - logger.info( - { status: response.status, response, body: await response.text() }, - '[ORCID_API_SERVICE]::ORCID NODE API ERROR', - ); + const body = await response.text(); + await saveInteractionWithoutReq(ActionType.ORCID_API_ERROR, { + userId, + orcid, + uuid, + statusCode: response.status, + error: body, + }); + logger.info({ status: response.status, response, body }, '[ORCID_API_SERVICE]::ORCID NODE API ERROR'); } } catch (err) { + await saveInteractionWithoutReq(ActionType.ORCID_API_ERROR, { + userId, + orcid, + uuid, + error: err, + }); logger.info({ err }, '[ORCID_API_SERVICE]::NODE API Error Response'); } } @@ -496,17 +527,38 @@ class OrcidApiService { }); } + await saveInteractionWithoutReq(ActionType.UPDATE_ORCID_RECORD, { + userId, + orcid, + uuid, + claimId: claim.id, + putCode: returnedCode, + }); + logger.info( { uuid, claimId: claim.id, userId, status: response.status, returnedCode, reference: putCodeReference }, 'ORCID CLAIM RECORD UPDATED', ); } else { - logger.info( - { status: response.status, response, body: await response.text() }, - '[ORCID_API_SERVICE]::ORCID CLAIM API ERROR', - ); + const body = await response.text(); + await saveInteractionWithoutReq(ActionType.ORCID_API_ERROR, { + userId, + orcid, + uuid, + claimId: claim.id, + statusCode: response.status, + error: body, + }); + logger.info({ status: response.status, response, body }, '[ORCID_API_SERVICE]::ORCID CLAIM API ERROR'); } } catch (err) { + await saveInteractionWithoutReq(ActionType.ORCID_API_ERROR, { + userId, + orcid, + uuid, + claimId: claim.id, + error: err, + }); logger.info({ err }, '[ORCID_API_SERVICE]::CLAIM API Error Response'); } } From 1731fe75602c1172b15bfda6cbf319ea3280053d Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Thu, 6 Jun 2024 15:52:37 +0000 Subject: [PATCH 085/278] add upsert component(s) action --- desci-models/package.json | 2 +- desci-models/src/automerge.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/desci-models/package.json b/desci-models/package.json index 70560586..ae4fbcbd 100644 --- a/desci-models/package.json +++ b/desci-models/package.json @@ -1,6 +1,6 @@ { "name": "@desci-labs/desci-models", - "version": "0.2.7-rc1.5", + "version": "0.2.7-rc2.5", "description": "Data models for DeSci Nodes", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/desci-models/src/automerge.ts b/desci-models/src/automerge.ts index 19edf697..fd5ca2ba 100644 --- a/desci-models/src/automerge.ts +++ b/desci-models/src/automerge.ts @@ -36,6 +36,7 @@ export type ManifestActions = | { type: 'Update ResearchFields'; researchFields: string[] } | { type: 'Add Component'; component: ResearchObjectV1Component } | { type: 'Upsert Component'; component: ResearchObjectV1Component } + | { type: 'Upsert Components'; component: ResearchObjectV1Component[] } | { type: 'Delete Component'; path: string } | { type: 'Add Contributor'; author: ResearchObjectV1Author } | { type: 'Remove Contributor'; contributorIndex: number } From b93bd7031578ae9c087375a9b87f4cd4f01a5264 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Fri, 7 Jun 2024 11:24:05 +0000 Subject: [PATCH 086/278] add helper to convert firstNestingComponents to manifest components --- desci-server/src/utils/driveUtils.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/desci-server/src/utils/driveUtils.ts b/desci-server/src/utils/driveUtils.ts index b4215292..f3bcc04a 100644 --- a/desci-server/src/utils/driveUtils.ts +++ b/desci-server/src/utils/driveUtils.ts @@ -393,6 +393,26 @@ export function DANGEROUSLY_addComponentsToManifest( return manifest; } +export function prepareFirstNestingComponents(firstNestingComponents: FirstNestingComponent[]) { + const preparedComponents: ResearchObjectV1Component[] = []; + firstNestingComponents.forEach((c) => { + const comp = { + id: randomUUID(), + name: c.name, + ...(c.componentType && { type: c.componentType }), + ...(c.componentSubtype && { subtype: c.componentSubtype }), + payload: { + cid: c.cid, + path: c.path, + ...(c.externalUrl && { externalUrl: c.externalUrl }), + }, + starred: c.star || false, + }; + preparedComponents.push(comp); + }); + return preparedComponents; +} + export async function addComponentsToDraftManifest(node: Node, firstNestingComponents: FirstNestingComponent[]) { //add duplicate path check const components = firstNestingComponents.map((entry) => { From 5db55bac46d083aac0a91b1fca9ffcddc606c4c5 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Fri, 7 Jun 2024 11:24:30 +0000 Subject: [PATCH 087/278] add multi component upsert --- desci-repo/package.json | 2 +- desci-repo/src/services/manifestRepo.ts | 10 + desci-repo/yarn.lock | 1681 +++++++++++------------ 3 files changed, 830 insertions(+), 863 deletions(-) diff --git a/desci-repo/package.json b/desci-repo/package.json index a64fe9d4..e1257360 100644 --- a/desci-repo/package.json +++ b/desci-repo/package.json @@ -68,7 +68,7 @@ "typescript": "5.1.6" }, "dependencies": { - "@desci-labs/desci-models": "0.2.7-rc1", + "@desci-labs/desci-models": "0.2.7-rc1.5", "@sentry/node": "^7.84.0", "@sentry/tracing": "^7.84.0", "axios": "^1.6.2", diff --git a/desci-repo/src/services/manifestRepo.ts b/desci-repo/src/services/manifestRepo.ts index 2e841282..72d8a361 100644 --- a/desci-repo/src/services/manifestRepo.ts +++ b/desci-repo/src/services/manifestRepo.ts @@ -216,6 +216,16 @@ export const getDocumentUpdater = (documentId: DocumentId) => { { time: Date.now(), message: action.type }, ); break; + case 'Upsert Components': + action.components.forEach((component) => { + handle.change( + (document) => { + upsertManifestComponent(document, component); + }, + { time: Date.now(), message: 'Upsert Component' }, + ); + }); + break; case 'Publish Dpid': handle.change( (document) => { diff --git a/desci-repo/yarn.lock b/desci-repo/yarn.lock index b946d2ed..f3dbc5a2 100644 --- a/desci-repo/yarn.lock +++ b/desci-repo/yarn.lock @@ -4,12 +4,12 @@ "@aashutoshrathi/word-wrap@^1.2.3": version "1.2.6" - resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + resolved "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz" integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== "@automerge/automerge-repo-network-websocket@^1.0.19": version "1.1.0" - resolved "https://registry.yarnpkg.com/@automerge/automerge-repo-network-websocket/-/automerge-repo-network-websocket-1.1.0.tgz#d4ebb0331f0dd8357e85da7a1688bc47be938d58" + resolved "https://registry.npmjs.org/@automerge/automerge-repo-network-websocket/-/automerge-repo-network-websocket-1.1.0.tgz" integrity sha512-D3k/RKI5xVPb+ZEmEmL/MiuGiu2vzujOloyHveLmd1R9BL2JakbKk1s4G2MhTBT1qF8Io02pIa1+lsaG9HlULA== dependencies: "@automerge/automerge-repo" "1.1.0" @@ -21,16 +21,16 @@ "@automerge/automerge-repo-storage-nodefs@^1.0.19": version "1.1.0" - resolved "https://registry.yarnpkg.com/@automerge/automerge-repo-storage-nodefs/-/automerge-repo-storage-nodefs-1.1.0.tgz#a65d31f26a96ed2afff6b2994a8f069e32f8a080" + resolved "https://registry.npmjs.org/@automerge/automerge-repo-storage-nodefs/-/automerge-repo-storage-nodefs-1.1.0.tgz" integrity sha512-31vTq4ItdV0n4x7MOF/mmKwUqEwYQMekYZ3OEgUdJAhw7qIrF1lY0IM194DjVp9V55UFFMQyb5vx+VJ4GpKewA== dependencies: "@automerge/automerge-repo" "1.1.0" rimraf "^5.0.1" -"@automerge/automerge-repo@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@automerge/automerge-repo/-/automerge-repo-1.1.0.tgz#adb24708e949b72a73d9349ab2ad4e7eb4487b76" - integrity sha512-QRSt2s89Uhrlofbkipsb/9Alyp65/e1PocNzY+L4J7yDDXD7fbEW5uThXey2lSb1m98Fe0+NtzyKD1we6lvAkA== +"@automerge/automerge-repo@^1.1.0": + version "1.1.1" + resolved "https://registry.npmjs.org/@automerge/automerge-repo/-/automerge-repo-1.1.1.tgz" + integrity sha512-fQq+4eUadubzHOUi2BIiC5f/XFUHixJ/kdfnbXRoh2xwzojMfQIlrRfZzxkuW5AdD9LOC2/LoWJs+ak4a9vq4Q== dependencies: "@automerge/automerge" "^2.1.9" bs58check "^3.0.1" @@ -43,10 +43,10 @@ uuid "^9.0.0" xstate "^4.37.0" -"@automerge/automerge-repo@^1.1.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@automerge/automerge-repo/-/automerge-repo-1.1.1.tgz#87d2fcabb0191d48ab4a15c55935681381b0a605" - integrity sha512-fQq+4eUadubzHOUi2BIiC5f/XFUHixJ/kdfnbXRoh2xwzojMfQIlrRfZzxkuW5AdD9LOC2/LoWJs+ak4a9vq4Q== +"@automerge/automerge-repo@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@automerge/automerge-repo/-/automerge-repo-1.1.0.tgz" + integrity sha512-QRSt2s89Uhrlofbkipsb/9Alyp65/e1PocNzY+L4J7yDDXD7fbEW5uThXey2lSb1m98Fe0+NtzyKD1we6lvAkA== dependencies: "@automerge/automerge" "^2.1.9" bs58check "^3.0.1" @@ -61,12 +61,12 @@ "@automerge/automerge-wasm@0.9.0": version "0.9.0" - resolved "https://registry.yarnpkg.com/@automerge/automerge-wasm/-/automerge-wasm-0.9.0.tgz#1b0e1ea595feeb47ea0f4b685bf2ffb7fa61f97c" + resolved "https://registry.npmjs.org/@automerge/automerge-wasm/-/automerge-wasm-0.9.0.tgz" integrity sha512-wTPcW3wVk20D1x0DOko/RsfZV1mlc8HJynqgTRhVocOxFIU/RCilnYRfJmSb8LwCG2uZzfqg0DLsEBqQZ53KBQ== "@automerge/automerge@^2.1.10", "@automerge/automerge@^2.1.9": version "2.1.10" - resolved "https://registry.yarnpkg.com/@automerge/automerge/-/automerge-2.1.10.tgz#257f9f94c37db088008548cca7e57e853d1ed354" + resolved "https://registry.npmjs.org/@automerge/automerge/-/automerge-2.1.10.tgz" integrity sha512-xj8R3fQHZmDYnrYW5WrBqWm/r5sLV9Z7mu89pJ10wGLVS2V+iAB2os85DoOGI2etzjmQsoHyrd97GBmszjH4zQ== dependencies: "@automerge/automerge-wasm" "0.9.0" @@ -74,7 +74,7 @@ "@babel/code-frame@^7.0.0": version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz" integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== dependencies: "@babel/highlight" "^7.23.4" @@ -82,87 +82,52 @@ "@babel/helper-validator-identifier@^7.22.20": version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz" integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== "@babel/highlight@^7.23.4": version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" + resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz" integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== dependencies: "@babel/helper-validator-identifier" "^7.22.20" chalk "^2.4.2" js-tokens "^4.0.0" -"@cbor-extract/cbor-extract-darwin-arm64@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@cbor-extract/cbor-extract-darwin-arm64/-/cbor-extract-darwin-arm64-2.2.0.tgz#8d65cb861a99622e1b4a268e2d522d2ec6137338" - integrity sha512-P7swiOAdF7aSi0H+tHtHtr6zrpF3aAq/W9FXx5HektRvLTM2O89xCyXF3pk7pLc7QpaY7AoaE8UowVf9QBdh3w== - -"@cbor-extract/cbor-extract-darwin-x64@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@cbor-extract/cbor-extract-darwin-x64/-/cbor-extract-darwin-x64-2.2.0.tgz#9fbec199c888c5ec485a1839f4fad0485ab6c40a" - integrity sha512-1liF6fgowph0JxBbYnAS7ZlqNYLf000Qnj4KjqPNW4GViKrEql2MgZnAsExhY9LSy8dnvA4C0qHEBgPrll0z0w== - -"@cbor-extract/cbor-extract-linux-arm64@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@cbor-extract/cbor-extract-linux-arm64/-/cbor-extract-linux-arm64-2.2.0.tgz#bf77e0db4a1d2200a5aa072e02210d5043e953ae" - integrity sha512-rQvhNmDuhjTVXSPFLolmQ47/ydGOFXtbR7+wgkSY0bdOxCFept1hvg59uiLPT2fVDuJFuEy16EImo5tE2x3RsQ== - -"@cbor-extract/cbor-extract-linux-arm@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@cbor-extract/cbor-extract-linux-arm/-/cbor-extract-linux-arm-2.2.0.tgz#491335037eb8533ed8e21b139c59f6df04e39709" - integrity sha512-QeBcBXk964zOytiedMPQNZr7sg0TNavZeuUCD6ON4vEOU/25+pLhNN6EDIKJ9VLTKaZ7K7EaAriyYQ1NQ05s/Q== - "@cbor-extract/cbor-extract-linux-x64@2.2.0": version "2.2.0" - resolved "https://registry.yarnpkg.com/@cbor-extract/cbor-extract-linux-x64/-/cbor-extract-linux-x64-2.2.0.tgz#672574485ccd24759bf8fb8eab9dbca517d35b97" + resolved "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-x64/-/cbor-extract-linux-x64-2.2.0.tgz" integrity sha512-cWLAWtT3kNLHSvP4RKDzSTX9o0wvQEEAj4SKvhWuOVZxiDAeQazr9A+PSiRILK1VYMLeDml89ohxCnUNQNQNCw== -"@cbor-extract/cbor-extract-win32-x64@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@cbor-extract/cbor-extract-win32-x64/-/cbor-extract-win32-x64-2.2.0.tgz#4b3f07af047f984c082de34b116e765cb9af975f" - integrity sha512-l2M+Z8DO2vbvADOBNLbbh9y5ST1RY5sqkWOg/58GkUPBYou/cuNZ68SGQ644f1CvZ8kcOxyZtw06+dxWHIoN/w== - "@cspotcode/source-map-support@^0.8.0": version "0.8.1" - resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + resolved "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz" integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@desci-labs/desci-models@^0.2.7": - version "0.2.6-rc1" - resolved "https://registry.yarnpkg.com/@desci-labs/desci-models/-/desci-models-0.2.6-rc1.tgz#aa85ff6ef50985435f68d6674d10fcb70d345f99" - integrity sha512-NrZQ7InitPPSqrSmf85TjAXfss4gfVN5tHJe21YPGZhK5dwyFbMrYCP8atqELA+gaCGaNi+9KH+iEIDpMprM3Q== +"@desci-labs/desci-models@file:../desci-models": + version "0.2.7-rc2.5" + resolved "file:../desci-models" dependencies: jsonld "^8.1.1" schema-dts "^1.1.2" -"@digitalbazaar/http-client@^3.4.1": - version "3.4.1" - resolved "https://registry.yarnpkg.com/@digitalbazaar/http-client/-/http-client-3.4.1.tgz#5116fc44290d647cfe4b615d1f3fad9d6005e44d" - integrity sha512-Ahk1N+s7urkgj7WvvUND5f8GiWEPfUw0D41hdElaqLgu8wZScI8gdI0q+qWw5N1d35x7GCRH2uk9mi+Uzo9M3g== - dependencies: - ky "^0.33.3" - ky-universal "^0.11.0" - undici "^5.21.2" - "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" - resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== dependencies: eslint-visitor-keys "^3.3.0" "@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": version "4.10.0" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" + resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz" integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== "@eslint/eslintrc@^2.1.4": version "2.1.4" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad" + resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz" integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== dependencies: ajv "^6.12.4" @@ -177,17 +142,12 @@ "@eslint/js@8.56.0": version "8.56.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.56.0.tgz#ef20350fec605a7f7035a01764731b2de0f3782b" + resolved "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz" integrity sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A== -"@fastify/busboy@^2.0.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.0.tgz#0709e9f4cb252351c609c6e6d8d6779a8d25edff" - integrity sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA== - "@humanwhocodes/config-array@^0.11.13": version "0.11.14" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz#d78e481a039f7566ecc9660b4ea7fe6b1fec442b" + resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz" integrity sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg== dependencies: "@humanwhocodes/object-schema" "^2.0.2" @@ -196,17 +156,17 @@ "@humanwhocodes/module-importer@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + resolved "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz" integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== "@humanwhocodes/object-schema@^2.0.2": version "2.0.2" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz#d9fae00a2d5cb40f92cfe64b47ad749fbc38f917" + resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz" integrity sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw== "@isaacs/cliui@^8.0.2": version "8.0.2" - resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + resolved "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz" integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== dependencies: string-width "^5.1.2" @@ -218,17 +178,17 @@ "@jridgewell/resolve-uri@^3.0.3": version "3.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz" integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== "@jridgewell/sourcemap-codec@^1.4.10": version "1.4.15" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== "@jridgewell/trace-mapping@0.3.9": version "0.3.9" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz" integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== dependencies: "@jridgewell/resolve-uri" "^3.0.3" @@ -236,25 +196,25 @@ "@noble/hashes@^1.2.0": version "1.3.3" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.3.tgz#39908da56a4adc270147bb07968bf3b16cfe1699" + resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz" integrity sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA== "@nodelib/fs.scandir@2.1.5": version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== dependencies: "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": +"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== "@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== dependencies: "@nodelib/fs.scandir" "2.1.5" @@ -262,17 +222,17 @@ "@pkgjs/parseargs@^0.11.0": version "0.11.0" - resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== "@pkgr/core@^0.1.0": version "0.1.1" - resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31" + resolved "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz" integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA== "@sentry-internal/tracing@7.99.0": version "7.99.0" - resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.99.0.tgz#ad13f8343444ecf7323a4220d4e57a55166565d7" + resolved "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.99.0.tgz" integrity sha512-z3JQhHjoM1KdM20qrHwRClKJrNLr2CcKtCluq7xevLtXHJWNAQQbafnWD+Aoj85EWXBzKt9yJMv2ltcXJ+at+w== dependencies: "@sentry/core" "7.99.0" @@ -281,7 +241,7 @@ "@sentry/core@7.99.0": version "7.99.0" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.99.0.tgz#6881aae5ac1436637b3d88e0b12df4ab56016c5f" + resolved "https://registry.npmjs.org/@sentry/core/-/core-7.99.0.tgz" integrity sha512-vOAtzcAXEUtS/oW7wi3wMkZ3hsb5Ch96gKyrrj/mXdOp2zrcwdNV6N9/pawq2E9P/7Pw8AXw4CeDZztZrjQLuA== dependencies: "@sentry/types" "7.99.0" @@ -289,7 +249,7 @@ "@sentry/node@^7.84.0": version "7.99.0" - resolved "https://registry.yarnpkg.com/@sentry/node/-/node-7.99.0.tgz#c70e174527bbd86294dd446dbc1ae9036fb729f2" + resolved "https://registry.npmjs.org/@sentry/node/-/node-7.99.0.tgz" integrity sha512-34wYtLddnPcQ8qvKq62AfxowaMFw+GMUZGv7fIs9FxeBqqqn6Ckl0gFCTADudIIBQ3rSbmN7sHJIXdyiQv+pcw== dependencies: "@sentry-internal/tracing" "7.99.0" @@ -299,46 +259,46 @@ "@sentry/tracing@^7.84.0": version "7.99.0" - resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-7.99.0.tgz#75ecdda05fa37e1a3e6bc43b39d71b5b51db2290" + resolved "https://registry.npmjs.org/@sentry/tracing/-/tracing-7.99.0.tgz" integrity sha512-Cf622gSeamiSsi0JEj3PTXnq019OymaCrGf91x1d6OPyJ5jAXdlNuhw7NkqCEw8euIhhULuS81l5nGfBrgjj9Q== dependencies: "@sentry-internal/tracing" "7.99.0" "@sentry/types@7.99.0": version "7.99.0" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.99.0.tgz#bba7a514abab445026ee42f40f92f81275a6deba" + resolved "https://registry.npmjs.org/@sentry/types/-/types-7.99.0.tgz" integrity sha512-94qwOw4w40sAs5mCmzcGyj8ZUu/KhnWnuMZARRq96k+SjRW/tHFAOlIdnFSrt3BLPvSOK7R3bVAskZQ0N4FTmA== "@sentry/utils@7.99.0": version "7.99.0" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.99.0.tgz#ef96c3b59e23c79f3ef500db508234a48fa1cfbe" + resolved "https://registry.npmjs.org/@sentry/utils/-/utils-7.99.0.tgz" integrity sha512-cYZy5WNTkWs5GgggGnjfGqC44CWir0pAv4GVVSx0fsup4D4pMKBJPrtub15f9uC+QkUf3vVkqwpBqeFxtmJQTQ== dependencies: "@sentry/types" "7.99.0" "@tsconfig/node10@^1.0.7": version "1.0.9" - resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" + resolved "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz" integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== "@tsconfig/node12@^1.0.7": version "1.0.11" - resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" + resolved "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz" integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== "@tsconfig/node14@^1.0.0": version "1.0.3" - resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" + resolved "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz" integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== "@tsconfig/node16@^1.0.2": version "1.0.4" - resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" + resolved "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz" integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== "@types/body-parser@*": version "1.19.5" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4" + resolved "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz" integrity sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg== dependencies: "@types/connect" "*" @@ -346,26 +306,26 @@ "@types/chai@^4.3.11": version "4.3.11" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.11.tgz#e95050bf79a932cb7305dd130254ccdf9bde671c" + resolved "https://registry.npmjs.org/@types/chai/-/chai-4.3.11.tgz" integrity sha512-qQR1dr2rGIHYlJulmr8Ioq3De0Le9E4MJ5AiaeAETJJpndT1uUNHsGFK3L/UIu+rbkQSdj8J/w2bCsBZc/Y5fQ== "@types/connect@*": version "3.4.38" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" + resolved "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz" integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== dependencies: "@types/node" "*" "@types/cors@^2.8.17": version "2.8.17" - resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.17.tgz#5d718a5e494a8166f569d986794e49c48b216b2b" + resolved "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz" integrity sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA== dependencies: "@types/node" "*" "@types/express-serve-static-core@^4.17.33": version "4.17.42" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.42.tgz#2a276952acc73d1b8dc63fd4210647abbc553a71" + resolved "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.42.tgz" integrity sha512-ckM3jm2bf/MfB3+spLPWYPUH573plBFwpOhqQ2WottxYV85j1HQFlxmnTq57X1yHY9awZPig06hL/cLMgNWHIQ== dependencies: "@types/node" "*" @@ -375,7 +335,7 @@ "@types/express@^4.17.21": version "4.17.21" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d" + resolved "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz" integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ== dependencies: "@types/body-parser" "*" @@ -385,63 +345,63 @@ "@types/http-errors@*": version "2.0.4" - resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f" + resolved "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz" integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== "@types/json-schema@^7.0.12": version "7.0.15" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== "@types/json5@^0.0.29": version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== "@types/jsonwebtoken@^9.0.5": version "9.0.5" - resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.5.tgz#0bd9b841c9e6c5a937c17656e2368f65da025588" + resolved "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.5.tgz" integrity sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA== dependencies: "@types/node" "*" "@types/mime@*": version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.4.tgz#2198ac274de6017b44d941e00261d5bc6a0e0a45" + resolved "https://registry.npmjs.org/@types/mime/-/mime-3.0.4.tgz" integrity sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw== "@types/mime@^1": version "1.3.5" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" + resolved "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz" integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== "@types/mocha@^10.0.6": version "10.0.6" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.6.tgz#818551d39113081048bdddbef96701b4e8bb9d1b" + resolved "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.6.tgz" integrity sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg== "@types/morgan@^1.9.9": version "1.9.9" - resolved "https://registry.yarnpkg.com/@types/morgan/-/morgan-1.9.9.tgz#d60dec3979e16c203a000159daa07d3fb7270d7f" + resolved "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.9.tgz" integrity sha512-iRYSDKVaC6FkGSpEVVIvrRGw0DfJMiQzIn3qr2G5B3C//AWkulhXgaBd7tS9/J79GWSYMTHGs7PfI5b3Y8m+RQ== dependencies: "@types/node" "*" "@types/node@*": version "20.11.13" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.13.tgz#188263ee2c8d590e181d3f5bfa7e485a932957cb" + resolved "https://registry.npmjs.org/@types/node/-/node-20.11.13.tgz" integrity sha512-5G4zQwdiQBSWYTDAH1ctw2eidqdhMJaNsiIDKHFr55ihz5Trl2qqR8fdrT732yPBho5gkNxXm67OxWFBqX9aPg== dependencies: undici-types "~5.26.4" "@types/parse-json@^4.0.0": version "4.0.2" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" + resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz" integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== "@types/pg@^8.10.9": version "8.11.0" - resolved "https://registry.yarnpkg.com/@types/pg/-/pg-8.11.0.tgz#355a07531d467f2e4fabaa78be087ce2d99fd862" + resolved "https://registry.npmjs.org/@types/pg/-/pg-8.11.0.tgz" integrity sha512-sDAlRiBNthGjNFfvt0k6mtotoVYVQ63pA8R4EMWka7crawSR60waVYR0HAgmPRs/e2YaeJTD/43OoZ3PFw80pw== dependencies: "@types/node" "*" @@ -450,22 +410,22 @@ "@types/qs@*": version "6.9.11" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.11.tgz#208d8a30bc507bd82e03ada29e4732ea46a6bbda" + resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz" integrity sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ== "@types/range-parser@*": version "1.2.7" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" + resolved "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz" integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== "@types/semver@^7.5.0": version "7.5.6" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.6.tgz#c65b2bfce1bec346582c07724e3f8c1017a20339" + resolved "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz" integrity sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A== "@types/send@*": version "0.17.4" - resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.4.tgz#6619cd24e7270793702e4e6a4b958a9010cfc57a" + resolved "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz" integrity sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA== dependencies: "@types/mime" "^1" @@ -473,7 +433,7 @@ "@types/serve-static@*": version "1.15.5" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.5.tgz#15e67500ec40789a1e8c9defc2d32a896f05b033" + resolved "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz" integrity sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ== dependencies: "@types/http-errors" "*" @@ -482,24 +442,24 @@ "@types/strip-bom@^3.0.0": version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/strip-bom/-/strip-bom-3.0.0.tgz#14a8ec3956c2e81edb7520790aecf21c290aebd2" + resolved "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz" integrity sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ== "@types/strip-json-comments@0.0.30": version "0.0.30" - resolved "https://registry.yarnpkg.com/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz#9aa30c04db212a9a0649d6ae6fd50accc40748a1" + resolved "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz" integrity sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ== "@types/ws@^8.5.10": version "8.5.10" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.10.tgz#4acfb517970853fa6574a3a6886791d04a396787" + resolved "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz" integrity sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A== dependencies: "@types/node" "*" "@typescript-eslint/eslint-plugin@^6.13.1": version "6.20.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.20.0.tgz#9cf31546d2d5e884602626d89b0e0d2168ac25ed" + resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.20.0.tgz" integrity sha512-fTwGQUnjhoYHeSF6m5pWNkzmDDdsKELYrOBxhjMrofPqCkoC2k3B2wvGHFxa1CTIqkEn88nlW1HVMztjo2K8Hg== dependencies: "@eslint-community/regexpp" "^4.5.1" @@ -514,17 +474,36 @@ semver "^7.5.4" ts-api-utils "^1.0.1" +"@typescript-eslint/parser@^6.0.0 || ^6.0.0-alpha": + version "6.21.0" + resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz" + integrity sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ== + dependencies: + "@typescript-eslint/scope-manager" "6.21.0" + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/typescript-estree" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" + debug "^4.3.4" + "@typescript-eslint/scope-manager@6.20.0": version "6.20.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.20.0.tgz#8a926e60f6c47feb5bab878246dc2ae465730151" + resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.20.0.tgz" integrity sha512-p4rvHQRDTI1tGGMDFQm+GtxP1ZHyAh64WANVoyEcNMpaTFn3ox/3CcgtIlELnRfKzSs/DwYlDccJEtr3O6qBvA== dependencies: "@typescript-eslint/types" "6.20.0" "@typescript-eslint/visitor-keys" "6.20.0" +"@typescript-eslint/scope-manager@6.21.0": + version "6.21.0" + resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz" + integrity sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg== + dependencies: + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" + "@typescript-eslint/type-utils@6.20.0": version "6.20.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.20.0.tgz#d395475cd0f3610dd80c7d8716fa0db767da3831" + resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.20.0.tgz" integrity sha512-qnSobiJQb1F5JjN0YDRPHruQTrX7ICsmltXhkV536mp4idGAYrIyr47zF/JmkJtEcAVnIz4gUYJ7gOZa6SmN4g== dependencies: "@typescript-eslint/typescript-estree" "6.20.0" @@ -534,12 +513,17 @@ "@typescript-eslint/types@6.20.0": version "6.20.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.20.0.tgz#5ccd74c29011ae7714ae6973e4ec0c634708b448" + resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.20.0.tgz" integrity sha512-MM9mfZMAhiN4cOEcUOEx+0HmuaW3WBfukBZPCfwSqFnQy0grXYtngKCqpQN339X3RrwtzspWJrpbrupKYUSBXQ== +"@typescript-eslint/types@6.21.0": + version "6.21.0" + resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz" + integrity sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg== + "@typescript-eslint/typescript-estree@6.20.0": version "6.20.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.20.0.tgz#5b2d0975949e6bdd8d45ee1471461ef5fadc5542" + resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.20.0.tgz" integrity sha512-RnRya9q5m6YYSpBN7IzKu9FmLcYtErkDkc8/dKv81I9QiLLtVBHrjz+Ev/crAqgMNW2FCsoZF4g2QUylMnJz+g== dependencies: "@typescript-eslint/types" "6.20.0" @@ -551,9 +535,23 @@ semver "^7.5.4" ts-api-utils "^1.0.1" +"@typescript-eslint/typescript-estree@6.21.0": + version "6.21.0" + resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz" + integrity sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ== + dependencies: + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + minimatch "9.0.3" + semver "^7.5.4" + ts-api-utils "^1.0.1" + "@typescript-eslint/utils@6.20.0": version "6.20.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.20.0.tgz#0e52afcfaa51af5656490ba4b7437cc3aa28633d" + resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.20.0.tgz" integrity sha512-/EKuw+kRu2vAqCoDwDCBtDRU6CTKbUmwwI7SH7AashZ+W+7o8eiyy6V2cdOqN49KsTcASWsC5QeghYuRDTyOOg== dependencies: "@eslint-community/eslint-utils" "^4.4.0" @@ -566,32 +564,40 @@ "@typescript-eslint/visitor-keys@6.20.0": version "6.20.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.20.0.tgz#f7ada27f2803de89df0edd9fd7be22c05ce6a498" + resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.20.0.tgz" integrity sha512-E8Cp98kRe4gKHjJD4NExXKz/zOJ1A2hhZc+IMVD6i7w4yjIvh6VyuRI0gRtxAsXtoC35uGMaQ9rjI2zJaXDEAw== dependencies: "@typescript-eslint/types" "6.20.0" eslint-visitor-keys "^3.4.1" +"@typescript-eslint/visitor-keys@6.21.0": + version "6.21.0" + resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz" + integrity sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A== + dependencies: + "@typescript-eslint/types" "6.21.0" + eslint-visitor-keys "^3.4.1" + "@ungap/structured-clone@^1.2.0": version "1.2.0" - resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" + resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz" integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== abbrev@1: version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== abort-controller@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + resolved "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz" integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== dependencies: event-target-shim "^5.0.0" accepts@~1.3.8: version "1.3.8" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz" integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== dependencies: mime-types "~2.1.34" @@ -599,22 +605,22 @@ accepts@~1.3.8: acorn-jsx@^5.3.2: version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== acorn-walk@^8.1.1: version "8.3.2" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.2.tgz#7703af9415f1b6db9315d6895503862e231d34aa" + resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz" integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A== -acorn@^8.4.1, acorn@^8.9.0: +"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.4.1, acorn@^8.9.0: version "8.11.3" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz" integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== aggregate-error@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz" integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== dependencies: clean-stack "^2.0.0" @@ -622,7 +628,7 @@ aggregate-error@^3.0.0: ajv@^6.12.4: version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== dependencies: fast-deep-equal "^3.1.1" @@ -630,55 +636,55 @@ ajv@^6.12.4: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ansi-colors@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - ansi-colors@^4.1.1: version "4.1.3" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" + resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz" integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + ansi-escapes@^4.3.0: version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== dependencies: type-fest "^0.21.3" ansi-regex@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== ansi-regex@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz" integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== ansi-styles@^3.2.1: version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" ansi-styles@^6.1.0: version "6.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz" integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== anymatch@~3.1.2: version "3.1.3" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== dependencies: normalize-path "^3.0.0" @@ -686,17 +692,17 @@ anymatch@~3.1.2: arg@^4.1.0: version "4.1.3" - resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + resolved "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz" integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== argparse@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== array-buffer-byte-length@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead" + resolved "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz" integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== dependencies: call-bind "^1.0.2" @@ -704,12 +710,12 @@ array-buffer-byte-length@^1.0.0: array-flatten@1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== array-includes@^3.1.7: version "3.1.7" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.7.tgz#8cd2e01b26f7a3086cbc87271593fe921c62abda" + resolved "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz" integrity sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ== dependencies: call-bind "^1.0.2" @@ -720,12 +726,12 @@ array-includes@^3.1.7: array-union@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== array.prototype.findlastindex@^1.2.3: version "1.2.3" - resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz#b37598438f97b579166940814e2c0493a4f50207" + resolved "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz" integrity sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA== dependencies: call-bind "^1.0.2" @@ -736,7 +742,7 @@ array.prototype.findlastindex@^1.2.3: array.prototype.flat@^1.3.2: version "1.3.2" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18" + resolved "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz" integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA== dependencies: call-bind "^1.0.2" @@ -746,7 +752,7 @@ array.prototype.flat@^1.3.2: array.prototype.flatmap@^1.3.2: version "1.3.2" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz#c9a7c6831db8e719d6ce639190146c24bbd3e527" + resolved "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz" integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== dependencies: call-bind "^1.0.2" @@ -756,7 +762,7 @@ array.prototype.flatmap@^1.3.2: arraybuffer.prototype.slice@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz#98bd561953e3e74bb34938e77647179dfe6e9f12" + resolved "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz" integrity sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw== dependencies: array-buffer-byte-length "^1.0.0" @@ -769,32 +775,32 @@ arraybuffer.prototype.slice@^1.0.2: assertion-error@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + resolved "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz" integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== astral-regex@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz" integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== asynckit@^0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== atomic-sleep@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" + resolved "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz" integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== available-typed-arrays@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== axios@^1.6.2: version "1.6.7" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.7.tgz#7b48c2e27c96f9c68a2f8f31e2ab19f59b06b0a7" + resolved "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz" integrity sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA== dependencies: follow-redirects "^1.15.4" @@ -803,34 +809,34 @@ axios@^1.6.2: balanced-match@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== base-x@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-4.0.0.tgz#d0e3b7753450c73f8ad2389b5c018a4af7b2224a" + resolved "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz" integrity sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw== base64-js@^1.3.1: version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== basic-auth@~2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.1.tgz#b998279bf47ce38344b4f3cf916d4679bbf51e3a" + resolved "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz" integrity sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg== dependencies: safe-buffer "5.1.2" binary-extensions@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== body-parser@1.20.1: version "1.20.1" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" + resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz" integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== dependencies: bytes "3.1.2" @@ -848,7 +854,7 @@ body-parser@1.20.1: brace-expansion@^1.1.7: version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== dependencies: balanced-match "^1.0.0" @@ -856,33 +862,33 @@ brace-expansion@^1.1.7: brace-expansion@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== dependencies: balanced-match "^1.0.0" braces@^3.0.2, braces@~3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== dependencies: fill-range "^7.0.1" browser-stdout@1.3.1: version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + resolved "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== bs58@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-5.0.0.tgz#865575b4d13c09ea2a84622df6c8cbeb54ffc279" + resolved "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz" integrity sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ== dependencies: base-x "^4.0.0" bs58check@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-3.0.1.tgz#2094d13720a28593de1cba1d8c4e48602fdd841c" + resolved "https://registry.npmjs.org/bs58check/-/bs58check-3.0.1.tgz" integrity sha512-hjuuJvoWEybo7Hn/0xOrczQKKEKD63WguEjlhLExYs2wUBcebDC1jDNK17eEAD2lYfw82d5ASC1d7K3SWszjaQ== dependencies: "@noble/hashes" "^1.2.0" @@ -890,22 +896,22 @@ bs58check@^3.0.1: buffer-equal-constant-time@1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + resolved "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz" integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== buffer-from@^1.0.0: version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== buffer-writer@2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-2.0.0.tgz#ce7eb81a38f7829db09c873f2fbb792c0c98ec04" + resolved "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz" integrity sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw== buffer@^6.0.3: version "6.0.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + resolved "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz" integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== dependencies: base64-js "^1.3.1" @@ -913,12 +919,12 @@ buffer@^6.0.3: bytes@3.1.2: version "3.1.2" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" + resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz" integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== dependencies: function-bind "^1.1.2" @@ -927,22 +933,17 @@ call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: callsites@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== camelcase@^6.0.0: version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -canonicalize@^1.0.1: - version "1.0.8" - resolved "https://registry.yarnpkg.com/canonicalize/-/canonicalize-1.0.8.tgz#24d1f1a00ed202faafd9bf8e63352cd4450c6df1" - integrity sha512-0CNTVCLZggSh7bc5VkX5WWPWO+cyZbNd07IHIsSXLia/eAq+r836hgk+8BKoEh7949Mda87VUOitx5OddVj64A== - cbor-extract@^2.2.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/cbor-extract/-/cbor-extract-2.2.0.tgz#cee78e630cbeae3918d1e2e58e0cebaf3a3be840" + resolved "https://registry.npmjs.org/cbor-extract/-/cbor-extract-2.2.0.tgz" integrity sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA== dependencies: node-gyp-build-optional-packages "5.1.1" @@ -956,14 +957,14 @@ cbor-extract@^2.2.0: cbor-x@^1.3.0: version "1.5.8" - resolved "https://registry.yarnpkg.com/cbor-x/-/cbor-x-1.5.8.tgz#3bd7bc61120692b5031d7f782a39b64f51f1d825" + resolved "https://registry.npmjs.org/cbor-x/-/cbor-x-1.5.8.tgz" integrity sha512-gc3bHBsvG6GClCY6c0/iip+ghlqizkVp+TtaL927lwvP4VP9xBdi1HmqPR5uj/Mj/0TOlngMkIYa25wKg+VNrQ== optionalDependencies: cbor-extract "^2.2.0" chai@4.3.4: version "4.3.4" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.4.tgz#b55e655b31e1eac7099be4c08c21964fce2e6c49" + resolved "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz" integrity sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA== dependencies: assertion-error "^1.1.0" @@ -975,16 +976,32 @@ chai@4.3.4: chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== dependencies: ansi-styles "^3.2.1" escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: +chalk@^4.0.0: version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chalk@^4.1.1: + version "4.1.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== dependencies: ansi-styles "^4.1.0" @@ -992,14 +1009,14 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: check-error@^1.0.2: version "1.0.3" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.3.tgz#a6502e4312a7ee969f646e83bb3ddd56281bd694" + resolved "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz" integrity sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg== dependencies: get-func-name "^2.0.2" -chokidar@3.5.3, chokidar@^3.5.1, chokidar@^3.5.2: +chokidar@^3.5.1, chokidar@^3.5.2, chokidar@3.5.3: version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== dependencies: anymatch "~3.1.2" @@ -1014,104 +1031,104 @@ chokidar@3.5.3, chokidar@^3.5.1, chokidar@^3.5.2: clean-stack@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + resolved "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== cli-cursor@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz" integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== dependencies: restore-cursor "^3.1.0" cli-truncate@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" + resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz" integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== dependencies: slice-ansi "^3.0.0" string-width "^4.2.0" -cliui@^7.0.2, cliui@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" - integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== dependencies: string-width "^4.2.0" - strip-ansi "^6.0.1" + strip-ansi "^6.0.0" wrap-ansi "^7.0.0" color-convert@^1.9.0: version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== dependencies: color-name "1.1.3" color-convert@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== dependencies: color-name "~1.1.4" -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - color-name@~1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + colorette@^2.0.16, colorette@^2.0.7: version "2.0.20" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz" integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== combined-stream@^1.0.8: version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== dependencies: delayed-stream "~1.0.0" commander@^7.2.0: version "7.2.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + resolved "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz" integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== concat-map@0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== content-disposition@0.5.4: version "0.5.4" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz" integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== dependencies: safe-buffer "5.2.1" content-type@~1.0.4: version "1.0.5" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz" integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== cookie-signature@1.0.6: version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== cookie@0.5.0: version "0.5.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz" integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== cors@^2.8.5: version "2.8.5" - resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + resolved "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz" integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== dependencies: object-assign "^4" @@ -1119,7 +1136,7 @@ cors@^2.8.5: cosmiconfig@^7.0.0: version "7.1.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" + resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz" integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== dependencies: "@types/parse-json" "^4.0.0" @@ -1130,12 +1147,12 @@ cosmiconfig@^7.0.0: create-require@^1.1.0: version "1.1.1" - resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== cross-spawn@^6.0.5: version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz" integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== dependencies: nice-try "^1.0.4" @@ -1146,59 +1163,54 @@ cross-spawn@^6.0.5: cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== dependencies: path-key "^3.1.0" shebang-command "^2.0.0" which "^2.0.1" -data-uri-to-buffer@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz#d8feb2b2881e6a4f58c2e08acfd0e2834e26222e" - integrity sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A== - dateformat@^4.6.3: version "4.6.3" - resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-4.6.3.tgz#556fa6497e5217fedb78821424f8a1c22fa3f4b5" + resolved "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz" integrity sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA== -debug@2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: - ms "2.0.0" + ms "^2.1.1" -debug@4.3.4, debug@^4, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: +debug@^4, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@4.3.4: version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== +debug@2.6.9: + version "2.6.9" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: - ms "^2.1.1" + ms "2.0.0" decamelize@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + resolved "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz" integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== deep-eql@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" + resolved "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz" integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== dependencies: type-detect "^4.0.0" deep-equal@^2.2.3: version "2.2.3" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.3.tgz#af89dafb23a396c7da3e862abc0be27cf51d56e1" + resolved "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz" integrity sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA== dependencies: array-buffer-byte-length "^1.0.0" @@ -1222,12 +1234,12 @@ deep-equal@^2.2.3: deep-is@^0.1.3: version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== define-data-property@^1.0.1, define-data-property@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" + resolved "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz" integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== dependencies: get-intrinsic "^1.2.1" @@ -1236,7 +1248,7 @@ define-data-property@^1.0.1, define-data-property@^1.1.1: define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" + resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz" integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== dependencies: define-data-property "^1.0.1" @@ -1245,58 +1257,58 @@ define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1: delayed-stream@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -depd@2.0.0, depd@~2.0.0: +depd@~2.0.0, depd@2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== destroy@1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + resolved "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== detect-libc@^2.0.1: version "2.0.2" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.2.tgz#8ccf2ba9315350e1241b88d0ac3b0e1fbd99605d" + resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz" integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw== -diff@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== - diff@^4.0.1: version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== +diff@5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + dir-glob@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== dependencies: path-type "^4.0.0" doctrine@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz" integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== dependencies: esutils "^2.0.2" doctrine@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== dependencies: esutils "^2.0.2" dotenv-cli@^7.3.0: version "7.3.0" - resolved "https://registry.yarnpkg.com/dotenv-cli/-/dotenv-cli-7.3.0.tgz#21e33e7944713001677658d68856063968edfbd2" + resolved "https://registry.npmjs.org/dotenv-cli/-/dotenv-cli-7.3.0.tgz" integrity sha512-314CA4TyK34YEJ6ntBf80eUY+t1XaFLyem1k9P0sX1gn30qThZ5qZr/ZwE318gEnzyYP9yj9HJk6SqwE0upkfw== dependencies: cross-spawn "^7.0.3" @@ -1306,63 +1318,63 @@ dotenv-cli@^7.3.0: dotenv-expand@^10.0.0: version "10.0.0" - resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-10.0.0.tgz#12605d00fb0af6d0a592e6558585784032e4ef37" + resolved "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz" integrity sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A== dotenv@^16.3.0, dotenv@^16.3.1: version "16.4.1" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.1.tgz#1d9931f1d3e5d2959350d1250efab299561f7f11" + resolved "https://registry.npmjs.org/dotenv/-/dotenv-16.4.1.tgz" integrity sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ== dynamic-dedupe@^0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz#06e44c223f5e4e94d78ef9db23a6515ce2f962a1" + resolved "https://registry.npmjs.org/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz" integrity sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ== dependencies: xtend "^4.0.0" eastasianwidth@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz" integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== ecdsa-sig-formatter@1.0.11: version "1.0.11" - resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" + resolved "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz" integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== dependencies: safe-buffer "^5.0.1" ee-first@1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== emoji-regex@^8.0.0: version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== emoji-regex@^9.2.2: version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz" integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== encodeurl@~1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== end-of-stream@^1.1.0: version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: once "^1.4.0" -enquirer@^2.3.6: +enquirer@^2.3.6, "enquirer@>= 2.3.0 < 3": version "2.4.1" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.4.1.tgz#93334b3fbd74fc7097b224ab4a8fb7e40bf4ae56" + resolved "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz" integrity sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ== dependencies: ansi-colors "^4.1.1" @@ -1370,14 +1382,14 @@ enquirer@^2.3.6: error-ex@^1.3.1: version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== dependencies: is-arrayish "^0.2.1" es-abstract@^1.22.1: version "1.22.3" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.3.tgz#48e79f5573198de6dee3589195727f4f74bc4f32" + resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz" integrity sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA== dependencies: array-buffer-byte-length "^1.0.0" @@ -1422,7 +1434,7 @@ es-abstract@^1.22.1: es-get-iterator@^1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.3.tgz#3ef87523c5d464d41084b2c3c9c214f1199763d6" + resolved "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz" integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw== dependencies: call-bind "^1.0.2" @@ -1437,7 +1449,7 @@ es-get-iterator@^1.1.3: es-set-tostringtag@^2.0.1: version "2.0.2" - resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz#11f7cc9f63376930a5f20be4915834f4bc74f9c9" + resolved "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz" integrity sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q== dependencies: get-intrinsic "^1.2.2" @@ -1446,14 +1458,14 @@ es-set-tostringtag@^2.0.1: es-shim-unscopables@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz#1f6942e71ecc7835ed1c8a83006d8771a63a3763" + resolved "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz" integrity sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw== dependencies: hasown "^2.0.0" es-to-primitive@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz" integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== dependencies: is-callable "^1.1.4" @@ -1462,32 +1474,32 @@ es-to-primitive@^1.2.1: escalade@^3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== escape-html@~1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== -escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - escape-string-regexp@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== -eslint-config-prettier@^9.1.0: +escape-string-regexp@^4.0.0, escape-string-regexp@4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-config-prettier@*, eslint-config-prettier@^9.1.0: version "9.1.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz#31af3d94578645966c082fcb71a5846d3c94867f" + resolved "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz" integrity sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw== eslint-import-resolver-node@^0.3.9: version "0.3.9" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" + resolved "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz" integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== dependencies: debug "^3.2.7" @@ -1496,14 +1508,14 @@ eslint-import-resolver-node@^0.3.9: eslint-module-utils@^2.8.0: version "2.8.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" + resolved "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz" integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== dependencies: debug "^3.2.7" eslint-plugin-import@^2.29.0: version "2.29.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz#d45b37b5ef5901d639c15270d74d46d161150643" + resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz" integrity sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw== dependencies: array-includes "^3.1.7" @@ -1526,12 +1538,12 @@ eslint-plugin-import@^2.29.0: eslint-plugin-no-array-reduce@^1.0.62: version "1.0.62" - resolved "https://registry.yarnpkg.com/eslint-plugin-no-array-reduce/-/eslint-plugin-no-array-reduce-1.0.62.tgz#925dee5bbe37f41ce7aa6ebb149c3988dd5b8d48" + resolved "https://registry.npmjs.org/eslint-plugin-no-array-reduce/-/eslint-plugin-no-array-reduce-1.0.62.tgz" integrity sha512-Hnauv6BNmo2RPNG6ka1fc2WcNDtsbcutCbvx188goD/EdSNab3Jp26HgmMSFERiqu3VQdIebHSnSKIS1GUrvoA== eslint-plugin-prettier@^5.0.1: version "5.1.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz#17cfade9e732cef32b5f5be53bd4e07afd8e67e1" + resolved "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz" integrity sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw== dependencies: prettier-linter-helpers "^1.0.0" @@ -1539,7 +1551,7 @@ eslint-plugin-prettier@^5.0.1: eslint-scope@^7.2.2: version "7.2.2" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz" integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== dependencies: esrecurse "^4.3.0" @@ -1547,12 +1559,12 @@ eslint-scope@^7.2.2: eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: version "3.4.3" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== -eslint@^8.55.0: +"eslint@^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^7.0.0 || ^8.0.0", eslint@^8.55.0, eslint@>=7.0.0, eslint@>=8.0.0: version "8.56.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.56.0.tgz#4957ce8da409dc0809f99ab07a1b94832ab74b15" + resolved "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz" integrity sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ== dependencies: "@eslint-community/eslint-utils" "^4.2.0" @@ -1596,7 +1608,7 @@ eslint@^8.55.0: espree@^9.6.0, espree@^9.6.1: version "9.6.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + resolved "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz" integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== dependencies: acorn "^8.9.0" @@ -1605,51 +1617,51 @@ espree@^9.6.0, espree@^9.6.1: esquery@^1.4.2: version "1.5.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + resolved "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz" integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== dependencies: estraverse "^5.1.0" esrecurse@^4.3.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: estraverse "^5.2.0" estraverse@^5.1.0, estraverse@^5.2.0: version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== esutils@^2.0.2: version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== etag@~1.8.1: version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== event-target-shim@^5.0.0: version "5.0.1" - resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + resolved "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== eventemitter3@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" + resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz" integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== events@^3.3.0: version "3.3.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== execa@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" + resolved "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz" integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== dependencies: cross-spawn "^7.0.0" @@ -1664,7 +1676,7 @@ execa@^4.1.0: execa@^5.0.0: version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== dependencies: cross-spawn "^7.0.3" @@ -1679,7 +1691,7 @@ execa@^5.0.0: express@^4.18.2: version "4.18.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" + resolved "https://registry.npmjs.org/express/-/express-4.18.2.tgz" integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== dependencies: accepts "~1.3.8" @@ -1716,22 +1728,22 @@ express@^4.18.2: fast-copy@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/fast-copy/-/fast-copy-3.0.1.tgz#9e89ef498b8c04c1cd76b33b8e14271658a732aa" + resolved "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.1.tgz" integrity sha512-Knr7NOtK3HWRYGtHoJrjkaWepqT8thIVGAwt0p0aUs1zqkAzXZV4vo9fFNwyb5fcqK1GKYFYxldQdIDVKhUAfA== fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-diff@^1.1.2: version "1.3.0" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" + resolved "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz" integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== fast-glob@^3.2.9: version "3.3.2" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz" integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== dependencies: "@nodelib/fs.stat" "^2.0.2" @@ -1742,61 +1754,53 @@ fast-glob@^3.2.9: fast-json-stable-stringify@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== fast-levenshtein@^2.0.6: version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fast-redact@^3.1.1: version "3.3.0" - resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.3.0.tgz#7c83ce3a7be4898241a46560d51de10f653f7634" + resolved "https://registry.npmjs.org/fast-redact/-/fast-redact-3.3.0.tgz" integrity sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ== fast-safe-stringify@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884" + resolved "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz" integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== fast-sha256@^1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/fast-sha256/-/fast-sha256-1.3.0.tgz#7916ba2054eeb255982608cccd0f6660c79b7ae6" + resolved "https://registry.npmjs.org/fast-sha256/-/fast-sha256-1.3.0.tgz" integrity sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ== fastq@^1.6.0: version "1.17.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.0.tgz#ca5e1a90b5e68f97fc8b61330d5819b82f5fab03" + resolved "https://registry.npmjs.org/fastq/-/fastq-1.17.0.tgz" integrity sha512-zGygtijUMT7jnk3h26kUms3BkSDp4IfIKjmnqI2tvx6nuBfiF1UqOxbnLfzdv+apBy+53oaImsKtMw/xYbW+1w== dependencies: reusify "^1.0.4" -fetch-blob@^3.1.2, fetch-blob@^3.1.4: - version "3.2.0" - resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-3.2.0.tgz#f09b8d4bbd45adc6f0c20b7e787e793e309dcce9" - integrity sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ== - dependencies: - node-domexception "^1.0.0" - web-streams-polyfill "^3.0.3" - file-entry-cache@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== dependencies: flat-cache "^3.0.4" fill-range@^7.0.1: version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== dependencies: to-regex-range "^5.0.1" finalhandler@1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz" integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== dependencies: debug "2.6.9" @@ -1807,25 +1811,25 @@ finalhandler@1.2.0: statuses "2.0.1" unpipe "~1.0.0" -find-up@5.0.0, find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - find-up@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== dependencies: locate-path "^5.0.0" path-exists "^4.0.0" +find-up@^5.0.0, find-up@5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + flat-cache@^3.0.4: version "3.2.0" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" + resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz" integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== dependencies: flatted "^3.2.9" @@ -1834,29 +1838,29 @@ flat-cache@^3.0.4: flat@^5.0.2: version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + resolved "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz" integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== flatted@^3.2.9: version "3.2.9" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf" + resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz" integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== follow-redirects@^1.15.4: version "1.15.5" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.5.tgz#54d4d6d062c0fa7d9d17feb008461550e3ba8020" + resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz" integrity sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw== for-each@^0.3.3: version "0.3.3" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + resolved "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz" integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== dependencies: is-callable "^1.1.3" foreground-child@^3.1.0: version "3.1.1" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" + resolved "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz" integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== dependencies: cross-spawn "^7.0.0" @@ -1864,48 +1868,36 @@ foreground-child@^3.1.0: form-data@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz" integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== dependencies: asynckit "^0.4.0" combined-stream "^1.0.8" mime-types "^2.1.12" -formdata-polyfill@^4.0.10: - version "4.0.10" - resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz#24807c31c9d402e002ab3d8c720144ceb8848423" - integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g== - dependencies: - fetch-blob "^3.1.2" - forwarded@0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== fresh@0.5.2: version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== fs.realpath@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" - integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== - function-bind@^1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== function.prototype.name@^1.1.6: version "1.1.6" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd" + resolved "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz" integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== dependencies: call-bind "^1.0.2" @@ -1915,22 +1907,22 @@ function.prototype.name@^1.1.6: functions-have-names@^1.2.3: version "1.2.3" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + resolved "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== get-caller-file@^2.0.5: version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== get-func-name@^2.0.0, get-func-name@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41" + resolved "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz" integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: version "1.2.2" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" + resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz" integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== dependencies: function-bind "^1.1.2" @@ -1940,24 +1932,24 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@ get-own-enumerable-property-symbols@^3.0.0: version "3.0.2" - resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" + resolved "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz" integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== get-stream@^5.0.0: version "5.2.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== dependencies: pump "^3.0.0" get-stream@^6.0.0: version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== get-symbol-description@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz" integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== dependencies: call-bind "^1.0.2" @@ -1965,33 +1957,21 @@ get-symbol-description@^1.0.0: glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" glob-parent@^6.0.2: version "6.0.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== dependencies: is-glob "^4.0.3" -glob@7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - glob@^10.3.7: version "10.3.10" - resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" + resolved "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz" integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== dependencies: foreground-child "^3.1.0" @@ -2002,7 +1982,7 @@ glob@^10.3.7: glob@^7.1.3: version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== dependencies: fs.realpath "^1.0.0" @@ -2012,23 +1992,35 @@ glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" +glob@7.2.0: + version "7.2.0" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + globals@^13.19.0: version "13.24.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171" + resolved "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz" integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== dependencies: type-fest "^0.20.2" globalthis@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" + resolved "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz" integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== dependencies: define-properties "^1.1.3" globby@^11.1.0: version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== dependencies: array-union "^2.1.0" @@ -2040,85 +2032,85 @@ globby@^11.1.0: gopd@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + resolved "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz" integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== dependencies: get-intrinsic "^1.1.3" graceful-fs@^4.1.2: version "4.2.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== graphemer@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + resolved "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz" integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== has-bigints@^1.0.1, has-bigints@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz" integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== has-flag@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== has-flag@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz#52ba30b6c5ec87fd89fa574bc1c39125c6f65340" + resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz" integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== dependencies: get-intrinsic "^1.2.2" has-proto@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + resolved "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz" integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== has-tostringtag@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz" integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== dependencies: has-symbols "^1.0.2" hasown@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" + resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz" integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== dependencies: function-bind "^1.1.2" he@1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== help-me@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/help-me/-/help-me-5.0.0.tgz#b1ebe63b967b74060027c2ac61f9be12d354a6f6" + resolved "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz" integrity sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg== hosted-git-info@^2.1.4: version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz" integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== http-errors@2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== dependencies: depd "2.0.0" @@ -2129,39 +2121,39 @@ http-errors@2.0.0: human-signals@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" + resolved "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz" integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== human-signals@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== iconv-lite@0.4.24: version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== dependencies: safer-buffer ">= 2.1.2 < 3" ieee754@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== ignore-by-default@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" + resolved "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz" integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA== ignore@^5.2.0, ignore@^5.2.4, ignore@^5.3.0: version "5.3.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" + resolved "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz" integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== import-fresh@^3.2.1: version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== dependencies: parent-module "^1.0.0" @@ -2169,17 +2161,17 @@ import-fresh@^3.2.1: imurmurhash@^0.1.4: version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== indent-string@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== inflight@^1.0.4: version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== dependencies: once "^1.3.0" @@ -2187,12 +2179,12 @@ inflight@^1.0.4: inherits@2, inherits@2.0.4: version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== internal-slot@^1.0.4, internal-slot@^1.0.5: version "1.0.6" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.6.tgz#37e756098c4911c5e912b8edbf71ed3aa116f930" + resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz" integrity sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg== dependencies: get-intrinsic "^1.2.2" @@ -2201,12 +2193,12 @@ internal-slot@^1.0.4, internal-slot@^1.0.5: ipaddr.js@1.9.1: version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== is-arguments@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + resolved "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz" integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== dependencies: call-bind "^1.0.2" @@ -2214,7 +2206,7 @@ is-arguments@^1.1.1: is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" + resolved "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz" integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== dependencies: call-bind "^1.0.2" @@ -2223,26 +2215,26 @@ is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: is-arrayish@^0.2.1: version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== is-bigint@^1.0.1: version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz" integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== dependencies: has-bigints "^1.0.1" is-binary-path@~2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== dependencies: binary-extensions "^2.0.0" is-boolean-object@^1.1.0: version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz" integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== dependencies: call-bind "^1.0.2" @@ -2250,80 +2242,80 @@ is-boolean-object@^1.1.0: is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: version "1.2.7" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== is-core-module@^2.13.0, is-core-module@^2.13.1: version "2.13.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" + resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz" integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== dependencies: hasown "^2.0.0" is-date-object@^1.0.1, is-date-object@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz" integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== dependencies: has-tostringtag "^1.0.0" is-extglob@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== is-fullwidth-code-point@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== dependencies: is-extglob "^2.1.1" is-map@^2.0.1, is-map@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" + resolved "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz" integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== is-negative-zero@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz" integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== is-number-object@^1.0.4: version "1.0.7" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" + resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz" integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== dependencies: has-tostringtag "^1.0.0" is-number@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== is-obj@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + resolved "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz" integrity sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg== is-path-inside@^3.0.3: version "3.0.3" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== is-plain-obj@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz" integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== is-regex@^1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz" integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== dependencies: call-bind "^1.0.2" @@ -2331,67 +2323,67 @@ is-regex@^1.1.4: is-regexp@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + resolved "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz" integrity sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA== is-set@^2.0.1, is-set@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" + resolved "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz" integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== is-shared-array-buffer@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" + resolved "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz" integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== dependencies: call-bind "^1.0.2" is-stream@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== is-string@^1.0.5, is-string@^1.0.7: version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + resolved "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz" integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== dependencies: has-tostringtag "^1.0.0" is-symbol@^1.0.2, is-symbol@^1.0.3: version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz" integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== dependencies: has-symbols "^1.0.2" is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.9: version "1.1.12" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" + resolved "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz" integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== dependencies: which-typed-array "^1.1.11" is-unicode-supported@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== is-weakmap@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" + resolved "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz" integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== is-weakref@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + resolved "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz" integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== dependencies: call-bind "^1.0.2" is-weakset@^2.0.1: version "2.0.2" - resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.2.tgz#4569d67a747a1ce5a994dfd4ef6dcea76e7c0a1d" + resolved "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz" integrity sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg== dependencies: call-bind "^1.0.2" @@ -2399,22 +2391,22 @@ is-weakset@^2.0.1: isarray@^2.0.5: version "2.0.5" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz" integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== isexe@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== isomorphic-ws@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf" + resolved "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz" integrity sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw== jackspeak@^2.3.5: version "2.3.6" - resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" + resolved "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz" integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== dependencies: "@isaacs/cliui" "^8.0.2" @@ -2423,66 +2415,56 @@ jackspeak@^2.3.5: joycon@^3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/joycon/-/joycon-3.1.1.tgz#bce8596d6ae808f8b68168f5fc69280996894f03" + resolved "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz" integrity sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw== js-tokens@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@4.1.0, js-yaml@^4.1.0: +js-yaml@^4.1.0, js-yaml@4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== dependencies: argparse "^2.0.1" json-buffer@3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + resolved "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz" integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== json-parse-better-errors@^1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + resolved "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== json-parse-even-better-errors@^2.3.0: version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== json-schema-traverse@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== json5@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" + resolved "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz" integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== dependencies: minimist "^1.2.0" -jsonld@^8.1.1: - version "8.3.2" - resolved "https://registry.yarnpkg.com/jsonld/-/jsonld-8.3.2.tgz#7033f8994aed346b536e9046025f7f1fe9669934" - integrity sha512-MwBbq95szLwt8eVQ1Bcfwmgju/Y5P2GdtlHE2ncyfuYjIdEhluUVyj1eudacf1mOkWIoS9GpDBTECqhmq7EOaA== - dependencies: - "@digitalbazaar/http-client" "^3.4.1" - canonicalize "^1.0.1" - lru-cache "^6.0.0" - rdf-canonize "^3.4.0" - jsonwebtoken@^9.0.2: version "9.0.2" - resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3" + resolved "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz" integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ== dependencies: jws "^3.2.2" @@ -2498,7 +2480,7 @@ jsonwebtoken@^9.0.2: jwa@^1.4.1: version "1.4.1" - resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" + resolved "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz" integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== dependencies: buffer-equal-constant-time "1.0.1" @@ -2507,7 +2489,7 @@ jwa@^1.4.1: jws@^3.2.2: version "3.2.2" - resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" + resolved "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz" integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== dependencies: jwa "^1.4.1" @@ -2515,27 +2497,14 @@ jws@^3.2.2: keyv@^4.5.3: version "4.5.4" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + resolved "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz" integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== dependencies: json-buffer "3.0.1" -ky-universal@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/ky-universal/-/ky-universal-0.11.0.tgz#f5edf857865aaaea416a1968222148ad7d9e4017" - integrity sha512-65KyweaWvk+uKKkCrfAf+xqN2/epw1IJDtlyCPxYffFCMR8u1sp2U65NtWpnozYfZxQ6IUzIlvUcw+hQ82U2Xw== - dependencies: - abort-controller "^3.0.0" - node-fetch "^3.2.10" - -ky@^0.33.3: - version "0.33.3" - resolved "https://registry.yarnpkg.com/ky/-/ky-0.33.3.tgz#bf1ad322a3f2c3428c13cfa4b3af95e6c4a2f543" - integrity sha512-CasD9OCEQSFIam2U8efFK81Yeg8vNMTBUqtMOHlrcWQHqUX3HeCl9Dr31u4toV7emlH8Mymk5+9p0lL6mKb/Xw== - levn@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== dependencies: prelude-ls "^1.2.1" @@ -2543,12 +2512,12 @@ levn@^0.4.1: lines-and-columns@^1.1.6: version "1.2.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== lint-staged@11.1.2: version "11.1.2" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-11.1.2.tgz#4dd78782ae43ee6ebf2969cad9af67a46b33cd90" + resolved "https://registry.npmjs.org/lint-staged/-/lint-staged-11.1.2.tgz" integrity sha512-6lYpNoA9wGqkL6Hew/4n1H6lRqF3qCsujVT0Oq5Z4hiSAM7S6NksPJ3gnr7A7R52xCtiZMcEUNNQ6d6X5Bvh9w== dependencies: chalk "^4.1.1" @@ -2568,7 +2537,7 @@ lint-staged@11.1.2: listr2@^3.8.2: version "3.14.0" - resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.14.0.tgz#23101cc62e1375fd5836b248276d1d2b51fdbe9e" + resolved "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz" integrity sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g== dependencies: cli-truncate "^2.1.0" @@ -2582,7 +2551,7 @@ listr2@^3.8.2: load-json-file@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz" integrity sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw== dependencies: graceful-fs "^4.1.2" @@ -2592,61 +2561,61 @@ load-json-file@^4.0.0: locate-path@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== dependencies: p-locate "^4.1.0" locate-path@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== dependencies: p-locate "^5.0.0" lodash.includes@^4.3.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + resolved "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz" integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w== lodash.isboolean@^3.0.3: version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + resolved "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz" integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg== lodash.isinteger@^4.0.4: version "4.0.4" - resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + resolved "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz" integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA== lodash.isnumber@^3.0.3: version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + resolved "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz" integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw== lodash.isplainobject@^4.0.6: version "4.0.6" - resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + resolved "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz" integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== lodash.isstring@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + resolved "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz" integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== lodash.merge@^4.6.2: version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== lodash.once@^4.0.0: version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + resolved "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz" integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== -log-symbols@4.1.0, log-symbols@^4.1.0: +log-symbols@^4.1.0, log-symbols@4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== dependencies: chalk "^4.1.0" @@ -2654,7 +2623,7 @@ log-symbols@4.1.0, log-symbols@^4.1.0: log-update@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" + resolved "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz" integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== dependencies: ansi-escapes "^4.3.0" @@ -2664,54 +2633,54 @@ log-update@^4.0.0: lru-cache@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== dependencies: yallist "^4.0.0" "lru-cache@^9.1.1 || ^10.0.0": version "10.2.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.0.tgz#0bd445ca57363465900f4d1f9bd8db343a4d95c3" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz" integrity sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q== make-error@^1.1.1: version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== media-typer@0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== memorystream@^0.3.1: version "0.3.1" - resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" + resolved "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz" integrity sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw== merge-descriptors@1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + resolved "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz" integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== merge-stream@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== methods@~1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz" integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== micromatch@^4.0.4: version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== dependencies: braces "^3.0.2" @@ -2719,65 +2688,72 @@ micromatch@^4.0.4: mime-db@1.52.0: version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== mime-types@^2.1.12, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: mime-db "1.52.0" mime@1.6.0: version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== mimic-fn@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^9.0.1: + version "9.0.3" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + minimatch@5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz" integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== dependencies: brace-expansion "^2.0.1" -minimatch@9.0.3, minimatch@^9.0.1: +minimatch@9.0.3: version "9.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz" integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== dependencies: brace-expansion "^2.0.1" -minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - minimist@^1.2.0, minimist@^1.2.6: version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== "minipass@^5.0.0 || ^6.0.2 || ^7.0.0": version "7.0.4" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" + resolved "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz" integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== mkdirp@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== mocha@^10.2.0: version "10.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" + resolved "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz" integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== dependencies: ansi-colors "4.1.1" @@ -2804,7 +2780,7 @@ mocha@^10.2.0: morgan@^1.10.0: version "1.10.0" - resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.10.0.tgz#091778abc1fc47cd3509824653dae1faab6b17d7" + resolved "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz" integrity sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ== dependencies: basic-auth "~2.0.1" @@ -2815,68 +2791,54 @@ morgan@^1.10.0: mri@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b" + resolved "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz" integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA== +ms@^2.1.1, ms@2.1.3: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + ms@2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== ms@2.1.2: version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3, ms@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - nanoid@3.3.3: version "3.3.3" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" + resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz" integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== natural-compare@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== negotiator@0.6.3: version "0.6.3" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== nice-try@^1.0.4: version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + resolved "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== -node-domexception@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" - integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== - -node-fetch@^3.2.10: - version "3.3.2" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.2.tgz#d1e889bacdf733b4ff3b2b243eb7a12866a0b78b" - integrity sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA== - dependencies: - data-uri-to-buffer "^4.0.0" - fetch-blob "^3.1.4" - formdata-polyfill "^4.0.10" - node-gyp-build-optional-packages@5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.1.1.tgz#52b143b9dd77b7669073cbfe39e3f4118bfc603c" + resolved "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.1.1.tgz" integrity sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw== dependencies: detect-libc "^2.0.1" nodemon@^3.0.2: version "3.0.3" - resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-3.0.3.tgz#244a62d1c690eece3f6165c6cdb0db03ebd80b76" + resolved "https://registry.npmjs.org/nodemon/-/nodemon-3.0.3.tgz" integrity sha512-7jH/NXbFPxVaMwmBCC2B9F/V6X1VkEdNgx3iu9jji8WxWcvhMWkmhNWhI5077zknOnZnBzba9hZP6bCPJLSReQ== dependencies: chokidar "^3.5.2" @@ -2892,14 +2854,14 @@ nodemon@^3.0.2: nopt@~1.0.10: version "1.0.10" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" + resolved "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz" integrity sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg== dependencies: abbrev "1" normalize-package-data@^2.3.2: version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz" integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== dependencies: hosted-git-info "^2.1.4" @@ -2909,12 +2871,12 @@ normalize-package-data@^2.3.2: normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== npm-run-all@^4.1.5: version "4.1.5" - resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba" + resolved "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz" integrity sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ== dependencies: ansi-styles "^3.2.1" @@ -2929,24 +2891,24 @@ npm-run-all@^4.1.5: npm-run-path@^4.0.0, npm-run-path@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== dependencies: path-key "^3.0.0" object-assign@^4: version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== object-inspect@^1.13.1, object-inspect@^1.9.0: version "1.13.1" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" + resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz" integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== object-is@^1.1.5: version "1.1.5" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + resolved "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz" integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== dependencies: call-bind "^1.0.2" @@ -2954,12 +2916,12 @@ object-is@^1.1.5: object-keys@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== object.assign@^4.1.4: version "4.1.5" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0" + resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz" integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ== dependencies: call-bind "^1.0.5" @@ -2969,7 +2931,7 @@ object.assign@^4.1.4: object.fromentries@^2.0.7: version "2.0.7" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.7.tgz#71e95f441e9a0ea6baf682ecaaf37fa2a8d7e616" + resolved "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz" integrity sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA== dependencies: call-bind "^1.0.2" @@ -2978,7 +2940,7 @@ object.fromentries@^2.0.7: object.groupby@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.1.tgz#d41d9f3c8d6c778d9cbac86b4ee9f5af103152ee" + resolved "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz" integrity sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ== dependencies: call-bind "^1.0.2" @@ -2988,7 +2950,7 @@ object.groupby@^1.0.1: object.values@^1.1.7: version "1.1.7" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.7.tgz#617ed13272e7e1071b43973aa1655d9291b8442a" + resolved "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz" integrity sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng== dependencies: call-bind "^1.0.2" @@ -2997,50 +2959,50 @@ object.values@^1.1.7: obuf@~1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + resolved "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== on-exit-leak-free@^2.1.0: version "2.1.2" - resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz#fed195c9ebddb7d9e4c3842f93f281ac8dadd3b8" + resolved "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz" integrity sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA== -on-finished@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" - integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== - dependencies: - ee-first "1.1.1" - on-finished@~2.3.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz" integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== dependencies: ee-first "1.1.1" +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + on-headers@~1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz" integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" onetime@^5.1.0, onetime@^5.1.2: version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== dependencies: mimic-fn "^2.1.0" optionator@^0.9.3: version "0.9.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz" integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== dependencies: "@aashutoshrathi/word-wrap" "^1.2.3" @@ -3052,59 +3014,59 @@ optionator@^0.9.3: p-limit@^2.2.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: p-try "^2.0.0" p-limit@^3.0.2: version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: yocto-queue "^0.1.0" p-locate@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz" integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== dependencies: p-limit "^2.2.0" p-locate@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== dependencies: p-limit "^3.0.2" p-map@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + resolved "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz" integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== dependencies: aggregate-error "^3.0.0" p-try@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== packet-reader@1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/packet-reader/-/packet-reader-1.0.0.tgz#9238e5480dedabacfe1fe3f2771063f164157d74" + resolved "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz" integrity sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ== parent-module@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== dependencies: callsites "^3.0.0" parse-json@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + resolved "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz" integrity sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw== dependencies: error-ex "^1.3.1" @@ -3112,7 +3074,7 @@ parse-json@^4.0.0: parse-json@^5.0.0: version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== dependencies: "@babel/code-frame" "^7.0.0" @@ -3122,37 +3084,37 @@ parse-json@^5.0.0: parseurl@~1.3.3: version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== path-exists@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== path-is-absolute@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== path-key@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + resolved "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz" integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== path-parse@^1.0.7: version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== path-scurry@^1.10.1: version "1.10.1" - resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" + resolved "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz" integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== dependencies: lru-cache "^9.1.1 || ^10.0.0" @@ -3160,59 +3122,59 @@ path-scurry@^1.10.1: path-to-regexp@0.1.7: version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== path-type@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + resolved "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz" integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== dependencies: pify "^3.0.0" path-type@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== pathval@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" + resolved "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz" integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== pg-cloudflare@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz#e6d5833015b170e23ae819e8c5d7eaedb472ca98" + resolved "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz" integrity sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q== pg-connection-string@^2.6.2: version "2.6.2" - resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.6.2.tgz#713d82053de4e2bd166fab70cd4f26ad36aab475" + resolved "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz" integrity sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA== pg-int8@1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c" + resolved "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz" integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw== pg-numeric@1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/pg-numeric/-/pg-numeric-1.0.2.tgz#816d9a44026086ae8ae74839acd6a09b0636aa3a" + resolved "https://registry.npmjs.org/pg-numeric/-/pg-numeric-1.0.2.tgz" integrity sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw== pg-pool@^3.6.1: version "3.6.1" - resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.6.1.tgz#5a902eda79a8d7e3c928b77abf776b3cb7d351f7" + resolved "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz" integrity sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og== pg-protocol@*, pg-protocol@^1.6.0: version "1.6.0" - resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.6.0.tgz#4c91613c0315349363af2084608db843502f8833" + resolved "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz" integrity sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q== pg-types@^2.1.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3" + resolved "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz" integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA== dependencies: pg-int8 "1.0.1" @@ -3223,7 +3185,7 @@ pg-types@^2.1.0: pg-types@^4.0.1: version "4.0.2" - resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-4.0.2.tgz#399209a57c326f162461faa870145bb0f918b76d" + resolved "https://registry.npmjs.org/pg-types/-/pg-types-4.0.2.tgz" integrity sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng== dependencies: pg-int8 "1.0.1" @@ -3234,9 +3196,9 @@ pg-types@^4.0.1: postgres-interval "^3.0.0" postgres-range "^1.1.1" -pg@^8.11.3: +pg@^8.11.3, pg@>=8.0: version "8.11.3" - resolved "https://registry.yarnpkg.com/pg/-/pg-8.11.3.tgz#d7db6e3fe268fcedd65b8e4599cda0b8b4bf76cb" + resolved "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz" integrity sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g== dependencies: buffer-writer "2.0.0" @@ -3251,39 +3213,39 @@ pg@^8.11.3: pgpass@1.x: version "1.0.5" - resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.5.tgz#9b873e4a564bb10fa7a7dbd55312728d422a223d" + resolved "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz" integrity sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug== dependencies: split2 "^4.1.0" picocolors@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== picomatch@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-3.0.1.tgz#817033161def55ec9638567a2f3bbc876b3e7516" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-3.0.1.tgz" integrity sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag== pidtree@^0.3.0: version "0.3.1" - resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.1.tgz#ef09ac2cc0533df1f3250ccf2c4d366b0d12114a" + resolved "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz" integrity sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA== pify@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + resolved "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz" integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== pino-abstract-transport@^1.0.0, pino-abstract-transport@v1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/pino-abstract-transport/-/pino-abstract-transport-1.1.0.tgz#083d98f966262164504afb989bccd05f665937a8" + resolved "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.1.0.tgz" integrity sha512-lsleG3/2a/JIWUtf9Q5gUNErBqwIu1tUKTT3dUzaf5DySw9ra1wcqKjJjLX1VTY64Wk1eEOYsVGSaGfCK85ekA== dependencies: readable-stream "^4.0.0" @@ -3291,7 +3253,7 @@ pino-abstract-transport@^1.0.0, pino-abstract-transport@v1.1.0: pino-http@^8.5.1: version "8.6.1" - resolved "https://registry.yarnpkg.com/pino-http/-/pino-http-8.6.1.tgz#46338caea759c9c86fc44f3226ed6976364ec269" + resolved "https://registry.npmjs.org/pino-http/-/pino-http-8.6.1.tgz" integrity sha512-J0hiJgUExtBXP2BjrK4VB305tHXS31sCmWJ9XJo2wPkLHa1NFPuW4V9wjG27PAc2fmBCigiNhQKpvrx+kntBPA== dependencies: get-caller-file "^2.0.5" @@ -3301,7 +3263,7 @@ pino-http@^8.5.1: pino-pretty@^10.2.3: version "10.3.1" - resolved "https://registry.yarnpkg.com/pino-pretty/-/pino-pretty-10.3.1.tgz#e3285a5265211ac6c7cd5988f9e65bf3371a0ca9" + resolved "https://registry.npmjs.org/pino-pretty/-/pino-pretty-10.3.1.tgz" integrity sha512-az8JbIYeN/1iLj2t0jR9DV48/LQ3RC6hZPpapKPkb84Q+yTidMCpgWxIT3N0flnBDilyBQ1luWNpOeJptjdp/g== dependencies: colorette "^2.0.7" @@ -3321,12 +3283,12 @@ pino-pretty@^10.2.3: pino-std-serializers@^6.0.0, pino-std-serializers@^6.2.2: version "6.2.2" - resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz#d9a9b5f2b9a402486a5fc4db0a737570a860aab3" + resolved "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz" integrity sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA== pino@^8.16.2, pino@^8.17.1: version "8.17.2" - resolved "https://registry.yarnpkg.com/pino/-/pino-8.17.2.tgz#0ed20175623a69d31664a1e8a5f85476272224be" + resolved "https://registry.npmjs.org/pino/-/pino-8.17.2.tgz" integrity sha512-LA6qKgeDMLr2ux2y/YiUt47EfgQ+S9LznBWOJdN3q1dx2sv0ziDLUBeVpyVv17TEcGCBuWf0zNtg3M5m1NhhWQ== dependencies: atomic-sleep "^1.0.0" @@ -3343,80 +3305,80 @@ pino@^8.16.2, pino@^8.17.1: please-upgrade-node@^3.2.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" + resolved "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz" integrity sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg== dependencies: semver-compare "^1.0.0" postgres-array@~2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e" + resolved "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz" integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA== postgres-array@~3.0.1: version "3.0.2" - resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-3.0.2.tgz#68d6182cb0f7f152a7e60dc6a6889ed74b0a5f98" + resolved "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.2.tgz" integrity sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog== postgres-bytea@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35" + resolved "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz" integrity sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w== postgres-bytea@~3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-3.0.0.tgz#9048dc461ac7ba70a6a42d109221619ecd1cb089" + resolved "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-3.0.0.tgz" integrity sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw== dependencies: obuf "~1.1.2" postgres-date@~1.0.4: version "1.0.7" - resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.7.tgz#51bc086006005e5061c591cee727f2531bf641a8" + resolved "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz" integrity sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q== postgres-date@~2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-2.1.0.tgz#b85d3c1fb6fb3c6c8db1e9942a13a3bf625189d0" + resolved "https://registry.npmjs.org/postgres-date/-/postgres-date-2.1.0.tgz" integrity sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA== postgres-interval@^1.1.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695" + resolved "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz" integrity sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ== dependencies: xtend "^4.0.0" postgres-interval@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-3.0.0.tgz#baf7a8b3ebab19b7f38f07566c7aab0962f0c86a" + resolved "https://registry.npmjs.org/postgres-interval/-/postgres-interval-3.0.0.tgz" integrity sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw== postgres-range@^1.1.1: version "1.1.4" - resolved "https://registry.yarnpkg.com/postgres-range/-/postgres-range-1.1.4.tgz#a59c5f9520909bcec5e63e8cf913a92e4c952863" + resolved "https://registry.npmjs.org/postgres-range/-/postgres-range-1.1.4.tgz" integrity sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w== prelude-ls@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== prettier-linter-helpers@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + resolved "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz" integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== dependencies: fast-diff "^1.1.2" -prettier@^3.1.0: +prettier@^2.0.0, prettier@^3.1.0, prettier@>=3.0.0: version "3.2.4" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.4.tgz#4723cadeac2ce7c9227de758e5ff9b14e075f283" + resolved "https://registry.npmjs.org/prettier/-/prettier-3.2.4.tgz" integrity sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ== pretty-quick@^3.1.3: version "3.3.1" - resolved "https://registry.yarnpkg.com/pretty-quick/-/pretty-quick-3.3.1.tgz#cfde97fec77a8d201a0e0c9c71d9990e12587ee2" + resolved "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.3.1.tgz" integrity sha512-3b36UXfYQ+IXXqex6mCca89jC8u0mYLqFAN5eTQKoXO6oCQYcIVYZEB/5AlBHI7JPYygReM2Vv6Vom/Gln7fBg== dependencies: execa "^4.1.0" @@ -3429,17 +3391,17 @@ pretty-quick@^3.1.3: process-warning@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-3.0.0.tgz#96e5b88884187a1dce6f5c3166d611132058710b" + resolved "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz" integrity sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ== process@^0.11.10: version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz" integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== proxy-addr@~2.0.7: version "2.0.7" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz" integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== dependencies: forwarded "0.2.0" @@ -3447,17 +3409,17 @@ proxy-addr@~2.0.7: proxy-from-env@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz" integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== pstree.remy@^1.1.8: version "1.1.8" - resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" + resolved "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz" integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== pump@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + resolved "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz" integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== dependencies: end-of-stream "^1.1.0" @@ -3465,41 +3427,41 @@ pump@^3.0.0: punycode@^2.1.0: version "2.3.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz" integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== qs@6.11.0: version "6.11.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + resolved "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz" integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== dependencies: side-channel "^1.0.4" queue-microtask@^1.2.2: version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== quick-format-unescaped@^4.0.3: version "4.0.4" - resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz#93ef6dd8d3453cbc7970dd614fad4c5954d6b5a7" + resolved "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz" integrity sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg== randombytes@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" range-parser@~1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== raw-body@2.5.1: version "2.5.1" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz" integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== dependencies: bytes "3.1.2" @@ -3507,16 +3469,9 @@ raw-body@2.5.1: iconv-lite "0.4.24" unpipe "1.0.0" -rdf-canonize@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/rdf-canonize/-/rdf-canonize-3.4.0.tgz#87f88342b173cc371d812a07de350f0c1aa9f058" - integrity sha512-fUeWjrkOO0t1rg7B2fdyDTvngj+9RlUyL92vOdiB7c0FPguWVsniIMjEtHH+meLBO9rzkUlUzBVXgWrjI8P9LA== - dependencies: - setimmediate "^1.0.5" - read-pkg@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz" integrity sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA== dependencies: load-json-file "^4.0.0" @@ -3525,7 +3480,7 @@ read-pkg@^3.0.0: readable-stream@^4.0.0: version "4.5.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-4.5.2.tgz#9e7fc4c45099baeed934bff6eb97ba6cf2729e09" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz" integrity sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g== dependencies: abort-controller "^3.0.0" @@ -3536,29 +3491,29 @@ readable-stream@^4.0.0: readdirp@~3.6.0: version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== dependencies: picomatch "^2.2.1" real-require@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/real-require/-/real-require-0.2.0.tgz#209632dea1810be2ae063a6ac084fee7e33fba78" + resolved "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz" integrity sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg== reflect-metadata@^0.1.13: version "0.1.14" - resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.14.tgz#24cf721fe60677146bb77eeb0e1f9dece3d65859" + resolved "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.14.tgz" integrity sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A== regenerator-runtime@^0.14.0: version "0.14.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz" integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== regexp.prototype.flags@^1.5.1: version "1.5.1" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz#90ce989138db209f81492edd734183ce99f9677e" + resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz" integrity sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg== dependencies: call-bind "^1.0.2" @@ -3567,17 +3522,17 @@ regexp.prototype.flags@^1.5.1: require-directory@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== resolve-from@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== resolve@^1.0.0, resolve@^1.10.0, resolve@^1.22.4: version "1.22.8" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz" integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== dependencies: is-core-module "^2.13.0" @@ -3586,7 +3541,7 @@ resolve@^1.0.0, resolve@^1.10.0, resolve@^1.22.4: restore-cursor@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz" integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== dependencies: onetime "^5.1.0" @@ -3594,52 +3549,52 @@ restore-cursor@^3.1.0: reusify@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== rfdc@^1.3.0: version "1.3.1" - resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.1.tgz#2b6d4df52dffe8bb346992a10ea9451f24373a8f" + resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz" integrity sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg== rimraf@^2.6.1: version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== dependencies: glob "^7.1.3" rimraf@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" rimraf@^5.0.1, rimraf@^5.0.5: version "5.0.5" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.5.tgz#9be65d2d6e683447d2e9013da2bf451139a61ccf" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz" integrity sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A== dependencies: glob "^10.3.7" run-parallel@^1.1.9: version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== dependencies: queue-microtask "^1.2.2" rxjs@^7.5.1: version "7.8.1" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" + resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz" integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== dependencies: tslib "^2.1.0" safe-array-concat@^1.0.1: version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.0.tgz#8d0cae9cb806d6d1c06e08ab13d847293ebe0692" + resolved "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz" integrity sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg== dependencies: call-bind "^1.0.5" @@ -3647,19 +3602,19 @@ safe-array-concat@^1.0.1: has-symbols "^1.0.3" isarray "^2.0.5" +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0, safe-buffer@5.2.1: + version "5.2.1" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + safe-buffer@5.1.2: version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - safe-regex-test@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.2.tgz#3ba32bdb3ea35f940ee87e5087c60ee786c3f6c5" + resolved "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.2.tgz" integrity sha512-83S9w6eFq12BBIJYvjMux6/dkirb8+4zJRA9cxNBVb7Wq5fJBW+Xze48WqR8pxua7bDuAaaAxtVVd4Idjp1dBQ== dependencies: call-bind "^1.0.5" @@ -3668,49 +3623,49 @@ safe-regex-test@^1.0.0: safe-stable-stringify@^2.3.1: version "2.4.3" - resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz#138c84b6f6edb3db5f8ef3ef7115b8f55ccbf886" + resolved "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz" integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g== "safer-buffer@>= 2.1.2 < 3": version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -schema-dts@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/schema-dts/-/schema-dts-1.1.2.tgz#82ccf71b5dcb80065a1cc5941888507a4ce1e44b" - integrity sha512-MpNwH0dZJHinVxk9bT8XUdjKTxMYrA5bLtrrGmFA6PTLwlOKnhi67XoRd6/ty+Djt6ZC0slR57qFhZDNMI6DhQ== - secure-json-parse@^2.4.0: version "2.7.0" - resolved "https://registry.yarnpkg.com/secure-json-parse/-/secure-json-parse-2.7.0.tgz#5a5f9cd6ae47df23dba3151edd06855d47e09862" + resolved "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz" integrity sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw== semver-compare@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" + resolved "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz" integrity sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow== -"semver@2 || 3 || 4 || 5", semver@^5.5.0: +semver@^5.5.0: version "5.7.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== semver@^6.3.1: version "6.3.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== semver@^7.5.3, semver@^7.5.4: version "7.5.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" +"semver@2 || 3 || 4 || 5": + version "5.7.2" + resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== + send@0.18.0: version "0.18.0" - resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + resolved "https://registry.npmjs.org/send/-/send-0.18.0.tgz" integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== dependencies: debug "2.6.9" @@ -3729,14 +3684,14 @@ send@0.18.0: serialize-javascript@6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz" integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== dependencies: randombytes "^2.1.0" serve-static@1.15.0: version "1.15.0" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz" integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== dependencies: encodeurl "~1.0.2" @@ -3746,7 +3701,7 @@ serve-static@1.15.0: set-function-length@^1.1.1: version "1.2.0" - resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.0.tgz#2f81dc6c16c7059bda5ab7c82c11f03a515ed8e1" + resolved "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz" integrity sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w== dependencies: define-data-property "^1.1.1" @@ -3757,55 +3712,50 @@ set-function-length@^1.1.1: set-function-name@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a" + resolved "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz" integrity sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA== dependencies: define-data-property "^1.0.1" functions-have-names "^1.2.3" has-property-descriptors "^1.0.0" -setimmediate@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== - setprototypeof@1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== shebang-command@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz" integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg== dependencies: shebang-regex "^1.0.0" shebang-command@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== dependencies: shebang-regex "^3.0.0" shebang-regex@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz" integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== shebang-regex@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== shell-quote@^1.6.1: version "1.8.1" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680" + resolved "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz" integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== side-channel@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== dependencies: call-bind "^1.0.0" @@ -3814,29 +3764,29 @@ side-channel@^1.0.4: signal-exit@^3.0.2, signal-exit@^3.0.3: version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== signal-exit@^4.0.1: version "4.1.0" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz" integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== simple-update-notifier@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz#d70b92bdab7d6d90dfd73931195a30b6e3d7cebb" + resolved "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz" integrity sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w== dependencies: semver "^7.5.3" slash@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== slice-ansi@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz" integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== dependencies: ansi-styles "^4.0.0" @@ -3845,7 +3795,7 @@ slice-ansi@^3.0.0: slice-ansi@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz" integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== dependencies: ansi-styles "^4.0.0" @@ -3854,14 +3804,14 @@ slice-ansi@^4.0.0: sonic-boom@^3.0.0, sonic-boom@^3.7.0: version "3.8.0" - resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-3.8.0.tgz#e442c5c23165df897d77c3c14ef3ca40dec66a66" + resolved "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.8.0.tgz" integrity sha512-ybz6OYOUjoQQCQ/i4LU8kaToD8ACtYP+Cj5qd2AO36bwbdewxWJ3ArmJ2cr6AvxlL2o0PqnCcPGUgkILbfkaCA== dependencies: atomic-sleep "^1.0.0" source-map-support@^0.5.12: version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== dependencies: buffer-from "^1.0.0" @@ -3869,12 +3819,12 @@ source-map-support@^0.5.12: source-map@^0.6.0: version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== spdx-correct@^3.0.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" + resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz" integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== dependencies: spdx-expression-parse "^3.0.0" @@ -3882,12 +3832,12 @@ spdx-correct@^3.0.0: spdx-exceptions@^2.1.0: version "2.4.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.4.0.tgz#c07a4ede25b16e4f78e6707bbd84b15a45c19c1b" + resolved "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.4.0.tgz" integrity sha512-hcjppoJ68fhxA/cjbN4T8N6uCUejN8yFw69ttpqtBeCbF3u13n7mb31NB9jKwGTTWWnt9IbRA/mf1FprYS8wfw== spdx-expression-parse@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + resolved "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz" integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== dependencies: spdx-exceptions "^2.1.0" @@ -3895,34 +3845,41 @@ spdx-expression-parse@^3.0.0: spdx-license-ids@^3.0.0: version "3.0.16" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz#a14f64e0954f6e25cc6587bd4f392522db0d998f" + resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz" integrity sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw== split2@^4.0.0, split2@^4.1.0: version "4.2.0" - resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" + resolved "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz" integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== statuses@2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== stop-iteration-iterator@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz#6a60be0b4ee757d1ed5254858ec66b10c49285e4" + resolved "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz" integrity sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ== dependencies: internal-slot "^1.0.4" +string_decoder@^1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + string-argv@0.3.1: version "0.3.1" - resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" + resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz" integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== "string-width-cjs@npm:string-width@^4.2.0": version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" @@ -3931,7 +3888,7 @@ string-argv@0.3.1: string-width@^4.1.0, string-width@^4.2.0: version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" @@ -3940,7 +3897,7 @@ string-width@^4.1.0, string-width@^4.2.0: string-width@^5.0.1, string-width@^5.1.2: version "5.1.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz" integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== dependencies: eastasianwidth "^0.2.0" @@ -3949,7 +3906,7 @@ string-width@^5.0.1, string-width@^5.1.2: string.prototype.padend@^3.0.0: version "3.1.5" - resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.1.5.tgz#311ef3a4e3c557dd999cdf88fbdde223f2ac0f95" + resolved "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.5.tgz" integrity sha512-DOB27b/2UTTD+4myKUFh+/fXWcu/UDyASIXfg+7VzoCNNGOfWvoyU/x5pvVHr++ztyt/oSYI1BcWBBG/hmlNjA== dependencies: call-bind "^1.0.2" @@ -3958,7 +3915,7 @@ string.prototype.padend@^3.0.0: string.prototype.trim@^1.2.8: version "1.2.8" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz#f9ac6f8af4bd55ddfa8895e6aea92a96395393bd" + resolved "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz" integrity sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ== dependencies: call-bind "^1.0.2" @@ -3967,7 +3924,7 @@ string.prototype.trim@^1.2.8: string.prototype.trimend@^1.0.7: version "1.0.7" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz#1bb3afc5008661d73e2dc015cd4853732d6c471e" + resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz" integrity sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA== dependencies: call-bind "^1.0.2" @@ -3976,23 +3933,16 @@ string.prototype.trimend@^1.0.7: string.prototype.trimstart@^1.0.7: version "1.0.7" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz#d4cdb44b83a4737ffbac2d406e405d43d0184298" + resolved "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz" integrity sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg== dependencies: call-bind "^1.0.2" define-properties "^1.2.0" es-abstract "^1.22.1" -string_decoder@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - stringify-object@^3.3.0: version "3.3.0" - resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" + resolved "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz" integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== dependencies: get-own-enumerable-property-symbols "^3.0.0" @@ -4001,74 +3951,74 @@ stringify-object@^3.3.0: "strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" strip-ansi@^7.0.1: version "7.1.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz" integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== dependencies: ansi-regex "^6.0.1" strip-bom@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== strip-final-newline@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== -strip-json-comments@3.1.1, strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - strip-json-comments@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz" integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== -supports-color@8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" +strip-json-comments@^3.1.1, strip-json-comments@3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== supports-color@^5.3.0, supports-color@^5.5.0: version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: has-flag "^3.0.0" supports-color@^7.1.0: version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== dependencies: has-flag "^4.0.0" +supports-color@8.1.1: + version "8.1.1" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== synckit@^0.8.6: version "0.8.8" - resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.8.tgz#fe7fe446518e3d3d49f5e429f443cf08b6edfcd7" + resolved "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz" integrity sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ== dependencies: "@pkgr/core" "^0.1.0" @@ -4076,58 +4026,58 @@ synckit@^0.8.6: text-table@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== thread-stream@^2.0.0: version "2.4.1" - resolved "https://registry.yarnpkg.com/thread-stream/-/thread-stream-2.4.1.tgz#6d588b14f0546e59d3f306614f044bc01ce43351" + resolved "https://registry.npmjs.org/thread-stream/-/thread-stream-2.4.1.tgz" integrity sha512-d/Ex2iWd1whipbT681JmTINKw0ZwOUBZm7+Gjs64DHuX34mmw8vJL2bFAaNacaW72zYiTJxSHi5abUuOi5nsfg== dependencies: real-require "^0.2.0" through@^2.3.8: version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== tiny-typed-emitter@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz#b3b027fdd389ff81a152c8e847ee2f5be9fad7b5" + resolved "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz" integrity sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA== to-regex-range@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== dependencies: is-number "^7.0.0" toidentifier@1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== touch@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" + resolved "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz" integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== dependencies: nopt "~1.0.10" tree-kill@^1.2.2: version "1.2.2" - resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" + resolved "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz" integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== ts-api-utils@^1.0.1: version "1.0.3" - resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.3.tgz#f12c1c781d04427313dbac808f453f050e54a331" + resolved "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz" integrity sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg== ts-node-dev@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/ts-node-dev/-/ts-node-dev-2.0.0.tgz#bdd53e17ab3b5d822ef519928dc6b4a7e0f13065" + resolved "https://registry.npmjs.org/ts-node-dev/-/ts-node-dev-2.0.0.tgz" integrity sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w== dependencies: chokidar "^3.5.1" @@ -4141,10 +4091,10 @@ ts-node-dev@^2.0.0: ts-node "^10.4.0" tsconfig "^7.0.0" -ts-node@10.9.1: - version "10.9.1" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" - integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== +ts-node@^10.4.0: + version "10.9.2" + resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz" + integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== dependencies: "@cspotcode/source-map-support" "^0.8.0" "@tsconfig/node10" "^1.0.7" @@ -4160,9 +4110,9 @@ ts-node@10.9.1: v8-compile-cache-lib "^3.0.1" yn "3.1.1" -ts-node@^10.4.0, ts-node@^10.9.1: +ts-node@^10.9.1: version "10.9.2" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f" + resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz" integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== dependencies: "@cspotcode/source-map-support" "^0.8.0" @@ -4179,9 +4129,28 @@ ts-node@^10.4.0, ts-node@^10.9.1: v8-compile-cache-lib "^3.0.1" yn "3.1.1" +ts-node@10.9.1: + version "10.9.1" + resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz" + integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + tsconfig-paths@^3.15.0: version "3.15.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4" + resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz" integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg== dependencies: "@types/json5" "^0.0.29" @@ -4191,7 +4160,7 @@ tsconfig-paths@^3.15.0: tsconfig@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/tsconfig/-/tsconfig-7.0.0.tgz#84538875a4dc216e5c4a5432b3a4dec3d54e91b7" + resolved "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz" integrity sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw== dependencies: "@types/strip-bom" "^3.0.0" @@ -4201,34 +4170,34 @@ tsconfig@^7.0.0: tslib@^2.1.0, tslib@^2.6.2: version "2.6.2" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== dependencies: prelude-ls "^1.2.1" type-detect@^4.0.0, type-detect@^4.0.5: version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== type-fest@^0.20.2: version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== type-fest@^0.21.3: version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== type-is@~1.6.18: version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz" integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== dependencies: media-typer "0.3.0" @@ -4236,7 +4205,7 @@ type-is@~1.6.18: typed-array-buffer@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60" + resolved "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz" integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== dependencies: call-bind "^1.0.2" @@ -4245,7 +4214,7 @@ typed-array-buffer@^1.0.0: typed-array-byte-length@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz#d787a24a995711611fb2b87a4052799517b230d0" + resolved "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz" integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== dependencies: call-bind "^1.0.2" @@ -4255,7 +4224,7 @@ typed-array-byte-length@^1.0.0: typed-array-byte-offset@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz#cbbe89b51fdef9cd6aaf07ad4707340abbc4ea0b" + resolved "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz" integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== dependencies: available-typed-arrays "^1.0.5" @@ -4266,21 +4235,21 @@ typed-array-byte-offset@^1.0.0: typed-array-length@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" + resolved "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz" integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== dependencies: call-bind "^1.0.2" for-each "^0.3.3" is-typed-array "^1.1.9" -typescript@5.1.6: +typescript@*, typescript@>=2.7, typescript@>=4.2.0, typescript@5.1.6: version "5.1.6" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" + resolved "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz" integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== unbox-primitive@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" + resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz" integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== dependencies: call-bind "^1.0.2" @@ -4290,51 +4259,44 @@ unbox-primitive@^1.0.2: undefsafe@^2.0.5: version "2.0.5" - resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" + resolved "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz" integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== undici-types@~5.26.4: version "5.26.5" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== -undici@^5.21.2: - version "5.28.2" - resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.2.tgz#fea200eac65fc7ecaff80a023d1a0543423b4c91" - integrity sha512-wh1pHJHnUeQV5Xa8/kyQhO7WFa8M34l026L5P/+2TYiakvGy5Rdc8jWZVyG7ieht/0WgJLEd3kcU5gKx+6GC8w== - dependencies: - "@fastify/busboy" "^2.0.0" - -unpipe@1.0.0, unpipe@~1.0.0: +unpipe@~1.0.0, unpipe@1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== uri-js@^4.2.2: version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" utils-merge@1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== uuid@^9.0.0, uuid@^9.0.1: version "9.0.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" + resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz" integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== v8-compile-cache-lib@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + resolved "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz" integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== validate-npm-package-license@^3.0.1: version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz" integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== dependencies: spdx-correct "^3.0.0" @@ -4342,17 +4304,12 @@ validate-npm-package-license@^3.0.1: vary@^1, vary@~1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== -web-streams-polyfill@^3.0.3: - version "3.3.2" - resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.3.2.tgz#32e26522e05128203a7de59519be3c648004343b" - integrity sha512-3pRGuxRF5gpuZc0W+EpwQRmCD7gRqcDOMt688KmdlDAgAyaB1XlN0zq2njfDNm44XVdIouE7pZ6GzbdyH47uIQ== - which-boxed-primitive@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz" integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== dependencies: is-bigint "^1.0.1" @@ -4363,7 +4320,7 @@ which-boxed-primitive@^1.0.2: which-collection@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906" + resolved "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz" integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== dependencies: is-map "^2.0.1" @@ -4373,7 +4330,7 @@ which-collection@^1.0.1: which-typed-array@^1.1.11, which-typed-array@^1.1.13: version "1.1.13" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.13.tgz#870cd5be06ddb616f504e7b039c4c24898184d36" + resolved "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz" integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow== dependencies: available-typed-arrays "^1.0.5" @@ -4384,26 +4341,26 @@ which-typed-array@^1.1.11, which-typed-array@^1.1.13: which@^1.2.9: version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: isexe "^2.0.0" which@^2.0.1: version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" workerpool@6.2.1: version "6.2.1" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" + resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz" integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== dependencies: ansi-styles "^4.0.0" @@ -4412,7 +4369,7 @@ workerpool@6.2.1: wrap-ansi@^6.2.0: version "6.2.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz" integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== dependencies: ansi-styles "^4.0.0" @@ -4421,7 +4378,7 @@ wrap-ansi@^6.2.0: wrap-ansi@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== dependencies: ansi-styles "^4.0.0" @@ -4430,7 +4387,7 @@ wrap-ansi@^7.0.0: wrap-ansi@^8.1.0: version "8.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz" integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== dependencies: ansi-styles "^6.1.0" @@ -4439,52 +4396,52 @@ wrap-ansi@^8.1.0: wrappy@1: version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== -ws@^8.14.2, ws@^8.7.0: +ws@*, ws@^8.14.2, ws@^8.7.0: version "8.16.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.16.0.tgz#d1cd774f36fbc07165066a60e40323eab6446fd4" + resolved "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz" integrity sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ== xstate@^4.37.0: version "4.38.3" - resolved "https://registry.yarnpkg.com/xstate/-/xstate-4.38.3.tgz#4e15e7ad3aa0ca1eea2010548a5379966d8f1075" + resolved "https://registry.npmjs.org/xstate/-/xstate-4.38.3.tgz" integrity sha512-SH7nAaaPQx57dx6qvfcIgqKRXIh4L0A1iYEqim4s1u7c9VoCgzZc+63FY90AKU4ZzOC2cfJzTnpO4zK7fCUzzw== xtend@^4.0.0: version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== y18n@^5.0.5: version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== yallist@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== yaml@^1.10.0: version "1.10.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - yargs-parser@^20.2.2: version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== +yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + yargs-unparser@2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + resolved "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz" integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== dependencies: camelcase "^6.0.0" @@ -4494,7 +4451,7 @@ yargs-unparser@2.0.0: yargs@16.2.0: version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + resolved "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz" integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== dependencies: cliui "^7.0.2" @@ -4507,15 +4464,15 @@ yargs@16.2.0: yn@3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + resolved "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz" integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== yocto-queue@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== zod@^3.22.4: version "3.22.4" - resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.4.tgz#f31c3a9386f61b1f228af56faa9255e845cf3fff" + resolved "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz" integrity sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg== From e2d3651b83c3108c737d73a84b9ac457c6a6e775 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Fri, 7 Jun 2024 11:25:16 +0000 Subject: [PATCH 088/278] add autostar optional param to update api --- desci-server/src/controllers/data/update.ts | 6 ++-- desci-server/src/services/data/processing.ts | 36 +++++++++++++++----- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/desci-server/src/controllers/data/update.ts b/desci-server/src/controllers/data/update.ts index 10d8e180..a7bbecb9 100644 --- a/desci-server/src/controllers/data/update.ts +++ b/desci-server/src/controllers/data/update.ts @@ -24,11 +24,11 @@ export interface ErrorResponse { export const update = async (req: RequestWithNode, res: Response) => { const owner = req.user; let node = req.node; - const { uuid, manifest: draftManifest, componentType, componentSubtype, newFolderName } = req.body; + const { uuid, manifest: draftManifest, componentType, componentSubtype, newFolderName, autoStar } = req.body; let { contextPath } = req.body; // debugger; if (contextPath.endsWith('/')) contextPath = contextPath.slice(0, -1); - + debugger; // temp workaround for non-file uploads if (!node) { node = await prisma.node.findFirst({ @@ -54,6 +54,7 @@ export const update = async (req: RequestWithNode, res: Response> { let pinResult: IpfsPinnedResult[] = []; let manifestPathsToTypesPrune: Record = {}; @@ -135,18 +139,28 @@ export async function processS3DataToIpfs({ // const ltsManifest = await getLatestManifestFromNode(ltsNode); let updatedManifest = await repoService.getDraftManifest(ltsNode.uuid as NodeUuid); + const { filteredFiles } = filterFirstNestings(pinResult); + if (componentTypeMap) { /** * Automatically create a new component(s) for the files added, to the first nesting. * It doesn't need to create a new component for every file, only the first nested ones, as inheritance takes care of the children files. * Only needs to happen if a predefined component type is to be added */ - // const firstNestingComponents = predefineComponentsForPinnedFiles({ - // pinnedFirstNestingFiles: filteredFiles, - // contextPath, - // componentType, - // componentSubtype, - // }); + if (autoStar) { + const firstNestingComponents = predefineComponentsForPinnedFiles({ + pinnedFirstNestingFiles: filteredFiles, + contextPath, + componentTypeMap, + star: true, + }); + const preparedComponents = prepareFirstNestingComponents(firstNestingComponents); + updatedManifest = await repoService.dispatchAction({ + type: 'Upsert Components', + components: preparedComponents, + }); + } + updatedManifest = await assignTypeMapInManifest(node, updatedManifest, componentTypeMap, contextPath, DRAFT_CID); logger.info({ updatedManifest }, 'assignTypeMapInManifest'); } @@ -459,9 +473,11 @@ export function updateManifestDataBucket({ manifest, newRootCid }: UpdatingManif interface PredefineComponentsForPinnedFilesParams { pinnedFirstNestingFiles: IpfsPinnedResult[]; contextPath: string; - componentType: ResearchObjectComponentType; + componentTypeMap?: ResearchObjectComponentTypeMap; + componentType?: ResearchObjectComponentType; componentSubtype?: ResearchObjectComponentSubtypes; externalUrl?: { url: string; path: string }; + star?: boolean; } /** @@ -472,7 +488,9 @@ export function predefineComponentsForPinnedFiles({ contextPath, componentType, componentSubtype, + componentTypeMap = {}, externalUrl, + star, }: PredefineComponentsForPinnedFilesParams): FirstNestingComponent[] { const firstNestingComponents: FirstNestingComponent[] = pinnedFirstNestingFiles.map((file) => { const neutralFullPath = contextPath + '/' + file.path; @@ -482,9 +500,9 @@ export function predefineComponentsForPinnedFiles({ name: name, path: neutralFullPath, cid: file.cid, - componentType, + componentType: componentType || extractComponentTypeFromTypeMap(neutralFullPath, componentTypeMap), componentSubtype, - // star: true, // removed; starring by default was unpopular + ...(star && { starred: star }), ...(externalUrl && { externalUrl: externalUrl.url }), }; }); From 0b6270268a6fad0d942f7647b5bfecd1892c764e Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Fri, 7 Jun 2024 11:29:23 +0000 Subject: [PATCH 089/278] logic fix --- desci-server/src/services/data/processing.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desci-server/src/services/data/processing.ts b/desci-server/src/services/data/processing.ts index f4522b47..c239cd51 100644 --- a/desci-server/src/services/data/processing.ts +++ b/desci-server/src/services/data/processing.ts @@ -502,7 +502,7 @@ export function predefineComponentsForPinnedFiles({ cid: file.cid, componentType: componentType || extractComponentTypeFromTypeMap(neutralFullPath, componentTypeMap), componentSubtype, - ...(star && { starred: star }), + ...(star && { star: true }), ...(externalUrl && { externalUrl: externalUrl.url }), }; }); From 2dd9ac1e7277794dee9e80d76f756a2894ffab93 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Fri, 7 Jun 2024 15:41:31 +0000 Subject: [PATCH 090/278] fix upsert calls --- desci-repo/package.json | 2 +- desci-repo/src/services/manifestRepo.ts | 2 +- desci-repo/yarn.lock | 499 ++++++++++--------- desci-server/package.json | 4 +- desci-server/src/services/data/processing.ts | 14 +- desci-server/yarn.lock | 41 +- 6 files changed, 321 insertions(+), 241 deletions(-) diff --git a/desci-repo/package.json b/desci-repo/package.json index e1257360..fc1e524a 100644 --- a/desci-repo/package.json +++ b/desci-repo/package.json @@ -68,7 +68,7 @@ "typescript": "5.1.6" }, "dependencies": { - "@desci-labs/desci-models": "0.2.7-rc1.5", + "@desci-labs/desci-models": "0.2.7-rc2.5", "@sentry/node": "^7.84.0", "@sentry/tracing": "^7.84.0", "axios": "^1.6.2", diff --git a/desci-repo/src/services/manifestRepo.ts b/desci-repo/src/services/manifestRepo.ts index 72d8a361..c87e8fcc 100644 --- a/desci-repo/src/services/manifestRepo.ts +++ b/desci-repo/src/services/manifestRepo.ts @@ -217,7 +217,7 @@ export const getDocumentUpdater = (documentId: DocumentId) => { ); break; case 'Upsert Components': - action.components.forEach((component) => { + action.component.forEach((component) => { handle.change( (document) => { upsertManifestComponent(document, component); diff --git a/desci-repo/yarn.lock b/desci-repo/yarn.lock index f3dbc5a2..0a73750a 100644 --- a/desci-repo/yarn.lock +++ b/desci-repo/yarn.lock @@ -27,10 +27,10 @@ "@automerge/automerge-repo" "1.1.0" rimraf "^5.0.1" -"@automerge/automerge-repo@^1.1.0": - version "1.1.1" - resolved "https://registry.npmjs.org/@automerge/automerge-repo/-/automerge-repo-1.1.1.tgz" - integrity sha512-fQq+4eUadubzHOUi2BIiC5f/XFUHixJ/kdfnbXRoh2xwzojMfQIlrRfZzxkuW5AdD9LOC2/LoWJs+ak4a9vq4Q== +"@automerge/automerge-repo@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@automerge/automerge-repo/-/automerge-repo-1.1.0.tgz" + integrity sha512-QRSt2s89Uhrlofbkipsb/9Alyp65/e1PocNzY+L4J7yDDXD7fbEW5uThXey2lSb1m98Fe0+NtzyKD1we6lvAkA== dependencies: "@automerge/automerge" "^2.1.9" bs58check "^3.0.1" @@ -43,10 +43,10 @@ uuid "^9.0.0" xstate "^4.37.0" -"@automerge/automerge-repo@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@automerge/automerge-repo/-/automerge-repo-1.1.0.tgz" - integrity sha512-QRSt2s89Uhrlofbkipsb/9Alyp65/e1PocNzY+L4J7yDDXD7fbEW5uThXey2lSb1m98Fe0+NtzyKD1we6lvAkA== +"@automerge/automerge-repo@^1.1.0": + version "1.1.1" + resolved "https://registry.npmjs.org/@automerge/automerge-repo/-/automerge-repo-1.1.1.tgz" + integrity sha512-fQq+4eUadubzHOUi2BIiC5f/XFUHixJ/kdfnbXRoh2xwzojMfQIlrRfZzxkuW5AdD9LOC2/LoWJs+ak4a9vq4Q== dependencies: "@automerge/automerge" "^2.1.9" bs58check "^3.0.1" @@ -94,11 +94,36 @@ chalk "^2.4.2" js-tokens "^4.0.0" +"@cbor-extract/cbor-extract-darwin-arm64@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@cbor-extract/cbor-extract-darwin-arm64/-/cbor-extract-darwin-arm64-2.2.0.tgz#8d65cb861a99622e1b4a268e2d522d2ec6137338" + integrity sha512-P7swiOAdF7aSi0H+tHtHtr6zrpF3aAq/W9FXx5HektRvLTM2O89xCyXF3pk7pLc7QpaY7AoaE8UowVf9QBdh3w== + +"@cbor-extract/cbor-extract-darwin-x64@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@cbor-extract/cbor-extract-darwin-x64/-/cbor-extract-darwin-x64-2.2.0.tgz#9fbec199c888c5ec485a1839f4fad0485ab6c40a" + integrity sha512-1liF6fgowph0JxBbYnAS7ZlqNYLf000Qnj4KjqPNW4GViKrEql2MgZnAsExhY9LSy8dnvA4C0qHEBgPrll0z0w== + +"@cbor-extract/cbor-extract-linux-arm64@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@cbor-extract/cbor-extract-linux-arm64/-/cbor-extract-linux-arm64-2.2.0.tgz#bf77e0db4a1d2200a5aa072e02210d5043e953ae" + integrity sha512-rQvhNmDuhjTVXSPFLolmQ47/ydGOFXtbR7+wgkSY0bdOxCFept1hvg59uiLPT2fVDuJFuEy16EImo5tE2x3RsQ== + +"@cbor-extract/cbor-extract-linux-arm@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@cbor-extract/cbor-extract-linux-arm/-/cbor-extract-linux-arm-2.2.0.tgz#491335037eb8533ed8e21b139c59f6df04e39709" + integrity sha512-QeBcBXk964zOytiedMPQNZr7sg0TNavZeuUCD6ON4vEOU/25+pLhNN6EDIKJ9VLTKaZ7K7EaAriyYQ1NQ05s/Q== + "@cbor-extract/cbor-extract-linux-x64@2.2.0": version "2.2.0" resolved "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-x64/-/cbor-extract-linux-x64-2.2.0.tgz" integrity sha512-cWLAWtT3kNLHSvP4RKDzSTX9o0wvQEEAj4SKvhWuOVZxiDAeQazr9A+PSiRILK1VYMLeDml89ohxCnUNQNQNCw== +"@cbor-extract/cbor-extract-win32-x64@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@cbor-extract/cbor-extract-win32-x64/-/cbor-extract-win32-x64-2.2.0.tgz#4b3f07af047f984c082de34b116e765cb9af975f" + integrity sha512-l2M+Z8DO2vbvADOBNLbbh9y5ST1RY5sqkWOg/58GkUPBYou/cuNZ68SGQ644f1CvZ8kcOxyZtw06+dxWHIoN/w== + "@cspotcode/source-map-support@^0.8.0": version "0.8.1" resolved "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz" @@ -106,13 +131,23 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@desci-labs/desci-models@file:../desci-models": +"@desci-labs/desci-models@0.2.7-rc2.5": version "0.2.7-rc2.5" - resolved "file:../desci-models" + resolved "https://registry.yarnpkg.com/@desci-labs/desci-models/-/desci-models-0.2.7-rc2.5.tgz#38f734db8de3386a214b59804a17472ef8cdcb97" + integrity sha512-K9sKQscay3u/YAZ2NghRJBUG9aLQFNQ4bCNWeYFO4+n536KcTQ74tElzci5UclxBozq7va8pGtoPyWM14yxkMw== dependencies: jsonld "^8.1.1" schema-dts "^1.1.2" +"@digitalbazaar/http-client@^3.4.1": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@digitalbazaar/http-client/-/http-client-3.4.1.tgz#5116fc44290d647cfe4b615d1f3fad9d6005e44d" + integrity sha512-Ahk1N+s7urkgj7WvvUND5f8GiWEPfUw0D41hdElaqLgu8wZScI8gdI0q+qWw5N1d35x7GCRH2uk9mi+Uzo9M3g== + dependencies: + ky "^0.33.3" + ky-universal "^0.11.0" + undici "^5.21.2" + "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" @@ -145,6 +180,11 @@ resolved "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz" integrity sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A== +"@fastify/busboy@^2.0.0": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.1.tgz#b9da6a878a371829a0502c9b6c1c143ef6663f4d" + integrity sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA== + "@humanwhocodes/config-array@^0.11.13": version "0.11.14" resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz" @@ -207,7 +247,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -474,17 +514,6 @@ semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/parser@^6.0.0 || ^6.0.0-alpha": - version "6.21.0" - resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz" - integrity sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ== - dependencies: - "@typescript-eslint/scope-manager" "6.21.0" - "@typescript-eslint/types" "6.21.0" - "@typescript-eslint/typescript-estree" "6.21.0" - "@typescript-eslint/visitor-keys" "6.21.0" - debug "^4.3.4" - "@typescript-eslint/scope-manager@6.20.0": version "6.20.0" resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.20.0.tgz" @@ -493,14 +522,6 @@ "@typescript-eslint/types" "6.20.0" "@typescript-eslint/visitor-keys" "6.20.0" -"@typescript-eslint/scope-manager@6.21.0": - version "6.21.0" - resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz" - integrity sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg== - dependencies: - "@typescript-eslint/types" "6.21.0" - "@typescript-eslint/visitor-keys" "6.21.0" - "@typescript-eslint/type-utils@6.20.0": version "6.20.0" resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.20.0.tgz" @@ -516,11 +537,6 @@ resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.20.0.tgz" integrity sha512-MM9mfZMAhiN4cOEcUOEx+0HmuaW3WBfukBZPCfwSqFnQy0grXYtngKCqpQN339X3RrwtzspWJrpbrupKYUSBXQ== -"@typescript-eslint/types@6.21.0": - version "6.21.0" - resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz" - integrity sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg== - "@typescript-eslint/typescript-estree@6.20.0": version "6.20.0" resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.20.0.tgz" @@ -535,20 +551,6 @@ semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/typescript-estree@6.21.0": - version "6.21.0" - resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz" - integrity sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ== - dependencies: - "@typescript-eslint/types" "6.21.0" - "@typescript-eslint/visitor-keys" "6.21.0" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - minimatch "9.0.3" - semver "^7.5.4" - ts-api-utils "^1.0.1" - "@typescript-eslint/utils@6.20.0": version "6.20.0" resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.20.0.tgz" @@ -570,14 +572,6 @@ "@typescript-eslint/types" "6.20.0" eslint-visitor-keys "^3.4.1" -"@typescript-eslint/visitor-keys@6.21.0": - version "6.21.0" - resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz" - integrity sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A== - dependencies: - "@typescript-eslint/types" "6.21.0" - eslint-visitor-keys "^3.4.1" - "@ungap/structured-clone@^1.2.0": version "1.2.0" resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz" @@ -613,7 +607,7 @@ acorn-walk@^8.1.1: resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz" integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A== -"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.4.1, acorn@^8.9.0: +acorn@^8.4.1, acorn@^8.9.0: version "8.11.3" resolved "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz" integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== @@ -636,16 +630,16 @@ ajv@^6.12.4: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ansi-colors@^4.1.1: - version "4.1.3" - resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz" - integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== - ansi-colors@4.1.1: version "4.1.1" resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== +ansi-colors@^4.1.1: + version "4.1.3" + resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz" + integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== + ansi-escapes@^4.3.0: version "4.3.2" resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" @@ -941,6 +935,11 @@ camelcase@^6.0.0: resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== +canonicalize@^1.0.1: + version "1.0.8" + resolved "https://registry.yarnpkg.com/canonicalize/-/canonicalize-1.0.8.tgz#24d1f1a00ed202faafd9bf8e63352cd4450c6df1" + integrity sha512-0CNTVCLZggSh7bc5VkX5WWPWO+cyZbNd07IHIsSXLia/eAq+r836hgk+8BKoEh7949Mda87VUOitx5OddVj64A== + cbor-extract@^2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/cbor-extract/-/cbor-extract-2.2.0.tgz" @@ -983,23 +982,7 @@ chalk@^2.4.1, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0: - version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chalk@^4.1.0: - version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chalk@^4.1.1: +chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: version "4.1.2" resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -1014,7 +997,7 @@ check-error@^1.0.2: dependencies: get-func-name "^2.0.2" -chokidar@^3.5.1, chokidar@^3.5.2, chokidar@3.5.3: +chokidar@3.5.3, chokidar@^3.5.1, chokidar@^3.5.2: version "3.5.3" resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== @@ -1049,13 +1032,13 @@ cli-truncate@^2.1.0: slice-ansi "^3.0.0" string-width "^4.2.0" -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== +cliui@^7.0.2, cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== dependencies: string-width "^4.2.0" - strip-ansi "^6.0.0" + strip-ansi "^6.0.1" wrap-ansi "^7.0.0" color-convert@^1.9.0: @@ -1072,16 +1055,16 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - color-name@1.1.3: version "1.1.3" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + colorette@^2.0.16, colorette@^2.0.7: version "2.0.20" resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz" @@ -1170,31 +1153,36 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +data-uri-to-buffer@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz#d8feb2b2881e6a4f58c2e08acfd0e2834e26222e" + integrity sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A== + dateformat@^4.6.3: version "4.6.3" resolved "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz" integrity sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA== -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== +debug@2.6.9: + version "2.6.9" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: - ms "^2.1.1" + ms "2.0.0" -debug@^4, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@4.3.4: +debug@4.3.4, debug@^4, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" -debug@2.6.9: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: - ms "2.0.0" + ms "^2.1.1" decamelize@^4.0.0: version "4.0.0" @@ -1260,7 +1248,7 @@ delayed-stream@~1.0.0: resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -depd@~2.0.0, depd@2.0.0: +depd@2.0.0, depd@~2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== @@ -1275,16 +1263,16 @@ detect-libc@^2.0.1: resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz" integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw== -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - diff@5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz" integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" @@ -1372,7 +1360,7 @@ end-of-stream@^1.1.0: dependencies: once "^1.4.0" -enquirer@^2.3.6, "enquirer@>= 2.3.0 < 3": +enquirer@^2.3.6: version "2.4.1" resolved "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz" integrity sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ== @@ -1482,17 +1470,17 @@ escape-html@~1.0.3: resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== +escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== -escape-string-regexp@^4.0.0, escape-string-regexp@4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -eslint-config-prettier@*, eslint-config-prettier@^9.1.0: +eslint-config-prettier@^9.1.0: version "9.1.0" resolved "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz" integrity sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw== @@ -1562,7 +1550,7 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4 resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== -"eslint@^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^7.0.0 || ^8.0.0", eslint@^8.55.0, eslint@>=7.0.0, eslint@>=8.0.0: +eslint@^8.55.0: version "8.56.0" resolved "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz" integrity sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ== @@ -1784,6 +1772,14 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" +fetch-blob@^3.1.2, fetch-blob@^3.1.4: + version "3.2.0" + resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-3.2.0.tgz#f09b8d4bbd45adc6f0c20b7e787e793e309dcce9" + integrity sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ== + dependencies: + node-domexception "^1.0.0" + web-streams-polyfill "^3.0.3" + file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" @@ -1811,6 +1807,14 @@ finalhandler@1.2.0: statuses "2.0.1" unpipe "~1.0.0" +find-up@5.0.0, find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + find-up@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" @@ -1819,14 +1823,6 @@ find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" -find-up@^5.0.0, find-up@5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - flat-cache@^3.0.4: version "3.2.0" resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz" @@ -1875,6 +1871,13 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +formdata-polyfill@^4.0.10: + version "4.0.10" + resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz#24807c31c9d402e002ab3d8c720144ceb8848423" + integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g== + dependencies: + fetch-blob "^3.1.2" + forwarded@0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" @@ -1890,6 +1893,11 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + function-bind@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" @@ -1969,6 +1977,18 @@ glob-parent@^6.0.2: dependencies: is-glob "^4.0.3" +glob@7.2.0: + version "7.2.0" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + glob@^10.3.7: version "10.3.10" resolved "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz" @@ -1992,18 +2012,6 @@ glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" -glob@7.2.0: - version "7.2.0" - resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - globals@^13.19.0: version "13.24.0" resolved "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz" @@ -2423,7 +2431,7 @@ js-tokens@^4.0.0: resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@^4.1.0, js-yaml@4.1.0: +js-yaml@4.1.0, js-yaml@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== @@ -2462,6 +2470,16 @@ json5@^1.0.2: dependencies: minimist "^1.2.0" +jsonld@^8.1.1: + version "8.3.2" + resolved "https://registry.yarnpkg.com/jsonld/-/jsonld-8.3.2.tgz#7033f8994aed346b536e9046025f7f1fe9669934" + integrity sha512-MwBbq95szLwt8eVQ1Bcfwmgju/Y5P2GdtlHE2ncyfuYjIdEhluUVyj1eudacf1mOkWIoS9GpDBTECqhmq7EOaA== + dependencies: + "@digitalbazaar/http-client" "^3.4.1" + canonicalize "^1.0.1" + lru-cache "^6.0.0" + rdf-canonize "^3.4.0" + jsonwebtoken@^9.0.2: version "9.0.2" resolved "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz" @@ -2502,6 +2520,19 @@ keyv@^4.5.3: dependencies: json-buffer "3.0.1" +ky-universal@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/ky-universal/-/ky-universal-0.11.0.tgz#f5edf857865aaaea416a1968222148ad7d9e4017" + integrity sha512-65KyweaWvk+uKKkCrfAf+xqN2/epw1IJDtlyCPxYffFCMR8u1sp2U65NtWpnozYfZxQ6IUzIlvUcw+hQ82U2Xw== + dependencies: + abort-controller "^3.0.0" + node-fetch "^3.2.10" + +ky@^0.33.3: + version "0.33.3" + resolved "https://registry.yarnpkg.com/ky/-/ky-0.33.3.tgz#bf1ad322a3f2c3428c13cfa4b3af95e6c4a2f543" + integrity sha512-CasD9OCEQSFIam2U8efFK81Yeg8vNMTBUqtMOHlrcWQHqUX3HeCl9Dr31u4toV7emlH8Mymk5+9p0lL6mKb/Xw== + levn@^0.4.1: version "0.4.1" resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" @@ -2613,7 +2644,7 @@ lodash.once@^4.0.0: resolved "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz" integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== -log-symbols@^4.1.0, log-symbols@4.1.0: +log-symbols@4.1.0, log-symbols@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== @@ -2708,20 +2739,6 @@ mimic-fn@^2.1.0: resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^9.0.1: - version "9.0.3" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== - dependencies: - brace-expansion "^2.0.1" - minimatch@5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz" @@ -2729,13 +2746,20 @@ minimatch@5.0.1: dependencies: brace-expansion "^2.0.1" -minimatch@9.0.3: +minimatch@9.0.3, minimatch@^9.0.1: version "9.0.3" resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz" integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== dependencies: brace-expansion "^2.0.1" +minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + minimist@^1.2.0, minimist@^1.2.6: version "1.2.8" resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" @@ -2794,11 +2818,6 @@ mri@^1.2.0: resolved "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz" integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA== -ms@^2.1.1, ms@2.1.3: - version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - ms@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" @@ -2809,6 +2828,11 @@ ms@2.1.2: resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + nanoid@3.3.3: version "3.3.3" resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz" @@ -2829,6 +2853,20 @@ nice-try@^1.0.4: resolved "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== +node-domexception@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" + integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== + +node-fetch@^3.2.10: + version "3.3.2" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.2.tgz#d1e889bacdf733b4ff3b2b243eb7a12866a0b78b" + integrity sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA== + dependencies: + data-uri-to-buffer "^4.0.0" + fetch-blob "^3.1.4" + formdata-polyfill "^4.0.10" + node-gyp-build-optional-packages@5.1.1: version "5.1.1" resolved "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.1.1.tgz" @@ -2967,13 +3005,6 @@ on-exit-leak-free@^2.1.0: resolved "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz" integrity sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA== -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz" - integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== - dependencies: - ee-first "1.1.1" - on-finished@2.4.1: version "2.4.1" resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" @@ -2981,6 +3012,13 @@ on-finished@2.4.1: dependencies: ee-first "1.1.1" +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz" + integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== + dependencies: + ee-first "1.1.1" + on-headers@~1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz" @@ -3196,7 +3234,7 @@ pg-types@^4.0.1: postgres-interval "^3.0.0" postgres-range "^1.1.1" -pg@^8.11.3, pg@>=8.0: +pg@^8.11.3: version "8.11.3" resolved "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz" integrity sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g== @@ -3371,7 +3409,7 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@^2.0.0, prettier@^3.1.0, prettier@>=3.0.0: +prettier@^3.1.0: version "3.2.4" resolved "https://registry.npmjs.org/prettier/-/prettier-3.2.4.tgz" integrity sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ== @@ -3469,6 +3507,13 @@ raw-body@2.5.1: iconv-lite "0.4.24" unpipe "1.0.0" +rdf-canonize@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/rdf-canonize/-/rdf-canonize-3.4.0.tgz#87f88342b173cc371d812a07de350f0c1aa9f058" + integrity sha512-fUeWjrkOO0t1rg7B2fdyDTvngj+9RlUyL92vOdiB7c0FPguWVsniIMjEtHH+meLBO9rzkUlUzBVXgWrjI8P9LA== + dependencies: + setimmediate "^1.0.5" + read-pkg@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz" @@ -3602,16 +3647,16 @@ safe-array-concat@^1.0.1: has-symbols "^1.0.3" isarray "^2.0.5" -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0, safe-buffer@5.2.1: - version "5.2.1" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - safe-buffer@5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + safe-regex-test@^1.0.0: version "1.0.2" resolved "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.2.tgz" @@ -3631,6 +3676,11 @@ safe-stable-stringify@^2.3.1: resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +schema-dts@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/schema-dts/-/schema-dts-1.1.2.tgz#82ccf71b5dcb80065a1cc5941888507a4ce1e44b" + integrity sha512-MpNwH0dZJHinVxk9bT8XUdjKTxMYrA5bLtrrGmFA6PTLwlOKnhi67XoRd6/ty+Djt6ZC0slR57qFhZDNMI6DhQ== + secure-json-parse@^2.4.0: version "2.7.0" resolved "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz" @@ -3641,7 +3691,7 @@ semver-compare@^1.0.0: resolved "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz" integrity sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow== -semver@^5.5.0: +"semver@2 || 3 || 4 || 5", semver@^5.5.0: version "5.7.2" resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== @@ -3658,11 +3708,6 @@ semver@^7.5.3, semver@^7.5.4: dependencies: lru-cache "^6.0.0" -"semver@2 || 3 || 4 || 5": - version "5.7.2" - resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz" - integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== - send@0.18.0: version "0.18.0" resolved "https://registry.npmjs.org/send/-/send-0.18.0.tgz" @@ -3719,6 +3764,11 @@ set-function-name@^2.0.0: functions-have-names "^1.2.3" has-property-descriptors "^1.0.0" +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== + setprototypeof@1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" @@ -3865,13 +3915,6 @@ stop-iteration-iterator@^1.0.0: dependencies: internal-slot "^1.0.4" -string_decoder@^1.3.0: - version "1.3.0" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - string-argv@0.3.1: version "0.3.1" resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz" @@ -3940,6 +3983,13 @@ string.prototype.trimstart@^1.0.7: define-properties "^1.2.0" es-abstract "^1.22.1" +string_decoder@^1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + stringify-object@^3.3.0: version "3.3.0" resolved "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz" @@ -3980,15 +4030,22 @@ strip-final-newline@^2.0.0: resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== +strip-json-comments@3.1.1, strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + strip-json-comments@^2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz" integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== -strip-json-comments@^3.1.1, strip-json-comments@3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +supports-color@8.1.1: + version "8.1.1" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" supports-color@^5.3.0, supports-color@^5.5.0: version "5.5.0" @@ -4004,13 +4061,6 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" -supports-color@8.1.1: - version "8.1.1" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" @@ -4091,10 +4141,10 @@ ts-node-dev@^2.0.0: ts-node "^10.4.0" tsconfig "^7.0.0" -ts-node@^10.4.0: - version "10.9.2" - resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz" - integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== +ts-node@10.9.1: + version "10.9.1" + resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz" + integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== dependencies: "@cspotcode/source-map-support" "^0.8.0" "@tsconfig/node10" "^1.0.7" @@ -4110,7 +4160,7 @@ ts-node@^10.4.0: v8-compile-cache-lib "^3.0.1" yn "3.1.1" -ts-node@^10.9.1: +ts-node@^10.4.0, ts-node@^10.9.1: version "10.9.2" resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz" integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== @@ -4129,25 +4179,6 @@ ts-node@^10.9.1: v8-compile-cache-lib "^3.0.1" yn "3.1.1" -ts-node@10.9.1: - version "10.9.1" - resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz" - integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== - dependencies: - "@cspotcode/source-map-support" "^0.8.0" - "@tsconfig/node10" "^1.0.7" - "@tsconfig/node12" "^1.0.7" - "@tsconfig/node14" "^1.0.0" - "@tsconfig/node16" "^1.0.2" - acorn "^8.4.1" - acorn-walk "^8.1.1" - arg "^4.1.0" - create-require "^1.1.0" - diff "^4.0.1" - make-error "^1.1.1" - v8-compile-cache-lib "^3.0.1" - yn "3.1.1" - tsconfig-paths@^3.15.0: version "3.15.0" resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz" @@ -4242,7 +4273,7 @@ typed-array-length@^1.0.4: for-each "^0.3.3" is-typed-array "^1.1.9" -typescript@*, typescript@>=2.7, typescript@>=4.2.0, typescript@5.1.6: +typescript@5.1.6: version "5.1.6" resolved "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz" integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== @@ -4267,7 +4298,14 @@ undici-types@~5.26.4: resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== -unpipe@~1.0.0, unpipe@1.0.0: +undici@^5.21.2: + version "5.28.4" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.4.tgz#6b280408edb6a1a604a9b20340f45b422e373068" + integrity sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g== + dependencies: + "@fastify/busboy" "^2.0.0" + +unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== @@ -4307,6 +4345,11 @@ vary@^1, vary@~1.1.2: resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== +web-streams-polyfill@^3.0.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz#2073b91a2fdb1fbfbd401e7de0ac9f8214cecb4b" + integrity sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw== + which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz" @@ -4399,7 +4442,7 @@ wrappy@1: resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== -ws@*, ws@^8.14.2, ws@^8.7.0: +ws@^8.14.2, ws@^8.7.0: version "8.16.0" resolved "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz" integrity sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ== @@ -4429,16 +4472,16 @@ yaml@^1.10.0: resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - yargs-parser@20.2.4: version "20.2.4" resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz" integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + yargs-unparser@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz" diff --git a/desci-server/package.json b/desci-server/package.json index 86eb086b..ccd5af30 100755 --- a/desci-server/package.json +++ b/desci-server/package.json @@ -55,7 +55,7 @@ "@automerge/automerge-repo": "^1.0.19", "@automerge/automerge-repo-network-websocket": "^1.0.19", "@aws-sdk/client-s3": "^3.537.0", - "@desci-labs/desci-models": "link:./desci-models", + "@desci-labs/desci-models": "0.2.7-rc2.5", "@honeycombio/opentelemetry-node": "^0.3.2", "@ipld/dag-pb": "^4.0.0", "@opentelemetry/api": "^1.8.0", @@ -174,4 +174,4 @@ "prisma": { "seed": "node --no-warnings=ExperimentalWarning --loader ts-node/esm prisma/seed.ts" } -} +} \ No newline at end of file diff --git a/desci-server/src/services/data/processing.ts b/desci-server/src/services/data/processing.ts index c239cd51..dd110eb2 100644 --- a/desci-server/src/services/data/processing.ts +++ b/desci-server/src/services/data/processing.ts @@ -155,10 +155,18 @@ export async function processS3DataToIpfs({ star: true, }); const preparedComponents = prepareFirstNestingComponents(firstNestingComponents); - updatedManifest = await repoService.dispatchAction({ - type: 'Upsert Components', - components: preparedComponents, + + const updatedDoc = await repoService.dispatchAction({ + uuid: node.uuid as NodeUuid, + documentId: node.manifestDocumentId as DocumentId, + actions: [ + { + type: 'Upsert Components', + component: preparedComponents, + }, + ], }); + updatedManifest = updatedDoc.manifest; } updatedManifest = await assignTypeMapInManifest(node, updatedManifest, componentTypeMap, contextPath, DRAFT_CID); diff --git a/desci-server/yarn.lock b/desci-server/yarn.lock index 60f309f2..b8e8a8cd 100644 --- a/desci-server/yarn.lock +++ b/desci-server/yarn.lock @@ -1635,9 +1635,13 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@desci-labs/desci-models@link:./desci-models": - version "0.0.0" - uid "" +"@desci-labs/desci-models@0.2.7-rc2.5": + version "0.2.7-rc2.5" + resolved "https://registry.yarnpkg.com/@desci-labs/desci-models/-/desci-models-0.2.7-rc2.5.tgz#38f734db8de3386a214b59804a17472ef8cdcb97" + integrity sha512-K9sKQscay3u/YAZ2NghRJBUG9aLQFNQ4bCNWeYFO4+n536KcTQ74tElzci5UclxBozq7va8pGtoPyWM14yxkMw== + dependencies: + jsonld "^8.1.1" + schema-dts "^1.1.2" "@digitalbazaar/http-client@^3.4.1": version "3.4.1" @@ -12846,7 +12850,16 @@ string-template@~0.2.1: resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" integrity sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw== -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -12919,7 +12932,7 @@ stringify-object@3.3.0: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -12933,6 +12946,13 @@ strip-ansi@^3.0.0: dependencies: ansi-regex "^2.0.0" +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-ansi@^7.0.1: version "7.1.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" @@ -13812,7 +13832,7 @@ workerpool@6.2.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -13830,6 +13850,15 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" From c90420c8c619f19a5355a041310f08eb60a2acc2 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Fri, 7 Jun 2024 17:50:38 +0000 Subject: [PATCH 091/278] autostar logic fix --- .vscode/launch.json | 2 +- desci-server/nodemon.json | 2 +- desci-server/src/controllers/data/update.ts | 1 - desci-server/src/services/data/processing.ts | 3 ++- docker-compose.dev.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 99647a2a..f6b0be3f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,7 +9,7 @@ "type": "node", "request": "attach", "restart": true, - "port": 9229, + "port": 9228, "address": "localhost", "localRoot": "${workspaceFolder}", "remoteRoot": "/app" diff --git a/desci-server/nodemon.json b/desci-server/nodemon.json index b343dff9..c24de8fa 100644 --- a/desci-server/nodemon.json +++ b/desci-server/nodemon.json @@ -7,7 +7,7 @@ "log/server.log" ], "verbose": true, - "exec": "node -r ts-node/register --inspect=0.0.0.0", + "exec": "node -r ts-node/register --inspect=0.0.0.0:9228", "delay": 300, "signal": "SIGTERM" } \ No newline at end of file diff --git a/desci-server/src/controllers/data/update.ts b/desci-server/src/controllers/data/update.ts index a7bbecb9..0a56d0c0 100644 --- a/desci-server/src/controllers/data/update.ts +++ b/desci-server/src/controllers/data/update.ts @@ -28,7 +28,6 @@ export const update = async (req: RequestWithNode, res: Response Date: Sat, 8 Jun 2024 06:18:17 +0000 Subject: [PATCH 092/278] add autopinning flag to external url uploads --- desci-server/src/controllers/data/update.ts | 1 + desci-server/src/services/data/externalUrlProcessing.ts | 3 +++ 2 files changed, 4 insertions(+) diff --git a/desci-server/src/controllers/data/update.ts b/desci-server/src/controllers/data/update.ts index 0a56d0c0..c7491808 100644 --- a/desci-server/src/controllers/data/update.ts +++ b/desci-server/src/controllers/data/update.ts @@ -113,6 +113,7 @@ export const update = async (req: RequestWithNode, res: Response 0) { From 568e2d436718c7399b3e56a52da27b0fce82d596 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Sat, 8 Jun 2024 06:20:42 +0000 Subject: [PATCH 093/278] model fixes, bump rc3 --- desci-models/package.json | 2 +- desci-models/src/automerge.ts | 2 +- desci-repo/src/services/manifestRepo.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/desci-models/package.json b/desci-models/package.json index ae4fbcbd..46452dbd 100644 --- a/desci-models/package.json +++ b/desci-models/package.json @@ -1,6 +1,6 @@ { "name": "@desci-labs/desci-models", - "version": "0.2.7-rc2.5", + "version": "0.2.7-rc3", "description": "Data models for DeSci Nodes", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/desci-models/src/automerge.ts b/desci-models/src/automerge.ts index fd5ca2ba..f0e91e14 100644 --- a/desci-models/src/automerge.ts +++ b/desci-models/src/automerge.ts @@ -36,7 +36,7 @@ export type ManifestActions = | { type: 'Update ResearchFields'; researchFields: string[] } | { type: 'Add Component'; component: ResearchObjectV1Component } | { type: 'Upsert Component'; component: ResearchObjectV1Component } - | { type: 'Upsert Components'; component: ResearchObjectV1Component[] } + | { type: 'Upsert Components'; components: ResearchObjectV1Component[] } | { type: 'Delete Component'; path: string } | { type: 'Add Contributor'; author: ResearchObjectV1Author } | { type: 'Remove Contributor'; contributorIndex: number } diff --git a/desci-repo/src/services/manifestRepo.ts b/desci-repo/src/services/manifestRepo.ts index c87e8fcc..72d8a361 100644 --- a/desci-repo/src/services/manifestRepo.ts +++ b/desci-repo/src/services/manifestRepo.ts @@ -217,7 +217,7 @@ export const getDocumentUpdater = (documentId: DocumentId) => { ); break; case 'Upsert Components': - action.component.forEach((component) => { + action.components.forEach((component) => { handle.change( (document) => { upsertManifestComponent(document, component); From f32292f6108393c853c74e6c4a49644b5c7ebe21 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Sat, 8 Jun 2024 06:43:03 +0000 Subject: [PATCH 094/278] model bump to 0.2.7-rc3 for server/repo --- desci-repo/package.json | 2 +- desci-server/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/desci-repo/package.json b/desci-repo/package.json index fc1e524a..3d5bd7bc 100644 --- a/desci-repo/package.json +++ b/desci-repo/package.json @@ -68,7 +68,7 @@ "typescript": "5.1.6" }, "dependencies": { - "@desci-labs/desci-models": "0.2.7-rc2.5", + "@desci-labs/desci-models": "0.2.7-rc3", "@sentry/node": "^7.84.0", "@sentry/tracing": "^7.84.0", "axios": "^1.6.2", diff --git a/desci-server/package.json b/desci-server/package.json index ccd5af30..bf462d4f 100755 --- a/desci-server/package.json +++ b/desci-server/package.json @@ -55,7 +55,7 @@ "@automerge/automerge-repo": "^1.0.19", "@automerge/automerge-repo-network-websocket": "^1.0.19", "@aws-sdk/client-s3": "^3.537.0", - "@desci-labs/desci-models": "0.2.7-rc2.5", + "@desci-labs/desci-models": "0.2.7-rc3", "@honeycombio/opentelemetry-node": "^0.3.2", "@ipld/dag-pb": "^4.0.0", "@opentelemetry/api": "^1.8.0", From c976d14e9a65932c0b2beb44e4b733a5f9d1d6a3 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Sat, 8 Jun 2024 06:44:28 +0000 Subject: [PATCH 095/278] fix for updated models --- desci-server/src/services/data/processing.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desci-server/src/services/data/processing.ts b/desci-server/src/services/data/processing.ts index cf260e93..9c26195b 100644 --- a/desci-server/src/services/data/processing.ts +++ b/desci-server/src/services/data/processing.ts @@ -163,7 +163,7 @@ export async function processS3DataToIpfs({ actions: [ { type: 'Upsert Components', - component: preparedComponents, + components: preparedComponents, }, ], }); From d7565ad834a208fff9334a7ac81ba621a29eaf5f Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Mon, 10 Jun 2024 12:22:28 +0000 Subject: [PATCH 096/278] push lock file updates --- desci-repo/yarn.lock | 8 ++++---- desci-server/yarn.lock | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/desci-repo/yarn.lock b/desci-repo/yarn.lock index 0a73750a..a87fb260 100644 --- a/desci-repo/yarn.lock +++ b/desci-repo/yarn.lock @@ -131,10 +131,10 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@desci-labs/desci-models@0.2.7-rc2.5": - version "0.2.7-rc2.5" - resolved "https://registry.yarnpkg.com/@desci-labs/desci-models/-/desci-models-0.2.7-rc2.5.tgz#38f734db8de3386a214b59804a17472ef8cdcb97" - integrity sha512-K9sKQscay3u/YAZ2NghRJBUG9aLQFNQ4bCNWeYFO4+n536KcTQ74tElzci5UclxBozq7va8pGtoPyWM14yxkMw== +"@desci-labs/desci-models@0.2.7-rc3": + version "0.2.7-rc3" + resolved "https://registry.yarnpkg.com/@desci-labs/desci-models/-/desci-models-0.2.7-rc3.tgz#b033073e6b77edde85491731d5c03469f443aaa1" + integrity sha512-RL1vwUHTumpmj7goX6+AcSVt0MGpdm4QWZ20gkmE9+BlL1eIxX+oQzQFmW92XXHWUQOETIaL1YnHsGCVz4gJNw== dependencies: jsonld "^8.1.1" schema-dts "^1.1.2" diff --git a/desci-server/yarn.lock b/desci-server/yarn.lock index b8e8a8cd..7357a32d 100644 --- a/desci-server/yarn.lock +++ b/desci-server/yarn.lock @@ -1635,10 +1635,10 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@desci-labs/desci-models@0.2.7-rc2.5": - version "0.2.7-rc2.5" - resolved "https://registry.yarnpkg.com/@desci-labs/desci-models/-/desci-models-0.2.7-rc2.5.tgz#38f734db8de3386a214b59804a17472ef8cdcb97" - integrity sha512-K9sKQscay3u/YAZ2NghRJBUG9aLQFNQ4bCNWeYFO4+n536KcTQ74tElzci5UclxBozq7va8pGtoPyWM14yxkMw== +"@desci-labs/desci-models@0.2.7-rc3": + version "0.2.7-rc3" + resolved "https://registry.yarnpkg.com/@desci-labs/desci-models/-/desci-models-0.2.7-rc3.tgz#b033073e6b77edde85491731d5c03469f443aaa1" + integrity sha512-RL1vwUHTumpmj7goX6+AcSVt0MGpdm4QWZ20gkmE9+BlL1eIxX+oQzQFmW92XXHWUQOETIaL1YnHsGCVz4gJNw== dependencies: jsonld "^8.1.1" schema-dts "^1.1.2" From 2128f69aee3094252aebc3899583b3270899d27c Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Tue, 11 Jun 2024 13:14:07 +0200 Subject: [PATCH 097/278] remove unnecessary message from api res --- desci-server/src/core/ApiResponse.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/desci-server/src/core/ApiResponse.ts b/desci-server/src/core/ApiResponse.ts index 0b8d0481..50964273 100644 --- a/desci-server/src/core/ApiResponse.ts +++ b/desci-server/src/core/ApiResponse.ts @@ -40,7 +40,7 @@ export abstract class ApiResponse { } export class SuccessMessageResponse extends ApiResponse { - constructor(_message = '') { + constructor(message = '') { super(ResponseStatus.SUCCESS, undefined); } } @@ -48,7 +48,7 @@ export class SuccessMessageResponse extends ApiResponse { export class SuccessResponse extends ApiResponse { constructor( private data: T, - message = 'Success', + message = '', ) { super(ResponseStatus.SUCCESS, message); } From ffc10963628de9d85a65a840835e7faae690d3b7 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Tue, 11 Jun 2024 16:55:37 +0200 Subject: [PATCH 098/278] add nodesUserId field to ManifestAuthor --- desci-models/package.json | 6 +++--- desci-models/src/ResearchObject.ts | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/desci-models/package.json b/desci-models/package.json index 46452dbd..e90cb595 100644 --- a/desci-models/package.json +++ b/desci-models/package.json @@ -1,6 +1,6 @@ { "name": "@desci-labs/desci-models", - "version": "0.2.7-rc3", + "version": "0.2.7-rc4", "description": "Data models for DeSci Nodes", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -15,7 +15,7 @@ "scripts": { "test": "mocha -r ts-node/register --inspect tests/**/*.test.ts", "coverage": "nyc -r lcov -e .ts -x \"*.test.ts\" npm run test", - "build": "tsc", + "build": "tsc && npm run generate", "doPublish": "npm publish --access public", "generate": "ts-interface-builder src/ResearchObject.ts src/RoCrate.ts --ignore-generics" }, @@ -38,4 +38,4 @@ "ts-node": "^10.9.1", "typescript": "^4.9.4" } -} \ No newline at end of file +} diff --git a/desci-models/src/ResearchObject.ts b/desci-models/src/ResearchObject.ts index 29b83796..9e2c7faf 100644 --- a/desci-models/src/ResearchObject.ts +++ b/desci-models/src/ResearchObject.ts @@ -108,6 +108,8 @@ export interface ResearchObjectV1Author { organizations?: ResearchObjectV1Organization[]; /** GitHub profile of the contributor */ github?: string; + /** Desci Nodes user id */ + nodesUserId?: string; } export interface ResearchObjectV1History { From e23fe0f7f4835bb8477386cf3f6f8cbab034f03f Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Tue, 11 Jun 2024 17:06:00 +0200 Subject: [PATCH 099/278] make noseUserId a number --- desci-models/package.json | 2 +- desci-models/src/ResearchObject.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/desci-models/package.json b/desci-models/package.json index e90cb595..354f6b9f 100644 --- a/desci-models/package.json +++ b/desci-models/package.json @@ -1,6 +1,6 @@ { "name": "@desci-labs/desci-models", - "version": "0.2.7-rc4", + "version": "0.2.7-rc5", "description": "Data models for DeSci Nodes", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/desci-models/src/ResearchObject.ts b/desci-models/src/ResearchObject.ts index 9e2c7faf..ece6739d 100644 --- a/desci-models/src/ResearchObject.ts +++ b/desci-models/src/ResearchObject.ts @@ -109,7 +109,7 @@ export interface ResearchObjectV1Author { /** GitHub profile of the contributor */ github?: string; /** Desci Nodes user id */ - nodesUserId?: string; + nodesUserId?: number; } export interface ResearchObjectV1History { From 7ba4b992b044f6935f7602d43c6188d2f3920738 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Wed, 12 Jun 2024 17:30:12 +0200 Subject: [PATCH 100/278] add traceIds to logs and also fix ipfs image imports --- desci-server/scripts/be-node-dev.sh | 6 +++ desci-server/scripts/import-ipfs-content.sh | 4 ++ desci-server/src/logger.ts | 46 +++++++++++++++++++- desci-server/src/middleware/authorisation.ts | 2 + desci-server/src/server.ts | 35 +++++++++++++-- 5 files changed, 88 insertions(+), 5 deletions(-) create mode 100755 desci-server/scripts/import-ipfs-content.sh diff --git a/desci-server/scripts/be-node-dev.sh b/desci-server/scripts/be-node-dev.sh index 3a794168..75b8bae2 100755 --- a/desci-server/scripts/be-node-dev.sh +++ b/desci-server/scripts/be-node-dev.sh @@ -14,6 +14,12 @@ chmod -R 777 /app/node_modules/prisma cd desci-server yarn run migrate npx prisma db seed + +# import required images from ipfs to local +echo "Hi" +chmod +x ./scripts/import-ipfs-content.sh +./scripts/import-ipfs-content.sh + # note: for local dev, you can probably import dpid 46 using the following script, however it doesn't work due to local IPFS client not being open to the public (swarm key) # when you set NODE_ENV=prod, it uses the public IPFS reader. Need to adjust this for local dev so we can properly import in the future # NODE_ENV=prod OPERATION=fillPublic USER_EMAIL=noreply@desci.com NODE_UUID=pOV6-0ZN8k8Nlb3iJ7BHgbHt4V_xt-H-dUbRQCLKl78. npm run script:fix-data-refs diff --git a/desci-server/scripts/import-ipfs-content.sh b/desci-server/scripts/import-ipfs-content.sh new file mode 100755 index 00000000..56dfc408 --- /dev/null +++ b/desci-server/scripts/import-ipfs-content.sh @@ -0,0 +1,4 @@ +# import required images from ipfs to local + +wget https://ipfs.desci.com/ipfs/bafkreih6yx7ywj7trvpp45vergrnytad7ezsku75tefyro4qrrcfrrmrt4 -O /tmp/cover.png +curl -F file=@/tmp/cover.png "http://host.docker.internal:5001/api/v0/add?cid-version=1" \ No newline at end of file diff --git a/desci-server/src/logger.ts b/desci-server/src/logger.ts index 530ad52e..5cb7acf2 100644 --- a/desci-server/src/logger.ts +++ b/desci-server/src/logger.ts @@ -1,11 +1,13 @@ +import { AsyncLocalStorage } from 'async_hooks'; import path from 'path'; import { fileURLToPath } from 'url'; import { pino } from 'pino'; - const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); +export const als = new AsyncLocalStorage(); + const logLevel = process.env.PINO_LOG_LEVEL || 'trace'; const devTransport = { @@ -29,6 +31,48 @@ export const logger = pino({ serializers: { files: omitBuffer, }, + hooks: { + logMethod: function (inputArgs, method) { + //get caller + const stack = new Error().stack.split('\n'); + // find first line that is not from this file + + let callerFilePath; + try { + callerFilePath = stack + .filter((a) => a.includes('file:///') && !a.includes('src/logger.ts'))[0] + .split('(')[1] + .split(')')[0] + .replace('file:///app/desci-server/src/', ''); + } catch (err) { + // callerFilePath = '-unknown-'; + } + + const target = typeof inputArgs[0] == 'string' ? 1 : 0; + const newInputArgs = [...inputArgs]; + if (!newInputArgs[target]) { + newInputArgs[target] = {}; + } + + newInputArgs[target]['caller'] = callerFilePath; + + newInputArgs[target]['userAuth'] = (als.getStore() as any)?.userAuth; + + const traceId = (als.getStore() as any)?.traceId; + if (traceId) { + newInputArgs[target]['traceId'] = traceId; + + const timingArray = (als.getStore() as any)?.timing; + if (timingArray) { + newInputArgs[target]['traceIndex'] = timingArray.length; + newInputArgs[target]['traceDelta'] = Date.now() - timingArray[timingArray.length - 1]; + } + (als.getStore() as any)?.timing.push(Date.now()); + } + + return method.apply(this, [...newInputArgs]); + }, + }, transport: process.env.NODE_ENV === 'production' ? undefined diff --git a/desci-server/src/middleware/authorisation.ts b/desci-server/src/middleware/authorisation.ts index c45b604a..de46735f 100644 --- a/desci-server/src/middleware/authorisation.ts +++ b/desci-server/src/middleware/authorisation.ts @@ -10,6 +10,8 @@ import { ensureUuidEndsWithDot, hideEmail } from '../utils.js'; export interface RequestWithUser extends Request { user: User; + userAuth?: any; + traceId?: string; } export interface RequestWithNode extends RequestWithUser { diff --git a/desci-server/src/server.ts b/desci-server/src/server.ts index 41c754c3..49f319ab 100644 --- a/desci-server/src/server.ts +++ b/desci-server/src/server.ts @@ -5,7 +5,6 @@ import * as child from 'child_process'; // import fs from 'fs'; import type { Server as HttpServer } from 'http'; // import path from 'path'; -import { fileURLToPath } from 'url'; import * as Sentry from '@sentry/node'; import * as Tracing from '@sentry/tracing'; @@ -24,13 +23,12 @@ import routes from './routes/index.js'; import { orcidConnect } from './controllers/auth/orcid.js'; import { orcidCheck } from './controllers/auth/orcidNext.js'; // import SocketServer from './wsServer.js'; -import { NotFoundError } from './internal.js'; -import { logger } from './logger.js'; +import { NotFoundError, RequestWithUser, extractAuthToken, extractUserFromToken } from './internal.js'; +import { als, logger } from './logger.js'; import { ensureUserIfPresent } from './middleware/ensureUserIfPresent.js'; import { errorHandler } from './middleware/errorHandler.js'; import { runWorkerUntilStopped } from './workers/publish.js'; -const __filename = fileURLToPath(import.meta.url); // const __dirname = path.dirname(__filename); const ENABLE_TELEMETRY = process.env.NODE_ENV === 'production'; @@ -90,6 +88,30 @@ class AppServer { next(); }); + // // attach user info to every request + this.app.use(async (req: RequestWithUser, res, next) => { + const token = await extractAuthToken(req); + + if (!token) { + req.userAuth = 'anonymous'; + } else { + const user = await extractUserFromToken(token); + req.userAuth = `${user?.id}`; + } + + next(); + }); + + // attach trace id to every request + this.app.use((req: RequestWithUser, res, next) => { + req.traceId = v4(); + res.header('X-Desci-Trace-Id', req.traceId); + + als.run({ traceId: req.traceId, timing: [new Date()], userAuth: req.userAuth }, () => { + next(); + }); + }); + this.#attachProxies(); this.#initTelemetry(); @@ -162,6 +184,11 @@ class AppServer { this.app.use( pinoHttp({ logger, + customProps: (req: RequestWithUser, res) => ({ + userAuth: req.userAuth, + traceId: (als.getStore() as any)?.traceId, + http: true, + }), serializers: { res: (res) => { if (IS_DEV) { From 8382d3295ba388a0ff6906d00f96c11d157cda65 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Wed, 12 Jun 2024 17:34:28 +0200 Subject: [PATCH 101/278] clean up --- desci-server/scripts/be-node-dev.sh | 1 - desci-server/src/server.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/desci-server/scripts/be-node-dev.sh b/desci-server/scripts/be-node-dev.sh index 75b8bae2..6d84bbd5 100755 --- a/desci-server/scripts/be-node-dev.sh +++ b/desci-server/scripts/be-node-dev.sh @@ -16,7 +16,6 @@ yarn run migrate npx prisma db seed # import required images from ipfs to local -echo "Hi" chmod +x ./scripts/import-ipfs-content.sh ./scripts/import-ipfs-content.sh diff --git a/desci-server/src/server.ts b/desci-server/src/server.ts index 49f319ab..cd47bdbd 100644 --- a/desci-server/src/server.ts +++ b/desci-server/src/server.ts @@ -187,7 +187,7 @@ class AppServer { customProps: (req: RequestWithUser, res) => ({ userAuth: req.userAuth, traceId: (als.getStore() as any)?.traceId, - http: true, + http: 1, }), serializers: { res: (res) => { From 8bfce9816e7380fe28472a78e46112120e6a9646 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Wed, 12 Jun 2024 17:54:57 +0200 Subject: [PATCH 102/278] fix caller in prod --- desci-server/src/logger.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desci-server/src/logger.ts b/desci-server/src/logger.ts index 5cb7acf2..f304a212 100644 --- a/desci-server/src/logger.ts +++ b/desci-server/src/logger.ts @@ -40,7 +40,7 @@ export const logger = pino({ let callerFilePath; try { callerFilePath = stack - .filter((a) => a.includes('file:///') && !a.includes('src/logger.ts'))[0] + .filter((a) => a.includes('file:///') && !a.includes('src/logger.'))[0] .split('(')[1] .split(')')[0] .replace('file:///app/desci-server/src/', ''); From dcdbdad1672fe522e1be3019a8ac7a046d102e82 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Wed, 12 Jun 2024 17:59:07 +0200 Subject: [PATCH 103/278] add x-forwarded-for to logs to get client IP instead of local ip --- desci-server/src/server.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/desci-server/src/server.ts b/desci-server/src/server.ts index cd47bdbd..392fecc1 100644 --- a/desci-server/src/server.ts +++ b/desci-server/src/server.ts @@ -188,6 +188,7 @@ class AppServer { userAuth: req.userAuth, traceId: (als.getStore() as any)?.traceId, http: 1, + remoteAddress: getRemoteAddress(req), }), serializers: { res: (res) => { @@ -243,5 +244,12 @@ class AppServer { await runWorkerUntilStopped(); } } - +function getRemoteAddress(req) { + const xForwardedFor = req.headers['x-forwarded-for']; + if (xForwardedFor) { + return xForwardedFor.split(',')[0].trim(); + } else { + return req.socket.remoteAddress; + } +} export const server = new AppServer(); From 0d427e5546f71907eb68193c47e05d230c460720 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Wed, 12 Jun 2024 19:07:08 +0200 Subject: [PATCH 104/278] fix caller filename for prod --- desci-server/src/logger.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desci-server/src/logger.ts b/desci-server/src/logger.ts index f304a212..15ea90e4 100644 --- a/desci-server/src/logger.ts +++ b/desci-server/src/logger.ts @@ -40,7 +40,7 @@ export const logger = pino({ let callerFilePath; try { callerFilePath = stack - .filter((a) => a.includes('file:///') && !a.includes('src/logger.'))[0] + .filter((a) => a.includes('file:///') && !(a.includes('/dist/logger.') || a.includes('/src/logger.')))[0] .split('(')[1] .split(')')[0] .replace('file:///app/desci-server/src/', ''); From 51ed4ae3a06d49c1e6c5ff211065260b98f878f0 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Wed, 12 Jun 2024 19:39:34 +0200 Subject: [PATCH 105/278] clean up caller filename for prod --- desci-server/src/logger.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/desci-server/src/logger.ts b/desci-server/src/logger.ts index 15ea90e4..61a09637 100644 --- a/desci-server/src/logger.ts +++ b/desci-server/src/logger.ts @@ -43,7 +43,8 @@ export const logger = pino({ .filter((a) => a.includes('file:///') && !(a.includes('/dist/logger.') || a.includes('/src/logger.')))[0] .split('(')[1] .split(')')[0] - .replace('file:///app/desci-server/src/', ''); + .replace('file:///app/desci-server/src/', '') + .replace('file:///app/dist/', ''); } catch (err) { // callerFilePath = '-unknown-'; } From b66f9853bb03bf28722e630b0982355f923dc8b4 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Wed, 12 Jun 2024 19:52:48 +0200 Subject: [PATCH 106/278] set logs to trace for common verbose logs related to auth --- desci-server/src/middleware/permissions.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/desci-server/src/middleware/permissions.ts b/desci-server/src/middleware/permissions.ts index 13a7f55c..1e9b33c1 100644 --- a/desci-server/src/middleware/permissions.ts +++ b/desci-server/src/middleware/permissions.ts @@ -40,7 +40,7 @@ export const extractAuthToken = async (request: ExpressRequest | Request) => { if (authHeader) { token = authHeader.split(' ')[1]; } - logger.info({ module: 'Permissions::extractToken', authHeaderLength: authHeader?.length || 0 }, 'Request'); + logger.trace({ module: 'Permissions::extractToken', authHeaderLength: authHeader?.length || 0 }, 'Request'); // Sanitize null or undefined string tokens passed from frontend if (token === 'null' || token === 'undefined') token = null; @@ -56,7 +56,7 @@ export const extractTokenFromCookie = async (request: ExpressRequest | Request, let token: string | undefined; // get from query string token = request.url.split(`${tokenName}=`)[1]; - logger.info({ url: request.url, token }, 'got url extract'); + logger.trace({ url: request.url, token }, 'got url extract'); if (!token) { // If auth token wasn't found in the header, try retrieve from cookies @@ -73,7 +73,7 @@ export const extractTokenFromCookie = async (request: ExpressRequest | Request, .filter(([key]) => key.trim().toLowerCase() === tokenName)[0]; token = parsedTokenValue?.[1]; } - logger.info({ tokenFound: !!token, tokenName }, 'COOKIE'); + logger.trace({ tokenFound: !!token, tokenName }, 'COOKIE'); } return token; }; @@ -96,7 +96,7 @@ export const extractUserFromToken = async (token: string): Promise return; } - logger.info({ module: 'ExtractAuthUser', user, tokenFound: !!token }, 'User decrypted'); + logger.trace({ module: 'ExtractAuthUser', user, tokenFound: !!token }, 'User decrypted'); if (!user) { resolve(null); @@ -127,7 +127,7 @@ export const extractUserFromToken = async (token: string): Promise */ export const extractApiKey = async (request: ExpressRequest | Request) => { const apiKeyHeader = request.headers['api-key']; - logger.info({ module: 'Permissions::extractApiKey', apiKeyLength: apiKeyHeader?.length || 0 }, 'Request'); + logger.trace({ module: 'Permissions::extractApiKey', apiKeyLength: apiKeyHeader?.length || 0 }, 'Request'); return apiKeyHeader; }; From 8025b817125245ceff1ab961f666721687e1e9ca Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Wed, 12 Jun 2024 21:22:36 +0200 Subject: [PATCH 107/278] set publish queue to trace instead of info level logs --- desci-server/src/workers/publish.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/desci-server/src/workers/publish.ts b/desci-server/src/workers/publish.ts index 9eba6971..8d20eaad 100644 --- a/desci-server/src/workers/publish.ts +++ b/desci-server/src/workers/publish.ts @@ -70,7 +70,7 @@ async function processPublishQueue() { } else if (txStatus === 0) { await prisma.publishTaskQueue.update({ where: { id: task.id }, data: { status: PublishTaskQueueStatus.FAILED } }); lockService.freeLock(task.transactionId); - if (!process.env.MUTE_PUBLISH_WORKER) logger.info({ txStatus }, 'PUBLISH TX FAILED'); + if (!process.env.MUTE_PUBLISH_WORKER) logger.error({ txStatus }, 'PUBLISH TX FAILED'); } else { await prisma.publishTaskQueue.update({ where: { id: task.id }, @@ -94,16 +94,16 @@ const dequeueTask = async () => { if (!tasks.length) { tasks = await prisma.publishTaskQueue.findMany({ where: { status: PublishTaskQueueStatus.PENDING }, take: 5 }); } - if (!process.env.MUTE_PUBLISH_WORKER) logger.info({ tasks }, 'TASKS'); + if (!process.env.MUTE_PUBLISH_WORKER) logger.trace({ tasks }, 'TASKS'); for (const task of tasks) { const taskLock = await lockService.aquireLock(task.transactionId); - logger.info({ taskLock, task }, 'ATTEMPT TO ACQUIRE LOCK'); + logger.trace({ taskLock, task }, 'ATTEMPT TO ACQUIRE LOCK'); if (taskLock) { nextTask = task; break; } } - if (!process.env.MUTE_PUBLISH_WORKER) logger.info({ nextTask }, 'DEQUEUE TASK'); + if (!process.env.MUTE_PUBLISH_WORKER) logger.trace({ nextTask }, 'DEQUEUE TASK'); return nextTask; }; @@ -114,7 +114,7 @@ const delay = async (timeMs: number) => { export async function runWorkerUntilStopped() { while (true) { const outcome = await processPublishQueue(); - if (!process.env.MUTE_PUBLISH_WORKER) logger.info({ outcome }, 'Processed Queue'); + if (!process.env.MUTE_PUBLISH_WORKER) logger.trace({ outcome }, 'Processed Queue'); switch (outcome) { case ProcessOutcome.EmptyQueue: await delay(10000); From 4b5b3e4f6c090bdb34235a98553daa33e30afdbd Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Wed, 12 Jun 2024 22:10:24 +0200 Subject: [PATCH 108/278] change api to use uuid instead of dpid for claiming attestations, enabling draft nodes to claim attestations --- .../migration.sql | 2 ++ desci-server/prisma/schema.prisma | 2 +- desci-server/src/controllers/attestations/show.ts | 10 +++++----- desci-server/src/routes/v1/attestations/index.ts | 2 +- desci-server/src/routes/v1/attestations/schema.ts | 8 ++++---- desci-server/src/services/Attestation.ts | 5 +++-- 6 files changed, 16 insertions(+), 13 deletions(-) create mode 100644 desci-server/prisma/migrations/20240612181102_node_attestation_dpid_optional/migration.sql diff --git a/desci-server/prisma/migrations/20240612181102_node_attestation_dpid_optional/migration.sql b/desci-server/prisma/migrations/20240612181102_node_attestation_dpid_optional/migration.sql new file mode 100644 index 00000000..69548293 --- /dev/null +++ b/desci-server/prisma/migrations/20240612181102_node_attestation_dpid_optional/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "NodeAttestation" ALTER COLUMN "nodeDpid10" DROP NOT NULL; diff --git a/desci-server/prisma/schema.prisma b/desci-server/prisma/schema.prisma index 9890e9c0..47bdcd7c 100755 --- a/desci-server/prisma/schema.prisma +++ b/desci-server/prisma/schema.prisma @@ -751,7 +751,7 @@ model NodeAttestation { community DesciCommunity @relation(fields: [desciCommunityId], references: [id]) claimedById Int claimedBy User @relation(fields: [claimedById], references: [id]) - nodeDpid10 String + nodeDpid10 String? nodeUuid String node Node @relation(fields: [nodeUuid], references: [uuid]) nodeVersion Int diff --git a/desci-server/src/controllers/attestations/show.ts b/desci-server/src/controllers/attestations/show.ts index 26c8ee12..118666b3 100644 --- a/desci-server/src/controllers/attestations/show.ts +++ b/desci-server/src/controllers/attestations/show.ts @@ -21,21 +21,21 @@ type ShowNodeAttestationsResponse = { }; export const showNodeAttestations = async ( - req: Request<{ dpid: string }>, + req: Request<{ uuid: string }>, res: Response, ) => { - const { dpid } = req.params; + const { uuid } = req.params; const logger = parentLogger.child({ module: 'ATTESTATIONS::showNodeAttestationsController', user: (req as any).user, - dpid, + uuid, }); logger.trace(`showNodeAttestations`); - if (!dpid) throw new BadRequestError('DPID is required'); + if (!uuid) throw new BadRequestError('uuid is required'); - let attestations = await attestationService.getAllNodeAttestations(dpid); + let attestations = await attestationService.getAllNodeAttestations(uuid); attestations = attestations.map((att) => ({ ...att, _count: undefined, diff --git a/desci-server/src/routes/v1/attestations/index.ts b/desci-server/src/routes/v1/attestations/index.ts index 359e3693..50961b87 100644 --- a/desci-server/src/routes/v1/attestations/index.ts +++ b/desci-server/src/routes/v1/attestations/index.ts @@ -49,7 +49,7 @@ router.get( asyncHander(showCommunityClaims), ); -router.get('/:dpid', [validate(showNodeAttestationsSchema)], asyncHander(showNodeAttestations)); +router.get('/:uuid', [validate(showNodeAttestationsSchema)], asyncHander(showNodeAttestations)); router.get('/:claimId/reactions', [validate(getAttestationReactionsSchema)], asyncHander(getAttestationReactions)); router.get( '/:claimId/verifications', diff --git a/desci-server/src/routes/v1/attestations/schema.ts b/desci-server/src/routes/v1/attestations/schema.ts index a720edf2..7a8ec37e 100644 --- a/desci-server/src/routes/v1/attestations/schema.ts +++ b/desci-server/src/routes/v1/attestations/schema.ts @@ -12,7 +12,7 @@ export const showCommunityClaimsSchema = z.object({ export const showNodeAttestationsSchema = z.object({ params: z.object({ - dpid, + uuid: z.string(), }), }); @@ -149,7 +149,7 @@ export const claimAttestationSchema = z.object({ attestationId: z.coerce.number(), nodeVersion: z.coerce.number(), nodeUuid: z.string(), - nodeDpid: z.string(), + nodeDpid: z.string().optional(), claimerId: z.coerce.number(), }), }); @@ -159,14 +159,14 @@ export const claimEntryAttestationsSchema = z.object({ communityId: z.coerce.number(), nodeVersion: z.coerce.number(), nodeUuid: z.string(), - nodeDpid: z.string(), + nodeDpid: z.string().optional(), claimerId: z.coerce.number(), }), }); export const removeClaimSchema = z.object({ body: z.object({ - dpid, + dpid: z.coerce.number().optional(), nodeUuid: z.string(), claimId: z.coerce.number(), }), diff --git a/desci-server/src/services/Attestation.ts b/desci-server/src/services/Attestation.ts index 8ac23c94..c862354f 100644 --- a/desci-server/src/services/Attestation.ts +++ b/desci-server/src/services/Attestation.ts @@ -18,6 +18,7 @@ import { NoAccessError, VerificationError, VerificationNotFoundError, + ensureUuidEndsWithDot, logger, } from '../internal.js'; import { communityService } from '../internal.js'; @@ -229,9 +230,9 @@ export class AttestationService { }); } - async getAllNodeAttestations(dpid: string) { + async getAllNodeAttestations(uuid: string) { return prisma.nodeAttestation.findMany({ - where: { nodeDpid10: dpid, revoked: false }, + where: { nodeUuid: ensureUuidEndsWithDot(uuid), revoked: false }, include: { community: { select: { name: true, description: true, keywords: true, image_url: true } }, attestation: { select: { protected: true, verified_image_url: true } }, From 8ebc4072cc4b3d04cc5090035582dc955a747324 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Wed, 12 Jun 2024 22:34:04 +0200 Subject: [PATCH 109/278] ensure we can unclaim draft attestations, only show published nodes on community radar --- desci-server/src/controllers/attestations/claims.ts | 2 +- desci-server/src/services/Attestation.ts | 4 ++++ desci-server/src/services/Communities.ts | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/desci-server/src/controllers/attestations/claims.ts b/desci-server/src/controllers/attestations/claims.ts index 58e5c782..5e72e313 100644 --- a/desci-server/src/controllers/attestations/claims.ts +++ b/desci-server/src/controllers/attestations/claims.ts @@ -106,7 +106,7 @@ export const removeClaim = async (req: RequestWithUser, res: Response, _next: Ne const node = await prisma.node.findFirst({ where: { uuid: body.nodeUuid } }); if (!node) throw new NotFoundError('Node not found'); - const claim = await attestationService.getClaimOnDpid(body.claimId, body.dpid.toString()); + const claim = await attestationService.getClaimOnUuid(body.claimId, body.nodeUuid); if (!claim) throw new NotFoundError(); if (node.ownerId !== req.user.id || claim.claimedById !== req.user.id) throw new AuthFailureError(); diff --git a/desci-server/src/services/Attestation.ts b/desci-server/src/services/Attestation.ts index c862354f..5e8604d6 100644 --- a/desci-server/src/services/Attestation.ts +++ b/desci-server/src/services/Attestation.ts @@ -446,6 +446,10 @@ export class AttestationService { return prisma.nodeAttestation.findFirst({ where: { id, nodeDpid10 } }); } + async getClaimOnUuid(id: number, nodeUuid: string) { + return prisma.nodeAttestation.findFirst({ where: { id, nodeUuid } }); + } + async verifyClaim(nodeAttestationId: number, userId: number) { assert(nodeAttestationId > 0, 'Error: nodeAttestationId is Zero'); assert(userId > 0, 'Error: userId is Zero'); diff --git a/desci-server/src/services/Communities.ts b/desci-server/src/services/Communities.ts index 1b1d83e5..ab01d5a4 100644 --- a/desci-server/src/services/Communities.ts +++ b/desci-server/src/services/Communities.ts @@ -95,7 +95,7 @@ export class CommunityService { left outer JOIN "Annotation" ON t1."id" = "Annotation"."nodeAttestationId" left outer JOIN "NodeAttestationReaction" ON t1."id" = "NodeAttestationReaction"."nodeAttestationId" left outer JOIN "NodeAttestationVerification" ON t1."id" = "NodeAttestationVerification"."nodeAttestationId" - WHERE t1."revoked" = false AND + WHERE t1."revoked" = false AND t1."nodeDpid10" IS NOT NULL AND EXISTS (SELECT * from "CommunityEntryAttestation" c1 From 0dc3c48155974d81ebaf093f2f8c7993a008508c Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Wed, 12 Jun 2024 22:44:07 +0200 Subject: [PATCH 110/278] fix tests --- desci-server/test/integration/Attestation.test.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/desci-server/test/integration/Attestation.test.ts b/desci-server/test/integration/Attestation.test.ts index da7efad8..71a9cbc7 100644 --- a/desci-server/test/integration/Attestation.test.ts +++ b/desci-server/test/integration/Attestation.test.ts @@ -337,7 +337,7 @@ describe('Attestations Service', async () => { expect(res.status).to.equal(200); // verify only one claim exists on the old version of the node - const attestations = await attestationService.getAllNodeAttestations('1'); + const attestations = await attestationService.getAllNodeAttestations(node.uuid); expect(attestations.length).to.equal(2); }); }); @@ -1508,7 +1508,7 @@ describe('Attestations Service', async () => { it('should show DPID 1 node attestations(API)', async () => { const JwtToken = jwt.sign({ email: users[0].email }, process.env.JWT_SECRET!, { expiresIn: '1y' }); const authHeaderVal = `Bearer ${JwtToken}`; - const res = await request(app).get(`/v1/attestations/${1}`).set('authorization', authHeaderVal); + const res = await request(app).get(`/v1/attestations/${node1.uuid}`).set('authorization', authHeaderVal); const attestations: NodeAttestationFragment[] = res.body.data; console.log(attestations); expect(attestations.length).to.be.equal(3); @@ -1518,7 +1518,7 @@ describe('Attestations Service', async () => { it('should show DPID 2 node attestations(API)', async () => { const JwtToken = jwt.sign({ email: users[0].email }, process.env.JWT_SECRET!, { expiresIn: '1y' }); const authHeaderVal = `Bearer ${JwtToken}`; - const res = await request(app).get(`/v1/attestations/${2}`).set('authorization', authHeaderVal); + const res = await request(app).get(`/v1/attestations/${node2.uuid}`).set('authorization', authHeaderVal); const attestations: NodeAttestationFragment[] = res.body.data; expect(attestations.length).to.be.equal(4); }); @@ -2029,7 +2029,7 @@ describe('Attestations Service', async () => { }); expect(res.status).to.equal(200); - const claims = await attestationService.getAllNodeAttestations('1'); + const claims = await attestationService.getAllNodeAttestations(node.uuid); expect(claims.length).to.equal(1); }); @@ -2077,7 +2077,7 @@ describe('Attestations Service', async () => { }); expect(res.status).to.equal(200); - const attestations = await attestationService.getAllNodeAttestations('1'); + const attestations = await attestationService.getAllNodeAttestations(node.uuid); expect(attestations.length).to.equal(2); res = await request(app).get(`/v1/attestations/${1}`).set('authorization', authHeaderVal); From 0a7b119d094d969468d674ccb660945886dd8457 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Thu, 13 Jun 2024 14:50:42 +0000 Subject: [PATCH 111/278] remove duplicate port under same service --- docker-compose.dev.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index a6e4e0ba..0daceff5 100755 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -54,7 +54,6 @@ services: - "5420:5420" - "9228:9228" - "9277:9277" - - "9228:9228" - "5555:5555" extra_hosts: - host.docker.internal:host-gateway From dac36064e41cd857740bc0ac4ad35a1376e4bbe2 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Thu, 13 Jun 2024 17:44:44 +0200 Subject: [PATCH 112/278] fix issue with logger --- desci-server/src/logger.ts | 76 ++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 31 deletions(-) diff --git a/desci-server/src/logger.ts b/desci-server/src/logger.ts index 61a09637..12709058 100644 --- a/desci-server/src/logger.ts +++ b/desci-server/src/logger.ts @@ -33,45 +33,59 @@ export const logger = pino({ }, hooks: { logMethod: function (inputArgs, method) { - //get caller - const stack = new Error().stack.split('\n'); - // find first line that is not from this file - - let callerFilePath; try { - callerFilePath = stack - .filter((a) => a.includes('file:///') && !(a.includes('/dist/logger.') || a.includes('/src/logger.')))[0] - .split('(')[1] - .split(')')[0] - .replace('file:///app/desci-server/src/', '') - .replace('file:///app/dist/', ''); - } catch (err) { - // callerFilePath = '-unknown-'; - } + //get caller + const stack = new Error().stack.split('\n'); + // find first line that is not from this file + + let callerFilePath; + try { + const intermediate = stack.filter( + (a) => a.includes('file:///') && !(a.includes('/dist/logger.') || a.includes('/src/logger.')), + )[0]; + + if (intermediate) { + callerFilePath = intermediate + .split('(')[1] + .split(')')[0] + .replace('file:///app/desci-server/src/', '') + .replace('file:///app/dist/', ''); + } + } catch (err) { + // callerFilePath = '-unknown-'; + } - const target = typeof inputArgs[0] == 'string' ? 1 : 0; - const newInputArgs = [...inputArgs]; - if (!newInputArgs[target]) { - newInputArgs[target] = {}; - } + const target = typeof inputArgs[0] == 'string' ? 1 : 0; + const newInputArgs = [...inputArgs]; + if (typeof newInputArgs[target] !== 'object') { + const rawValue = newInputArgs[target]; + newInputArgs[target] = { rawValue }; + } + if (!newInputArgs[target]) { + newInputArgs[target] = {}; + } - newInputArgs[target]['caller'] = callerFilePath; + newInputArgs[target]['caller'] = callerFilePath; - newInputArgs[target]['userAuth'] = (als.getStore() as any)?.userAuth; + newInputArgs[target]['userAuth'] = (als.getStore() as any)?.userAuth; - const traceId = (als.getStore() as any)?.traceId; - if (traceId) { - newInputArgs[target]['traceId'] = traceId; + const traceId = (als.getStore() as any)?.traceId; + if (traceId) { + newInputArgs[target]['traceId'] = traceId; - const timingArray = (als.getStore() as any)?.timing; - if (timingArray) { - newInputArgs[target]['traceIndex'] = timingArray.length; - newInputArgs[target]['traceDelta'] = Date.now() - timingArray[timingArray.length - 1]; + const timingArray = (als.getStore() as any)?.timing; + if (timingArray) { + newInputArgs[target]['traceIndex'] = timingArray.length; + newInputArgs[target]['traceDelta'] = Date.now() - timingArray[timingArray.length - 1]; + } + (als.getStore() as any)?.timing.push(Date.now()); } - (als.getStore() as any)?.timing.push(Date.now()); - } - return method.apply(this, [...newInputArgs]); + return method.apply(this, [...newInputArgs]); + } catch (err) { + // logger.error({ err }, 'error in logMethod hook'); + return method.apply(this, inputArgs); + } }, }, transport: From 368164c00fce7acf1eba63626423953a01c71093 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Thu, 13 Jun 2024 20:32:10 +0200 Subject: [PATCH 113/278] don't drop log variables if we have a log format issue --- desci-server/src/logger.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/desci-server/src/logger.ts b/desci-server/src/logger.ts index 12709058..b53cfaca 100644 --- a/desci-server/src/logger.ts +++ b/desci-server/src/logger.ts @@ -55,14 +55,20 @@ export const logger = pino({ // callerFilePath = '-unknown-'; } - const target = typeof inputArgs[0] == 'string' ? 1 : 0; - const newInputArgs = [...inputArgs]; - if (typeof newInputArgs[target] !== 'object') { - const rawValue = newInputArgs[target]; - newInputArgs[target] = { rawValue }; - } + let target = typeof inputArgs[0] == 'string' ? 1 : 0; + let newInputArgs = [...inputArgs]; + if (!newInputArgs[target]) { newInputArgs[target] = {}; + } else if (typeof newInputArgs[target] !== 'object') { + const rawValue = {}; + rawValue['stringLogs'] = inputArgs; + + rawValue['error'] = + 'this means your pino log statement is incorrectly formatted, check the order of the arguments'; + target = 0; + newInputArgs[target] = { rawValue }; + newInputArgs = [newInputArgs[0], inputArgs[0]]; } newInputArgs[target]['caller'] = callerFilePath; From bb41e35f1566cf2a696016903fe003d04cadc8c7 Mon Sep 17 00:00:00 2001 From: m0ar Date: Wed, 22 May 2024 15:59:36 +0200 Subject: [PATCH 114/278] Initial version of alias registry contract --- .../DpidAliasRegistry.json | 380 +++++++++ .../contracts/DpidAliasRegistry.sol | 131 +++ desci-contracts/hardhat.config.ts | 3 + desci-contracts/package.json | 6 +- desci-contracts/test/DpidAliasRegistry.ts | 227 +++++ .../typechain-types/ContextUpgradeable.js | 2 - .../typechain-types/DpidAliasRegistry.ts | 497 +++++++++++ .../typechain-types/DpidRegistry.js | 2 - desci-contracts/typechain-types/ERC165.js | 2 - .../typechain-types/ERC165Upgradeable.js | 2 - desci-contracts/typechain-types/ERC721.js | 2 - .../typechain-types/ERC721Upgradeable.js | 2 - .../typechain-types/IDpidRegistry.js | 2 - desci-contracts/typechain-types/IERC165.js | 2 - .../typechain-types/IERC165Upgradeable.js | 2 - desci-contracts/typechain-types/IERC721.js | 2 - .../typechain-types/IERC721Metadata.js | 2 - .../IERC721MetadataUpgradeable.js | 2 - .../typechain-types/IERC721Receiver.js | 2 - .../IERC721ReceiverUpgradeable.js | 2 - .../typechain-types/IERC721Upgradeable.js | 2 - .../typechain-types/Initializable.js | 2 - .../typechain-types/OwnableUpgradeable.js | 2 - .../typechain-types/ResearchObject.js | 2 - .../typechain-types/ResearchObjectMigrated.js | 2 - .../typechain-types/ResearchObjectV2.js | 2 - desci-contracts/typechain-types/TestERC721.js | 2 - .../typechain-types/VersionedERC721.js | 2 - .../typechain-types/VersionedERC721V2.js | 2 - desci-contracts/typechain-types/common.js | 2 - .../factories/ContextUpgradeable__factory.js | 35 - .../factories/DpidAliasRegistry__factory.ts | 433 ++++++++++ .../factories/DpidRegistry__factory.js | 483 ----------- .../factories/ERC165Upgradeable__factory.js | 54 -- .../factories/ERC165__factory.js | 41 - .../factories/ERC721Upgradeable__factory.js | 409 --------- .../factories/ERC721__factory.js | 412 --------- .../factories/IDpidRegistry__factory.js | 94 --- .../factories/IERC165Upgradeable__factory.js | 41 - .../factories/IERC165__factory.js | 41 - .../IERC721MetadataUpgradeable__factory.js | 352 -------- .../factories/IERC721Metadata__factory.js | 352 -------- .../IERC721ReceiverUpgradeable__factory.js | 56 -- .../factories/IERC721Receiver__factory.js | 56 -- .../factories/IERC721Upgradeable__factory.js | 307 ------- .../factories/IERC721__factory.js | 307 ------- .../factories/Initializable__factory.js | 35 - .../factories/OwnableUpgradeable__factory.js | 87 -- .../ResearchObjectMigrated__factory.js | 790 ------------------ .../factories/ResearchObjectV2__factory.js | 663 --------------- .../factories/ResearchObject__factory.js | 663 --------------- .../factories/TestERC721__factory.js | 425 ---------- .../factories/VersionedERC721V2__factory.js | 508 ----------- .../factories/VersionedERC721__factory.js | 508 ----------- desci-contracts/typechain-types/hardhat.d.ts | 9 + desci-contracts/typechain-types/index.js | 60 -- desci-contracts/typechain-types/index.ts | 2 + desci-contracts/yarn.lock | 16 +- 58 files changed, 1702 insertions(+), 6829 deletions(-) create mode 100644 desci-contracts/artifacts/contracts/DpidAliasRegistry.sol/DpidAliasRegistry.json create mode 100644 desci-contracts/contracts/DpidAliasRegistry.sol create mode 100644 desci-contracts/test/DpidAliasRegistry.ts delete mode 100644 desci-contracts/typechain-types/ContextUpgradeable.js create mode 100644 desci-contracts/typechain-types/DpidAliasRegistry.ts delete mode 100644 desci-contracts/typechain-types/DpidRegistry.js delete mode 100644 desci-contracts/typechain-types/ERC165.js delete mode 100644 desci-contracts/typechain-types/ERC165Upgradeable.js delete mode 100644 desci-contracts/typechain-types/ERC721.js delete mode 100644 desci-contracts/typechain-types/ERC721Upgradeable.js delete mode 100644 desci-contracts/typechain-types/IDpidRegistry.js delete mode 100644 desci-contracts/typechain-types/IERC165.js delete mode 100644 desci-contracts/typechain-types/IERC165Upgradeable.js delete mode 100644 desci-contracts/typechain-types/IERC721.js delete mode 100644 desci-contracts/typechain-types/IERC721Metadata.js delete mode 100644 desci-contracts/typechain-types/IERC721MetadataUpgradeable.js delete mode 100644 desci-contracts/typechain-types/IERC721Receiver.js delete mode 100644 desci-contracts/typechain-types/IERC721ReceiverUpgradeable.js delete mode 100644 desci-contracts/typechain-types/IERC721Upgradeable.js delete mode 100644 desci-contracts/typechain-types/Initializable.js delete mode 100644 desci-contracts/typechain-types/OwnableUpgradeable.js delete mode 100644 desci-contracts/typechain-types/ResearchObject.js delete mode 100644 desci-contracts/typechain-types/ResearchObjectMigrated.js delete mode 100644 desci-contracts/typechain-types/ResearchObjectV2.js delete mode 100644 desci-contracts/typechain-types/TestERC721.js delete mode 100644 desci-contracts/typechain-types/VersionedERC721.js delete mode 100644 desci-contracts/typechain-types/VersionedERC721V2.js delete mode 100644 desci-contracts/typechain-types/common.js delete mode 100644 desci-contracts/typechain-types/factories/ContextUpgradeable__factory.js create mode 100644 desci-contracts/typechain-types/factories/DpidAliasRegistry__factory.ts delete mode 100644 desci-contracts/typechain-types/factories/DpidRegistry__factory.js delete mode 100644 desci-contracts/typechain-types/factories/ERC165Upgradeable__factory.js delete mode 100644 desci-contracts/typechain-types/factories/ERC165__factory.js delete mode 100644 desci-contracts/typechain-types/factories/ERC721Upgradeable__factory.js delete mode 100644 desci-contracts/typechain-types/factories/ERC721__factory.js delete mode 100644 desci-contracts/typechain-types/factories/IDpidRegistry__factory.js delete mode 100644 desci-contracts/typechain-types/factories/IERC165Upgradeable__factory.js delete mode 100644 desci-contracts/typechain-types/factories/IERC165__factory.js delete mode 100644 desci-contracts/typechain-types/factories/IERC721MetadataUpgradeable__factory.js delete mode 100644 desci-contracts/typechain-types/factories/IERC721Metadata__factory.js delete mode 100644 desci-contracts/typechain-types/factories/IERC721ReceiverUpgradeable__factory.js delete mode 100644 desci-contracts/typechain-types/factories/IERC721Receiver__factory.js delete mode 100644 desci-contracts/typechain-types/factories/IERC721Upgradeable__factory.js delete mode 100644 desci-contracts/typechain-types/factories/IERC721__factory.js delete mode 100644 desci-contracts/typechain-types/factories/Initializable__factory.js delete mode 100644 desci-contracts/typechain-types/factories/OwnableUpgradeable__factory.js delete mode 100644 desci-contracts/typechain-types/factories/ResearchObjectMigrated__factory.js delete mode 100644 desci-contracts/typechain-types/factories/ResearchObjectV2__factory.js delete mode 100644 desci-contracts/typechain-types/factories/ResearchObject__factory.js delete mode 100644 desci-contracts/typechain-types/factories/TestERC721__factory.js delete mode 100644 desci-contracts/typechain-types/factories/VersionedERC721V2__factory.js delete mode 100644 desci-contracts/typechain-types/factories/VersionedERC721__factory.js delete mode 100644 desci-contracts/typechain-types/index.js diff --git a/desci-contracts/artifacts/contracts/DpidAliasRegistry.sol/DpidAliasRegistry.json b/desci-contracts/artifacts/contracts/DpidAliasRegistry.sol/DpidAliasRegistry.json new file mode 100644 index 00000000..24c64307 --- /dev/null +++ b/desci-contracts/artifacts/contracts/DpidAliasRegistry.sol/DpidAliasRegistry.json @@ -0,0 +1,380 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "DpidAliasRegistry", + "sourceName": "contracts/DpidAliasRegistry.sol", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "dpid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "streamID", + "type": "string" + } + ], + "name": "DpidMinted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "dpid", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "components": [ + { + "internalType": "string", + "name": "cid", + "type": "string" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "internalType": "struct DpidAliasRegistry.LegacyVersion[]", + "name": "versions", + "type": "tuple[]" + } + ], + "indexed": false, + "internalType": "struct DpidAliasRegistry.LegacyDpidEntry", + "name": "entry", + "type": "tuple" + } + ], + "name": "ImportedDpid", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "dpid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "streamId", + "type": "string" + } + ], + "name": "UpgradedDpid", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "firstDpid", + "type": "uint256" + } + ], + "name": "__DpidAliasRegistry_init", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "_firstDpid", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "dpid", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "components": [ + { + "internalType": "string", + "name": "cid", + "type": "string" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "internalType": "struct DpidAliasRegistry.LegacyVersion[]", + "name": "versions", + "type": "tuple[]" + } + ], + "internalType": "struct DpidAliasRegistry.LegacyDpidEntry", + "name": "entry", + "type": "tuple" + } + ], + "name": "importLegacyDpid", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "legacy", + "outputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "dpid", + "type": "uint256" + } + ], + "name": "legacyLookup", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "components": [ + { + "internalType": "string", + "name": "cid", + "type": "string" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "internalType": "struct DpidAliasRegistry.LegacyVersion[]", + "name": "versions", + "type": "tuple[]" + } + ], + "internalType": "struct DpidAliasRegistry.LegacyDpidEntry", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "dpid", + "type": "uint256" + } + ], + "name": "lookup", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "streamId", + "type": "string" + } + ], + "name": "mintDpid", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "nextDpid", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "registry", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "dpid", + "type": "uint256" + }, + { + "internalType": "string", + "name": "streamId", + "type": "string" + } + ], + "name": "upgradeDpid", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d3565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000127565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff161015620000ed5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e4919062000149565b60405180910390a15b565b6000620000fe60278362000166565b91506200010b8262000184565b604082019050919050565b620001218162000177565b82525050565b600060208201905081810360008301526200014281620000ef565b9050919050565b600060208201905062000160600083018462000116565b92915050565b600082825260208201905092915050565b600060ff82169050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b6122cb80620001e36000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c8063810a9afa1161008c578063b724de3a11610066578063b724de3a14610212578063dc5d7a2e14610242578063ded8896b14610260578063f2fde38b1461027c576100cf565b8063810a9afa146101a65780638da5cb5b146101d6578063afc26911146101f4576100cf565b80630a874df6146100d4578063144ae85514610104578063362b3e63146101205780635893253c1461013c578063715018a61461016c578063788243d514610176575b600080fd5b6100ee60048036038101906100e99190610dff565b610298565b6040516100fb919061131c565b60405180910390f35b61011e60048036038101906101199190610e80565b61033d565b005b61013a60048036038101906101359190610dff565b6103a5565b005b61015660048036038101906101519190610dff565b6104eb565b604051610163919061131c565b60405180910390f35b61017461058b565b005b610190600480360381019061018b9190610dff565b61059f565b60405161019d91906112e6565b60405180910390f35b6101c060048036038101906101bb9190610dff565b6105dd565b6040516101cd91906113fe565b60405180910390f35b6101de61075b565b6040516101eb91906112e6565b60405180910390f35b6101fc610785565b6040516102099190611420565b60405180910390f35b61022c60048036038101906102279190610dba565b61078b565b6040516102399190611420565b60405180910390f35b61024a610813565b6040516102579190611420565b60405180910390f35b61027a60048036038101906102759190610e28565b610819565b005b61029660048036038101906102919190610d91565b610982565b005b60606067600083815260200190815260200160002080546102b890611c27565b80601f01602080910402602001604051908101604052809291908181526020018280546102e490611c27565b80156103315780601f1061030657610100808354040283529160200191610331565b820191906000526020600020905b81548152906001019060200180831161031457829003601f168201915b50505050509050919050565b610345610a06565b8060686000848152602001908152602001600020818161036591906121ee565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada828260405161039992919061146d565b60405180910390a15050565b60008060019054906101000a900460ff161590508080156103d65750600160008054906101000a900460ff1660ff16105b8061040357506103e530610a84565b1580156104025750600160008054906101000a900460ff1660ff16145b5b610442576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104399061137e565b60405180910390fd5b60016000806101000a81548160ff021916908360ff160217905550801561047f576001600060016101000a81548160ff0219169083151502179055505b610487610aa7565b8160668190555080156104e75760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516104de9190611301565b60405180910390a15b5050565b6067602052806000526040600020600091509050805461050a90611c27565b80601f016020809104026020016040519081016040528092919081815260200182805461053690611c27565b80156105835780601f1061055857610100808354040283529160200191610583565b820191906000526020600020905b81548152906001019060200180831161056657829003601f168201915b505050505081565b610593610a06565b61059d6000610b00565b565b60686020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b6105e5610c2f565b606860008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b8282101561074c57838290600052602060002090600202016040518060400160405290816000820180546106b190611c27565b80601f01602080910402602001604051908101604052809291908181526020018280546106dd90611c27565b801561072a5780601f106106ff5761010080835404028352916020019161072a565b820191906000526020600020905b81548152906001019060200180831161070d57829003601f168201915b505050505081526020016001820154815250508152602001906001019061067e565b50505050815250509050919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60665481565b600080606654905083836067600084815260200190815260200160002091906107b5929190610c5f565b507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d8185856040516107e99392919061143b565b60405180910390a16066600081548092919061080490611c75565b91905055508091505092915050565b60655481565b600060676000858152602001908152602001600020805461083990611c27565b90501461087b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108729061133e565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff166068600085815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461091f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610916906113de565b60405180910390fd5b8181606760008681526020019081526020016000209190610941929190610c5f565b507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c8383836040516109759392919061143b565b60405180910390a1505050565b61098a610a06565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156109fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109f19061135e565b60405180910390fd5b610a0381610b00565b50565b610a0e610bc6565b73ffffffffffffffffffffffffffffffffffffffff16610a2c61075b565b73ffffffffffffffffffffffffffffffffffffffff1614610a82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a799061139e565b60405180910390fd5b565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610af6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aed906113be565b60405180910390fd5b610afe610bce565b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600060019054906101000a900460ff16610c1d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c14906113be565b60405180910390fd5b610c2d610c28610bc6565b610b00565b565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b828054610c6b90611c27565b90600052602060002090601f016020900481019282610c8d5760008555610cd4565b82601f10610ca657803560ff1916838001178555610cd4565b82800160010185558215610cd4579182015b82811115610cd3578235825591602001919060010190610cb8565b5b509050610ce19190610ce5565b5090565b5b80821115610cfe576000816000905550600101610ce6565b5090565b600081359050610d1181612262565b92915050565b60008083601f840112610d2957600080fd5b8235905067ffffffffffffffff811115610d4257600080fd5b602083019150836001820283011115610d5a57600080fd5b9250929050565b600060408284031215610d7357600080fd5b81905092915050565b600081359050610d8b81612279565b92915050565b600060208284031215610da357600080fd5b6000610db184828501610d02565b91505092915050565b60008060208385031215610dcd57600080fd5b600083013567ffffffffffffffff811115610de757600080fd5b610df385828601610d17565b92509250509250929050565b600060208284031215610e1157600080fd5b6000610e1f84828501610d7c565b91505092915050565b600080600060408486031215610e3d57600080fd5b6000610e4b86828701610d7c565b935050602084013567ffffffffffffffff811115610e6857600080fd5b610e7486828701610d17565b92509250509250925092565b60008060408385031215610e9357600080fd5b6000610ea185828601610d7c565b925050602083013567ffffffffffffffff811115610ebe57600080fd5b610eca85828601610d61565b9150509250929050565b6000610ee0838361123c565b905092915050565b6000610ef4838361128b565b905092915050565b610f05816118ad565b82525050565b610f14816118ad565b82525050565b6000610f26838561161b565b935083602084028501610f3884611586565b8060005b87811015610f7c578484038952610f538284611818565b610f5d8582610ed4565b9450610f6883611601565b925060208a01995050600181019050610f3c565b50829750879450505050509392505050565b6000610f99826115d5565b610fa3818561161b565b935083602082028501610fb585611590565b8060005b85811015610ff15784840389528151610fd28582610ee8565b9450610fdd8361160e565b925060208a01995050600181019050610fb9565b50829750879550505050505092915050565b61100c8161199c565b82525050565b600061101e838561162c565b935061102b838584611b59565b61103483611ecc565b840190509392505050565b600061104b838561163d565b9350611058838584611b59565b61106183611ecc565b840190509392505050565b6000611077826115f6565b611081818561162c565b9350611091818560208601611b68565b61109a81611ecc565b840191505092915050565b60006110b0826115f6565b6110ba818561163d565b93506110ca818560208601611b68565b6110d381611ecc565b840191505092915050565b60006110eb60158361163d565b91506110f682611f58565b602082019050919050565b600061110e60268361163d565b915061111982611f81565b604082019050919050565b6000611131602e8361163d565b915061113c82611fd0565b604082019050919050565b600061115460208361163d565b915061115f8261201f565b602082019050919050565b6000611177602b8361163d565b915061118282612048565b604082019050919050565b600061119a60198361163d565b91506111a582612097565b602082019050919050565b6000604083016111c36000840184611753565b6111d06000860182610efc565b506111de602084018461176a565b85830360208701526111f1838284610f1a565b925050508091505092915050565b60006040830160008301516112176000860182610efc565b506020830151848203602086015261122f8282610f8e565b9150508091505092915050565b60006040830161124f60008401846117c1565b8583036000870152611262838284611012565b92505050611273602084018461183c565b61128060208601826112c8565b508091505092915050565b600060408301600083015184820360008601526112a8828261106c565b91505060208301516112bd60208601826112c8565b508091505092915050565b6112d1816118df565b82525050565b6112e0816118df565b82525050565b60006020820190506112fb6000830184610f0b565b92915050565b60006020820190506113166000830184611003565b92915050565b6000602082019050818103600083015261133681846110a5565b905092915050565b60006020820190508181036000830152611357816110de565b9050919050565b6000602082019050818103600083015261137781611101565b9050919050565b6000602082019050818103600083015261139781611124565b9050919050565b600060208201905081810360008301526113b781611147565b9050919050565b600060208201905081810360008301526113d78161116a565b9050919050565b600060208201905081810360008301526113f78161118d565b9050919050565b6000602082019050818103600083015261141881846111ff565b905092915050565b600060208201905061143560008301846112d7565b92915050565b600060408201905061145060008301866112d7565b818103602083015261146381848661103f565b9050949350505050565b600060408201905061148260008301856112d7565b818103602083015261149481846111b0565b90509392505050565b600080833560016020038436030381126114b657600080fd5b80840192508235915067ffffffffffffffff8211156114d457600080fd5b6020830192506020820236038313156114ec57600080fd5b509250929050565b6000808335600160200384360303811261150d57600080fd5b80840192508235915067ffffffffffffffff82111561152b57600080fd5b60208301925060018202360383131561154357600080fd5b509250929050565b60008235600160400383360303811261156357600080fd5b80830191505092915050565b600081905061157f826002611853565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b60208410600081146116a757601f841160018114611677576116708685611c59565b83556116a1565b611680836115b5565b6116956020601f880104820160018301611904565b61169f87856120c0565b505b506116f0565b6116b0826115b5565b6020601f8701048101601f871680156116d1576116d08160018403611d98565b5b6116e36020601f890104840183611904565b6001886002021785555050505b5050505050565b6020831060008114611742576020851060008114611720576117198685611c59565b835561173c565b8360ff1916935083611731846115b5565b556001866002020183555b5061174c565b6001856002020182555b5050505050565b60006117626020840184610d02565b905092915050565b6000808335600160200384360303811261178357600080fd5b83810192508235915060208301925067ffffffffffffffff8211156117a757600080fd5b6020820236038413156117b957600080fd5b509250929050565b600080833560016020038436030381126117da57600080fd5b83810192508235915060208301925067ffffffffffffffff8211156117fe57600080fd5b60018202360384131561181057600080fd5b509250929050565b60008235600160400383360303811261183057600080fd5b82810191505092915050565b600061184b6020840184610d7c565b905092915050565b600061185e826118df565b9150611869836118df565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156118a2576118a1611d0b565b5b828202905092915050565b60006118b8826118bf565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b611901600082611e77565b50565b5b8181101561192357611918600082611f40565b600181019050611905565b5050565b5b818110156119465761193b600082611f22565b600281019050611928565b5050565b818110156119685761195d600082611f40565b60018101905061194a565b5050565b6119796000808301611f04565b611987600060018301611f40565b50565b6000611995826119ae565b9050919050565b60006119a7826118e9565b9050919050565b60006119b9826119c0565b9050919050565b60006119cb826118bf565b9050919050565b60006119dd826118df565b9050919050565b6119ee83836115ca565b6119f88183611e13565b611a0183611586565b611a0a836115a0565b6000805b84811015611a4357611a20848861154b565b611a2b81848661221f565b60208501945060028401935050600181019050611a0e565b5050505050505050565b611a5783836115eb565b67ffffffffffffffff811115611a7057611a6f611d69565b5b611a7a8254611c27565b600080601f8411601f84111715611a9757611a94856115b5565b90505b601f831115611aca576020601f85010481016020851015611ab6578190505b611ac86020601f860104830182611904565b505b601f841160018114611af75760008515611ae5578388013590505b611aef8682611c59565b875550611b4f565b601f1985168260005b82811015611b2557858a01358255600182019150602086019550602081019050611b00565b87831015611b4257858a0135611b3e601f8a1682611cbe565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b83811015611b86578082015181840152602081019050611b6b565b83811115611b95576000848401525b50505050565b600081016000830180611bad81611de7565b9050611bb981846121ab565b5050506001810160208301611bce818561149d565b611bd98183866121ce565b505050505050565b6000810160008301611bf381856114f4565b611bfe8183866121de565b50505050600181016020830180611c1481611dfd565b9050611c2081846121fc565b5050505050565b60006002820490506001821680611c3f57607f821691505b60208210811415611c5357611c52611d3a565b5b50919050565b6000611c658383611cbe565b9150826002028217905092915050565b6000611c80826118df565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415611cb357611cb2611d0b565b5b600182019050919050565b6000611ccf60001984600802611ef7565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611dc87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83602003600802611ef7565b815481168255505050565b6000819050919050565b6000819050919050565b60008135611df481612262565b80915050919050565b60008135611e0a81612279565b80915050919050565b68010000000000000000821115611e2d57611e2c611d69565b5b611e36816115e0565b82825580831015611e7257611e4a8161156f565b611e538461156f565b611e5c846115a0565b818101838201611e6c8183611927565b50505050505b505050565b68010000000000000000821115611e9157611e90611d69565b5b8054611e9c81611c27565b80841115611eb157611eb0848284866116f7565b5b80841015611ec657611ec58482848661164e565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b60008214611f1557611f14611cdc565b5b611f1e816118f6565b5050565b60008214611f3357611f32611cdc565b5b611f3c8161196c565b5050565b611f48612290565b611f5381848461223d565b505050565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b6120c9816115b5565b6120d4838254611c59565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff61210184611edd565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61214384611edd565b9350801983169250808416831791505092915050565b6000600883026121897fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82611eea565b6121938683611eea565b95508019841693508086168417925050509392505050565b6121b48261198a565b6121c76121c082611dd3565b83546120e1565b8255505050565b6121d98383836119e4565b505050565b6121e9838383611a4d565b505050565b6121f88282611b9b565b5050565b612205826119d2565b61221861221182611ddd565b8354612117565b8255505050565b811561222e5761222d611cdc565b5b6122388382611be1565b505050565b612246836119d2565b61225a61225282611ddd565b848454612159565b825550505050565b61226b816118ad565b811461227657600080fd5b50565b612282816118df565b811461228d57600080fd5b50565b60009056fea26469706673582212209d15c5501273e10408c38b0c27c1d9008c55404af21e411dc9d13c190f83a2b364736f6c63430008040033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100cf5760003560e01c8063810a9afa1161008c578063b724de3a11610066578063b724de3a14610212578063dc5d7a2e14610242578063ded8896b14610260578063f2fde38b1461027c576100cf565b8063810a9afa146101a65780638da5cb5b146101d6578063afc26911146101f4576100cf565b80630a874df6146100d4578063144ae85514610104578063362b3e63146101205780635893253c1461013c578063715018a61461016c578063788243d514610176575b600080fd5b6100ee60048036038101906100e99190610dff565b610298565b6040516100fb919061131c565b60405180910390f35b61011e60048036038101906101199190610e80565b61033d565b005b61013a60048036038101906101359190610dff565b6103a5565b005b61015660048036038101906101519190610dff565b6104eb565b604051610163919061131c565b60405180910390f35b61017461058b565b005b610190600480360381019061018b9190610dff565b61059f565b60405161019d91906112e6565b60405180910390f35b6101c060048036038101906101bb9190610dff565b6105dd565b6040516101cd91906113fe565b60405180910390f35b6101de61075b565b6040516101eb91906112e6565b60405180910390f35b6101fc610785565b6040516102099190611420565b60405180910390f35b61022c60048036038101906102279190610dba565b61078b565b6040516102399190611420565b60405180910390f35b61024a610813565b6040516102579190611420565b60405180910390f35b61027a60048036038101906102759190610e28565b610819565b005b61029660048036038101906102919190610d91565b610982565b005b60606067600083815260200190815260200160002080546102b890611c27565b80601f01602080910402602001604051908101604052809291908181526020018280546102e490611c27565b80156103315780601f1061030657610100808354040283529160200191610331565b820191906000526020600020905b81548152906001019060200180831161031457829003601f168201915b50505050509050919050565b610345610a06565b8060686000848152602001908152602001600020818161036591906121ee565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada828260405161039992919061146d565b60405180910390a15050565b60008060019054906101000a900460ff161590508080156103d65750600160008054906101000a900460ff1660ff16105b8061040357506103e530610a84565b1580156104025750600160008054906101000a900460ff1660ff16145b5b610442576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104399061137e565b60405180910390fd5b60016000806101000a81548160ff021916908360ff160217905550801561047f576001600060016101000a81548160ff0219169083151502179055505b610487610aa7565b8160668190555080156104e75760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516104de9190611301565b60405180910390a15b5050565b6067602052806000526040600020600091509050805461050a90611c27565b80601f016020809104026020016040519081016040528092919081815260200182805461053690611c27565b80156105835780601f1061055857610100808354040283529160200191610583565b820191906000526020600020905b81548152906001019060200180831161056657829003601f168201915b505050505081565b610593610a06565b61059d6000610b00565b565b60686020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b6105e5610c2f565b606860008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b8282101561074c57838290600052602060002090600202016040518060400160405290816000820180546106b190611c27565b80601f01602080910402602001604051908101604052809291908181526020018280546106dd90611c27565b801561072a5780601f106106ff5761010080835404028352916020019161072a565b820191906000526020600020905b81548152906001019060200180831161070d57829003601f168201915b505050505081526020016001820154815250508152602001906001019061067e565b50505050815250509050919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60665481565b600080606654905083836067600084815260200190815260200160002091906107b5929190610c5f565b507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d8185856040516107e99392919061143b565b60405180910390a16066600081548092919061080490611c75565b91905055508091505092915050565b60655481565b600060676000858152602001908152602001600020805461083990611c27565b90501461087b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108729061133e565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff166068600085815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461091f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610916906113de565b60405180910390fd5b8181606760008681526020019081526020016000209190610941929190610c5f565b507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c8383836040516109759392919061143b565b60405180910390a1505050565b61098a610a06565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156109fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109f19061135e565b60405180910390fd5b610a0381610b00565b50565b610a0e610bc6565b73ffffffffffffffffffffffffffffffffffffffff16610a2c61075b565b73ffffffffffffffffffffffffffffffffffffffff1614610a82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a799061139e565b60405180910390fd5b565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610af6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aed906113be565b60405180910390fd5b610afe610bce565b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600060019054906101000a900460ff16610c1d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c14906113be565b60405180910390fd5b610c2d610c28610bc6565b610b00565b565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b828054610c6b90611c27565b90600052602060002090601f016020900481019282610c8d5760008555610cd4565b82601f10610ca657803560ff1916838001178555610cd4565b82800160010185558215610cd4579182015b82811115610cd3578235825591602001919060010190610cb8565b5b509050610ce19190610ce5565b5090565b5b80821115610cfe576000816000905550600101610ce6565b5090565b600081359050610d1181612262565b92915050565b60008083601f840112610d2957600080fd5b8235905067ffffffffffffffff811115610d4257600080fd5b602083019150836001820283011115610d5a57600080fd5b9250929050565b600060408284031215610d7357600080fd5b81905092915050565b600081359050610d8b81612279565b92915050565b600060208284031215610da357600080fd5b6000610db184828501610d02565b91505092915050565b60008060208385031215610dcd57600080fd5b600083013567ffffffffffffffff811115610de757600080fd5b610df385828601610d17565b92509250509250929050565b600060208284031215610e1157600080fd5b6000610e1f84828501610d7c565b91505092915050565b600080600060408486031215610e3d57600080fd5b6000610e4b86828701610d7c565b935050602084013567ffffffffffffffff811115610e6857600080fd5b610e7486828701610d17565b92509250509250925092565b60008060408385031215610e9357600080fd5b6000610ea185828601610d7c565b925050602083013567ffffffffffffffff811115610ebe57600080fd5b610eca85828601610d61565b9150509250929050565b6000610ee0838361123c565b905092915050565b6000610ef4838361128b565b905092915050565b610f05816118ad565b82525050565b610f14816118ad565b82525050565b6000610f26838561161b565b935083602084028501610f3884611586565b8060005b87811015610f7c578484038952610f538284611818565b610f5d8582610ed4565b9450610f6883611601565b925060208a01995050600181019050610f3c565b50829750879450505050509392505050565b6000610f99826115d5565b610fa3818561161b565b935083602082028501610fb585611590565b8060005b85811015610ff15784840389528151610fd28582610ee8565b9450610fdd8361160e565b925060208a01995050600181019050610fb9565b50829750879550505050505092915050565b61100c8161199c565b82525050565b600061101e838561162c565b935061102b838584611b59565b61103483611ecc565b840190509392505050565b600061104b838561163d565b9350611058838584611b59565b61106183611ecc565b840190509392505050565b6000611077826115f6565b611081818561162c565b9350611091818560208601611b68565b61109a81611ecc565b840191505092915050565b60006110b0826115f6565b6110ba818561163d565b93506110ca818560208601611b68565b6110d381611ecc565b840191505092915050565b60006110eb60158361163d565b91506110f682611f58565b602082019050919050565b600061110e60268361163d565b915061111982611f81565b604082019050919050565b6000611131602e8361163d565b915061113c82611fd0565b604082019050919050565b600061115460208361163d565b915061115f8261201f565b602082019050919050565b6000611177602b8361163d565b915061118282612048565b604082019050919050565b600061119a60198361163d565b91506111a582612097565b602082019050919050565b6000604083016111c36000840184611753565b6111d06000860182610efc565b506111de602084018461176a565b85830360208701526111f1838284610f1a565b925050508091505092915050565b60006040830160008301516112176000860182610efc565b506020830151848203602086015261122f8282610f8e565b9150508091505092915050565b60006040830161124f60008401846117c1565b8583036000870152611262838284611012565b92505050611273602084018461183c565b61128060208601826112c8565b508091505092915050565b600060408301600083015184820360008601526112a8828261106c565b91505060208301516112bd60208601826112c8565b508091505092915050565b6112d1816118df565b82525050565b6112e0816118df565b82525050565b60006020820190506112fb6000830184610f0b565b92915050565b60006020820190506113166000830184611003565b92915050565b6000602082019050818103600083015261133681846110a5565b905092915050565b60006020820190508181036000830152611357816110de565b9050919050565b6000602082019050818103600083015261137781611101565b9050919050565b6000602082019050818103600083015261139781611124565b9050919050565b600060208201905081810360008301526113b781611147565b9050919050565b600060208201905081810360008301526113d78161116a565b9050919050565b600060208201905081810360008301526113f78161118d565b9050919050565b6000602082019050818103600083015261141881846111ff565b905092915050565b600060208201905061143560008301846112d7565b92915050565b600060408201905061145060008301866112d7565b818103602083015261146381848661103f565b9050949350505050565b600060408201905061148260008301856112d7565b818103602083015261149481846111b0565b90509392505050565b600080833560016020038436030381126114b657600080fd5b80840192508235915067ffffffffffffffff8211156114d457600080fd5b6020830192506020820236038313156114ec57600080fd5b509250929050565b6000808335600160200384360303811261150d57600080fd5b80840192508235915067ffffffffffffffff82111561152b57600080fd5b60208301925060018202360383131561154357600080fd5b509250929050565b60008235600160400383360303811261156357600080fd5b80830191505092915050565b600081905061157f826002611853565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b60208410600081146116a757601f841160018114611677576116708685611c59565b83556116a1565b611680836115b5565b6116956020601f880104820160018301611904565b61169f87856120c0565b505b506116f0565b6116b0826115b5565b6020601f8701048101601f871680156116d1576116d08160018403611d98565b5b6116e36020601f890104840183611904565b6001886002021785555050505b5050505050565b6020831060008114611742576020851060008114611720576117198685611c59565b835561173c565b8360ff1916935083611731846115b5565b556001866002020183555b5061174c565b6001856002020182555b5050505050565b60006117626020840184610d02565b905092915050565b6000808335600160200384360303811261178357600080fd5b83810192508235915060208301925067ffffffffffffffff8211156117a757600080fd5b6020820236038413156117b957600080fd5b509250929050565b600080833560016020038436030381126117da57600080fd5b83810192508235915060208301925067ffffffffffffffff8211156117fe57600080fd5b60018202360384131561181057600080fd5b509250929050565b60008235600160400383360303811261183057600080fd5b82810191505092915050565b600061184b6020840184610d7c565b905092915050565b600061185e826118df565b9150611869836118df565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156118a2576118a1611d0b565b5b828202905092915050565b60006118b8826118bf565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b611901600082611e77565b50565b5b8181101561192357611918600082611f40565b600181019050611905565b5050565b5b818110156119465761193b600082611f22565b600281019050611928565b5050565b818110156119685761195d600082611f40565b60018101905061194a565b5050565b6119796000808301611f04565b611987600060018301611f40565b50565b6000611995826119ae565b9050919050565b60006119a7826118e9565b9050919050565b60006119b9826119c0565b9050919050565b60006119cb826118bf565b9050919050565b60006119dd826118df565b9050919050565b6119ee83836115ca565b6119f88183611e13565b611a0183611586565b611a0a836115a0565b6000805b84811015611a4357611a20848861154b565b611a2b81848661221f565b60208501945060028401935050600181019050611a0e565b5050505050505050565b611a5783836115eb565b67ffffffffffffffff811115611a7057611a6f611d69565b5b611a7a8254611c27565b600080601f8411601f84111715611a9757611a94856115b5565b90505b601f831115611aca576020601f85010481016020851015611ab6578190505b611ac86020601f860104830182611904565b505b601f841160018114611af75760008515611ae5578388013590505b611aef8682611c59565b875550611b4f565b601f1985168260005b82811015611b2557858a01358255600182019150602086019550602081019050611b00565b87831015611b4257858a0135611b3e601f8a1682611cbe565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b83811015611b86578082015181840152602081019050611b6b565b83811115611b95576000848401525b50505050565b600081016000830180611bad81611de7565b9050611bb981846121ab565b5050506001810160208301611bce818561149d565b611bd98183866121ce565b505050505050565b6000810160008301611bf381856114f4565b611bfe8183866121de565b50505050600181016020830180611c1481611dfd565b9050611c2081846121fc565b5050505050565b60006002820490506001821680611c3f57607f821691505b60208210811415611c5357611c52611d3a565b5b50919050565b6000611c658383611cbe565b9150826002028217905092915050565b6000611c80826118df565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415611cb357611cb2611d0b565b5b600182019050919050565b6000611ccf60001984600802611ef7565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611dc87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83602003600802611ef7565b815481168255505050565b6000819050919050565b6000819050919050565b60008135611df481612262565b80915050919050565b60008135611e0a81612279565b80915050919050565b68010000000000000000821115611e2d57611e2c611d69565b5b611e36816115e0565b82825580831015611e7257611e4a8161156f565b611e538461156f565b611e5c846115a0565b818101838201611e6c8183611927565b50505050505b505050565b68010000000000000000821115611e9157611e90611d69565b5b8054611e9c81611c27565b80841115611eb157611eb0848284866116f7565b5b80841015611ec657611ec58482848661164e565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b60008214611f1557611f14611cdc565b5b611f1e816118f6565b5050565b60008214611f3357611f32611cdc565b5b611f3c8161196c565b5050565b611f48612290565b611f5381848461223d565b505050565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b6120c9816115b5565b6120d4838254611c59565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff61210184611edd565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61214384611edd565b9350801983169250808416831791505092915050565b6000600883026121897fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82611eea565b6121938683611eea565b95508019841693508086168417925050509392505050565b6121b48261198a565b6121c76121c082611dd3565b83546120e1565b8255505050565b6121d98383836119e4565b505050565b6121e9838383611a4d565b505050565b6121f88282611b9b565b5050565b612205826119d2565b61221861221182611ddd565b8354612117565b8255505050565b811561222e5761222d611cdc565b5b6122388382611be1565b505050565b612246836119d2565b61225a61225282611ddd565b848454612159565b825550505050565b61226b816118ad565b811461227657600080fd5b50565b612282816118df565b811461228d57600080fd5b50565b60009056fea26469706673582212209d15c5501273e10408c38b0c27c1d9008c55404af21e411dc9d13c190f83a2b364736f6c63430008040033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/desci-contracts/contracts/DpidAliasRegistry.sol b/desci-contracts/contracts/DpidAliasRegistry.sol new file mode 100644 index 00000000..c68f6b50 --- /dev/null +++ b/desci-contracts/contracts/DpidAliasRegistry.sol @@ -0,0 +1,131 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; + +contract DpidAliasRegistry is OwnableUpgradeable { + uint256 public _firstDpid; + uint256 public nextDpid; + + // dpid => codex streamID + mapping(uint256 => string) public registry; + + + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + function __DpidAliasRegistry_init(uint256 firstDpid) public initializer { + OwnableUpgradeable.__Ownable_init(); + firstDpid = firstDpid; + nextDpid = firstDpid; + } + + /** + * Lookup the codex stream ID of a given dPID + * @param dpid the alias to lookup + */ + function lookup(uint256 dpid) public view returns(string memory) { + return registry[dpid]; + } + + event DpidMinted ( + uint256 dpid, + string streamID + ); + + /** + * Claim the next free dPID by pointing it to a codex stream ID + * + * @param streamId the codex stream ID to alias + */ + function mintDpid(string calldata streamId) public returns(uint256) { + uint256 thisDpid = nextDpid; + registry[thisDpid] = streamId; + + emit DpidMinted(thisDpid, streamId); + + nextDpid++; + return thisDpid; + } + + // ---------------------- // + // Backward compatibility // + // ---------------------- // + + struct LegacyVersion { + string cid; + uint256 timestamp; + } + + struct LegacyDpidEntry { + address owner; + LegacyVersion[] versions; + } + + /** + * Maps dPIDs before _firstDpid to it's complete history. + * This allows resolving every old state of a legacy dPID + * using only this contract. If the author wants to update + * this history, they need to call migrateDpid. + */ + mapping(uint256 => LegacyDpidEntry) public legacy; + + /** + * Lookup the token ID of an unmigrated, legacy dPID. + * Use this to + * @param dpid the alias to lookup + */ + function legacyLookup(uint256 dpid) public view returns(LegacyDpidEntry memory) { + return legacy[dpid]; + } + + event UpgradedDpid ( + uint256 dpid, + string streamId + ); + + /** + * The owner of a migrated ResearchObject token can call this function + * to claim the same dPID in this alias registry by pointing it to a codex + * streamID representing the same research object. + * + * This is an at-most-once operation, as the registry is immutable. + * The caller must make sure the stream represents the same history, + * and that it controls the stream. + * + * The legacy entry is deleted when migrated. + * + * @param dpid the dPID to migrate + * @param streamId the codex stream ID that shall supersede the legacy history + */ + function upgradeDpid(uint256 dpid, string calldata streamId) public { + // Assert that this dPID has not been set in the main registry + require(bytes(registry[dpid]).length == 0, "dpid already upgraded"); + // Assert that the tx was made by the owner of the imported entry + require(legacy[dpid].owner == tx.origin, "unauthorized dpid upgrade"); + + // Reclaim old dpid + registry[dpid] = streamId; + + emit UpgradedDpid(dpid, streamId); + + // Delete the legacy entry ? + // delete legacy[dpid]; + } + + // ---------------------------- // + // Population of legacy mapping // + // ---------------------------- // + + event ImportedDpid ( + uint256 dpid, + LegacyDpidEntry entry + ); + + function importLegacyDpid(uint256 dpid, LegacyDpidEntry calldata entry) public onlyOwner { + legacy[dpid] = entry; + emit ImportedDpid(dpid, entry); + } +} diff --git a/desci-contracts/hardhat.config.ts b/desci-contracts/hardhat.config.ts index 2659b66e..70862b6b 100644 --- a/desci-contracts/hardhat.config.ts +++ b/desci-contracts/hardhat.config.ts @@ -39,6 +39,9 @@ module.exports = { // alternative is to use ganache for more than running contract tests hardhat: { chainId: 1337, + accounts: { + mnemonic: process.env.MNEMONIC || DEFAULT_MNEMONIC, + }, }, optimism: { url: "http://127.0.0.1:8545", diff --git a/desci-contracts/package.json b/desci-contracts/package.json index d52bbebf..e26bfb55 100644 --- a/desci-contracts/package.json +++ b/desci-contracts/package.json @@ -4,7 +4,7 @@ "version": "0.2.3-rc3", "license": "MIT", "scripts": { - "test": "hardhat clean && hardhat test", + "test": "hardhat clean && hardhat test test/DpidAliasRegistry.ts", "build": "hardhat compile --network ganache", "makePackage": "rm -rf dist && tsc && cp -r .openzeppelin dist", "docker:build": "docker build -t desci-hardhat-node .", @@ -40,6 +40,7 @@ "@typechain/ethers-v5": "^9.0.0", "@typechain/hardhat": "^4.0.0", "@types/chai": "^4.2.21", + "@types/chai-as-promised": "^7.1.8", "@types/mocha": "^9.0.0", "@types/node": "^16.4.10", "as-base64": "^0.2.0", @@ -60,5 +61,8 @@ "ts-node": "^10.1.0", "typechain": "^7.0.0", "typescript": "^4.3.5" + }, + "dependencies": { + "chai-as-promised": "^7.1.2" } } diff --git a/desci-contracts/test/DpidAliasRegistry.ts b/desci-contracts/test/DpidAliasRegistry.ts new file mode 100644 index 00000000..006398a6 --- /dev/null +++ b/desci-contracts/test/DpidAliasRegistry.ts @@ -0,0 +1,227 @@ +import { expect, use } from "chai"; +import chaiAsPromised from "chai-as-promised"; +import { ethers as hhe, upgrades } from "hardhat"; +import { BigNumber, ContractReceipt, ContractTransaction } from "ethers"; +import { + DpidAliasRegistry__factory, + DpidAliasRegistry, +} from "../typechain-types"; +import { TransactionReceipt } from "@ethersproject/abstract-provider"; +import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; + +use(chaiAsPromised); + +const FIRST_DPID = hhe.BigNumber.from(100); + +describe("dPID", () => { + let _accounts: SignerWithAddress[]; + let owner: SignerWithAddress; + let user1: SignerWithAddress; + let user2: SignerWithAddress; + let DpidAliasRegistryFactory: DpidAliasRegistry__factory; + let dpidAliasRegistry: DpidAliasRegistry; + + before( async () => { + _accounts = await hhe.getSigners() + owner = _accounts[0]; + user1 = _accounts[1]; + user2 = _accounts[2]; + + DpidAliasRegistryFactory = await hhe.getContractFactory( + "DpidAliasRegistry", + ) as DpidAliasRegistry__factory; + + dpidAliasRegistry = await upgrades.deployProxy( + DpidAliasRegistryFactory, + [ + FIRST_DPID // firstDpid + ], + { + initializer: "__DpidAliasRegistry_init" + } + ) as DpidAliasRegistry; + await dpidAliasRegistry.deployed(); + + // Default instance to non-owner user + dpidAliasRegistry = dpidAliasRegistry.connect(user1); + }); + + describe("deployment", () => { + let reciept: TransactionReceipt; + let proxyAddress: string; + let implAddress: string; + let proxyAdmin: string; + + before(async () => { + reciept = await dpidAliasRegistry.deployTransaction.wait(); + proxyAddress = reciept.contractAddress; + implAddress = await upgrades.erc1967.getImplementationAddress(proxyAddress); + proxyAdmin = await upgrades.erc1967.getAdminAddress(proxyAddress); + + console.log({ + implAddress, + proxyAdmin, + implOwner: await dpidAliasRegistry.owner(), + }) + }); + + it("costs a reasonable amount of gas", async () => { + expect( + BigNumber.from(reciept.cumulativeGasUsed).lte(32000000), + `Gas limit exceeded` + ).to.be.true; + }); + + it("is made through proxy", () => { + expect(proxyAddress).not.to.equal(implAddress); + }); + + it("deploys implementation with proxy admin as owner", async () => { + const registryOwner = await dpidAliasRegistry.owner(); + expect(registryOwner).to.equal(proxyAdmin); + }); + + it("respects initializer dpid offset", async () => { + const nextDpid = await dpidAliasRegistry.nextDpid(); + expect(nextDpid).to.equal(FIRST_DPID); + }) + }); + + describe("alias registry", () => { + const STREAM_A = "kjzl6kcym7w8y7i5ugaq9a3vlm7hhuaf4bpl5o5qykeh4qtsa12c6rb5ekw6aaa"; + + describe("entry", () => { + let tx: ContractTransaction; + let res: ContractReceipt; + + before(async () => { + tx = await dpidAliasRegistry.mintDpid(STREAM_A); + res = await tx.wait(); + }); + + it("can be added", async () => { + const entry = await dpidAliasRegistry.registry(100); + expect(entry).to.equal(STREAM_A); + }); + + it("emits event on mint", async () => { + const event = res.events![0]; + const [ dpid, streamId ] = event.args!; + + expect(event.event).to.equal("DpidMinted"); + expect(dpid).to.equal(BigNumber.from(100)); + expect(streamId).to.equal(STREAM_A); + }); + + it("increases counter on mint", async () => { + const nextDpid = await dpidAliasRegistry.nextDpid(); + expect(nextDpid).to.equal(101); + }); + + it("gets next free dpid", async () => { + const STREAM_B = "kjzl6kcym7w8y7i5ugaq9a3vlm7hhuaf4bpl5o5qykeh4qtsa12c6rb5ekw6bbb"; + const tx2 = await dpidAliasRegistry.mintDpid(STREAM_B); + await tx2.wait(); + const entry = await dpidAliasRegistry.registry(101); + expect(entry).to.equal(STREAM_B); + }); + }); + + describe("legacy entry", () => { + let migrationEntry: DpidAliasRegistry.LegacyDpidEntryStruct; + + before(async () => { + migrationEntry = { + owner: user1.address, // of dpid owner + versions: [ + { + cid: "bafybeihdwdcefgh4dqkjv67uzcmw7ojee6xedzdetojuzjevtenxquvyku", + timestamp: 1716369952, + }, + ], + }; + }); + + describe("import", () => { + let successReceipt: ContractReceipt; + + it("can be done by contract owner", async () => { + const tx = await dpidAliasRegistry + .connect(owner) + .importLegacyDpid(0, migrationEntry); + successReceipt = await tx.wait(); + }); + + it("can be resolved", async () => { + const legacyEntry = await dpidAliasRegistry.legacyLookup(0); + + expect(legacyEntry.owner).to.equal(migrationEntry.owner); + expect(legacyEntry.versions.length).to.equal(1); + expect(legacyEntry.versions[0].cid).to.equal("bafybeihdwdcefgh4dqkjv67uzcmw7ojee6xedzdetojuzjevtenxquvyku"); + expect(legacyEntry.versions[0].timestamp).to.equal(1716369952); + }); + + it("emits an event on success", () => { + const event = successReceipt.events![0]; + const [ dpid, { owner }] = event.args!; + const args = successReceipt.events![0].args!; + + expect(event.event).to.equal("ImportedDpid"); + expect(dpid).to.equal(0); + expect(owner).to.equal(user1.address); + }); + + it("can NOT be done by others", async () => { + const doImport = async () => await dpidAliasRegistry + .importLegacyDpid(1, migrationEntry); + + await expect(doImport()).to.be.rejectedWith("caller is not the owner"); + }); + }); + + describe("upgrade", () => { + let successReceipt: ContractReceipt; + + it("can NOT be done by others", async () => { + const doUpgrade = async () => await dpidAliasRegistry + .connect(user2) + .upgradeDpid(0, STREAM_A); + + await expect(doUpgrade()).to.be.rejectedWith("unauthorized dpid upgrade"); + }); + + it("can NOT be done by contract owner", async () => { + const doUpgrade = async () => await dpidAliasRegistry + .connect(owner) + .upgradeDpid(0, STREAM_A); + + await expect(doUpgrade()).to.be.rejectedWith("unauthorized dpid upgrade"); + }); + + it("can be done by dpid owner", async () => { + const tx = await dpidAliasRegistry.upgradeDpid(0, STREAM_A); + successReceipt = await tx.wait(); + + const upgradedEntry = await dpidAliasRegistry.lookup(0); + expect(upgradedEntry).to.equal(STREAM_A); + }); + + it("cannot be done twice", async () => { + const doSecondUpgrade = async () => + await dpidAliasRegistry.upgradeDpid(0, STREAM_A); + + await expect(doSecondUpgrade()).to.be.rejectedWith("dpid already upgraded"); + }); + + it("emits an event", async () => { + const event = successReceipt.events![0]; + const [ dpid, streamId ] = event.args!; + + expect(event.event).to.equal("UpgradedDpid"); + expect(dpid).to.equal(0); + expect(streamId).to.equal(STREAM_A); + }); + }); + }); + }); +}); diff --git a/desci-contracts/typechain-types/ContextUpgradeable.js b/desci-contracts/typechain-types/ContextUpgradeable.js deleted file mode 100644 index 0e345787..00000000 --- a/desci-contracts/typechain-types/ContextUpgradeable.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -exports.__esModule = true; diff --git a/desci-contracts/typechain-types/DpidAliasRegistry.ts b/desci-contracts/typechain-types/DpidAliasRegistry.ts new file mode 100644 index 00000000..7fe4135e --- /dev/null +++ b/desci-contracts/typechain-types/DpidAliasRegistry.ts @@ -0,0 +1,497 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import { + BaseContract, + BigNumber, + BigNumberish, + BytesLike, + CallOverrides, + ContractTransaction, + Overrides, + PopulatedTransaction, + Signer, + utils, +} from "ethers"; +import { FunctionFragment, Result, EventFragment } from "@ethersproject/abi"; +import { Listener, Provider } from "@ethersproject/providers"; +import { TypedEventFilter, TypedEvent, TypedListener, OnEvent } from "./common"; + +export declare namespace DpidAliasRegistry { + export type LegacyVersionStruct = { cid: string; timestamp: BigNumberish }; + + export type LegacyVersionStructOutput = [string, BigNumber] & { + cid: string; + timestamp: BigNumber; + }; + + export type LegacyDpidEntryStruct = { + owner: string; + versions: DpidAliasRegistry.LegacyVersionStruct[]; + }; + + export type LegacyDpidEntryStructOutput = [ + string, + DpidAliasRegistry.LegacyVersionStructOutput[] + ] & { + owner: string; + versions: DpidAliasRegistry.LegacyVersionStructOutput[]; + }; +} + +export interface DpidAliasRegistryInterface extends utils.Interface { + contractName: "DpidAliasRegistry"; + functions: { + "__DpidAliasRegistry_init(uint256)": FunctionFragment; + "_firstDpid()": FunctionFragment; + "importLegacyDpid(uint256,(address,(string,uint256)[]))": FunctionFragment; + "legacy(uint256)": FunctionFragment; + "legacyLookup(uint256)": FunctionFragment; + "lookup(uint256)": FunctionFragment; + "mintDpid(string)": FunctionFragment; + "nextDpid()": FunctionFragment; + "owner()": FunctionFragment; + "registry(uint256)": FunctionFragment; + "renounceOwnership()": FunctionFragment; + "transferOwnership(address)": FunctionFragment; + "upgradeDpid(uint256,string)": FunctionFragment; + }; + + encodeFunctionData( + functionFragment: "__DpidAliasRegistry_init", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "_firstDpid", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "importLegacyDpid", + values: [BigNumberish, DpidAliasRegistry.LegacyDpidEntryStruct] + ): string; + encodeFunctionData( + functionFragment: "legacy", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "legacyLookup", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "lookup", + values: [BigNumberish] + ): string; + encodeFunctionData(functionFragment: "mintDpid", values: [string]): string; + encodeFunctionData(functionFragment: "nextDpid", values?: undefined): string; + encodeFunctionData(functionFragment: "owner", values?: undefined): string; + encodeFunctionData( + functionFragment: "registry", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "renounceOwnership", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "transferOwnership", + values: [string] + ): string; + encodeFunctionData( + functionFragment: "upgradeDpid", + values: [BigNumberish, string] + ): string; + + decodeFunctionResult( + functionFragment: "__DpidAliasRegistry_init", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "_firstDpid", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "importLegacyDpid", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "legacy", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "legacyLookup", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "lookup", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "mintDpid", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "nextDpid", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "owner", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "registry", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "renounceOwnership", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "transferOwnership", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "upgradeDpid", + data: BytesLike + ): Result; + + events: { + "DpidMinted(uint256,string)": EventFragment; + "ImportedDpid(uint256,tuple)": EventFragment; + "Initialized(uint8)": EventFragment; + "OwnershipTransferred(address,address)": EventFragment; + "UpgradedDpid(uint256,string)": EventFragment; + }; + + getEvent(nameOrSignatureOrTopic: "DpidMinted"): EventFragment; + getEvent(nameOrSignatureOrTopic: "ImportedDpid"): EventFragment; + getEvent(nameOrSignatureOrTopic: "Initialized"): EventFragment; + getEvent(nameOrSignatureOrTopic: "OwnershipTransferred"): EventFragment; + getEvent(nameOrSignatureOrTopic: "UpgradedDpid"): EventFragment; +} + +export type DpidMintedEvent = TypedEvent< + [BigNumber, string], + { dpid: BigNumber; streamID: string } +>; + +export type DpidMintedEventFilter = TypedEventFilter; + +export type ImportedDpidEvent = TypedEvent< + [BigNumber, DpidAliasRegistry.LegacyDpidEntryStructOutput], + { dpid: BigNumber; entry: DpidAliasRegistry.LegacyDpidEntryStructOutput } +>; + +export type ImportedDpidEventFilter = TypedEventFilter; + +export type InitializedEvent = TypedEvent<[number], { version: number }>; + +export type InitializedEventFilter = TypedEventFilter; + +export type OwnershipTransferredEvent = TypedEvent< + [string, string], + { previousOwner: string; newOwner: string } +>; + +export type OwnershipTransferredEventFilter = + TypedEventFilter; + +export type UpgradedDpidEvent = TypedEvent< + [BigNumber, string], + { dpid: BigNumber; streamId: string } +>; + +export type UpgradedDpidEventFilter = TypedEventFilter; + +export interface DpidAliasRegistry extends BaseContract { + contractName: "DpidAliasRegistry"; + connect(signerOrProvider: Signer | Provider | string): this; + attach(addressOrName: string): this; + deployed(): Promise; + + interface: DpidAliasRegistryInterface; + + queryFilter( + event: TypedEventFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>; + + listeners( + eventFilter?: TypedEventFilter + ): Array>; + listeners(eventName?: string): Array; + removeAllListeners( + eventFilter: TypedEventFilter + ): this; + removeAllListeners(eventName?: string): this; + off: OnEvent; + on: OnEvent; + once: OnEvent; + removeListener: OnEvent; + + functions: { + __DpidAliasRegistry_init( + firstDpid: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + _firstDpid(overrides?: CallOverrides): Promise<[BigNumber]>; + + importLegacyDpid( + dpid: BigNumberish, + entry: DpidAliasRegistry.LegacyDpidEntryStruct, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + legacy( + arg0: BigNumberish, + overrides?: CallOverrides + ): Promise<[string] & { owner: string }>; + + legacyLookup( + dpid: BigNumberish, + overrides?: CallOverrides + ): Promise<[DpidAliasRegistry.LegacyDpidEntryStructOutput]>; + + lookup(dpid: BigNumberish, overrides?: CallOverrides): Promise<[string]>; + + mintDpid( + streamId: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + nextDpid(overrides?: CallOverrides): Promise<[BigNumber]>; + + owner(overrides?: CallOverrides): Promise<[string]>; + + registry(arg0: BigNumberish, overrides?: CallOverrides): Promise<[string]>; + + renounceOwnership( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + transferOwnership( + newOwner: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + upgradeDpid( + dpid: BigNumberish, + streamId: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + }; + + __DpidAliasRegistry_init( + firstDpid: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + _firstDpid(overrides?: CallOverrides): Promise; + + importLegacyDpid( + dpid: BigNumberish, + entry: DpidAliasRegistry.LegacyDpidEntryStruct, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + legacy(arg0: BigNumberish, overrides?: CallOverrides): Promise; + + legacyLookup( + dpid: BigNumberish, + overrides?: CallOverrides + ): Promise; + + lookup(dpid: BigNumberish, overrides?: CallOverrides): Promise; + + mintDpid( + streamId: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + nextDpid(overrides?: CallOverrides): Promise; + + owner(overrides?: CallOverrides): Promise; + + registry(arg0: BigNumberish, overrides?: CallOverrides): Promise; + + renounceOwnership( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + transferOwnership( + newOwner: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + upgradeDpid( + dpid: BigNumberish, + streamId: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + callStatic: { + __DpidAliasRegistry_init( + firstDpid: BigNumberish, + overrides?: CallOverrides + ): Promise; + + _firstDpid(overrides?: CallOverrides): Promise; + + importLegacyDpid( + dpid: BigNumberish, + entry: DpidAliasRegistry.LegacyDpidEntryStruct, + overrides?: CallOverrides + ): Promise; + + legacy(arg0: BigNumberish, overrides?: CallOverrides): Promise; + + legacyLookup( + dpid: BigNumberish, + overrides?: CallOverrides + ): Promise; + + lookup(dpid: BigNumberish, overrides?: CallOverrides): Promise; + + mintDpid(streamId: string, overrides?: CallOverrides): Promise; + + nextDpid(overrides?: CallOverrides): Promise; + + owner(overrides?: CallOverrides): Promise; + + registry(arg0: BigNumberish, overrides?: CallOverrides): Promise; + + renounceOwnership(overrides?: CallOverrides): Promise; + + transferOwnership( + newOwner: string, + overrides?: CallOverrides + ): Promise; + + upgradeDpid( + dpid: BigNumberish, + streamId: string, + overrides?: CallOverrides + ): Promise; + }; + + filters: { + "DpidMinted(uint256,string)"( + dpid?: null, + streamID?: null + ): DpidMintedEventFilter; + DpidMinted(dpid?: null, streamID?: null): DpidMintedEventFilter; + + "ImportedDpid(uint256,tuple)"( + dpid?: null, + entry?: null + ): ImportedDpidEventFilter; + ImportedDpid(dpid?: null, entry?: null): ImportedDpidEventFilter; + + "Initialized(uint8)"(version?: null): InitializedEventFilter; + Initialized(version?: null): InitializedEventFilter; + + "OwnershipTransferred(address,address)"( + previousOwner?: string | null, + newOwner?: string | null + ): OwnershipTransferredEventFilter; + OwnershipTransferred( + previousOwner?: string | null, + newOwner?: string | null + ): OwnershipTransferredEventFilter; + + "UpgradedDpid(uint256,string)"( + dpid?: null, + streamId?: null + ): UpgradedDpidEventFilter; + UpgradedDpid(dpid?: null, streamId?: null): UpgradedDpidEventFilter; + }; + + estimateGas: { + __DpidAliasRegistry_init( + firstDpid: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + _firstDpid(overrides?: CallOverrides): Promise; + + importLegacyDpid( + dpid: BigNumberish, + entry: DpidAliasRegistry.LegacyDpidEntryStruct, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + legacy(arg0: BigNumberish, overrides?: CallOverrides): Promise; + + legacyLookup( + dpid: BigNumberish, + overrides?: CallOverrides + ): Promise; + + lookup(dpid: BigNumberish, overrides?: CallOverrides): Promise; + + mintDpid( + streamId: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + nextDpid(overrides?: CallOverrides): Promise; + + owner(overrides?: CallOverrides): Promise; + + registry(arg0: BigNumberish, overrides?: CallOverrides): Promise; + + renounceOwnership( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + transferOwnership( + newOwner: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + upgradeDpid( + dpid: BigNumberish, + streamId: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + }; + + populateTransaction: { + __DpidAliasRegistry_init( + firstDpid: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + _firstDpid(overrides?: CallOverrides): Promise; + + importLegacyDpid( + dpid: BigNumberish, + entry: DpidAliasRegistry.LegacyDpidEntryStruct, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + legacy( + arg0: BigNumberish, + overrides?: CallOverrides + ): Promise; + + legacyLookup( + dpid: BigNumberish, + overrides?: CallOverrides + ): Promise; + + lookup( + dpid: BigNumberish, + overrides?: CallOverrides + ): Promise; + + mintDpid( + streamId: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + nextDpid(overrides?: CallOverrides): Promise; + + owner(overrides?: CallOverrides): Promise; + + registry( + arg0: BigNumberish, + overrides?: CallOverrides + ): Promise; + + renounceOwnership( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + transferOwnership( + newOwner: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + upgradeDpid( + dpid: BigNumberish, + streamId: string, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + }; +} diff --git a/desci-contracts/typechain-types/DpidRegistry.js b/desci-contracts/typechain-types/DpidRegistry.js deleted file mode 100644 index 0e345787..00000000 --- a/desci-contracts/typechain-types/DpidRegistry.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -exports.__esModule = true; diff --git a/desci-contracts/typechain-types/ERC165.js b/desci-contracts/typechain-types/ERC165.js deleted file mode 100644 index 0e345787..00000000 --- a/desci-contracts/typechain-types/ERC165.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -exports.__esModule = true; diff --git a/desci-contracts/typechain-types/ERC165Upgradeable.js b/desci-contracts/typechain-types/ERC165Upgradeable.js deleted file mode 100644 index 0e345787..00000000 --- a/desci-contracts/typechain-types/ERC165Upgradeable.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -exports.__esModule = true; diff --git a/desci-contracts/typechain-types/ERC721.js b/desci-contracts/typechain-types/ERC721.js deleted file mode 100644 index 0e345787..00000000 --- a/desci-contracts/typechain-types/ERC721.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -exports.__esModule = true; diff --git a/desci-contracts/typechain-types/ERC721Upgradeable.js b/desci-contracts/typechain-types/ERC721Upgradeable.js deleted file mode 100644 index 0e345787..00000000 --- a/desci-contracts/typechain-types/ERC721Upgradeable.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -exports.__esModule = true; diff --git a/desci-contracts/typechain-types/IDpidRegistry.js b/desci-contracts/typechain-types/IDpidRegistry.js deleted file mode 100644 index 0e345787..00000000 --- a/desci-contracts/typechain-types/IDpidRegistry.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -exports.__esModule = true; diff --git a/desci-contracts/typechain-types/IERC165.js b/desci-contracts/typechain-types/IERC165.js deleted file mode 100644 index 0e345787..00000000 --- a/desci-contracts/typechain-types/IERC165.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -exports.__esModule = true; diff --git a/desci-contracts/typechain-types/IERC165Upgradeable.js b/desci-contracts/typechain-types/IERC165Upgradeable.js deleted file mode 100644 index 0e345787..00000000 --- a/desci-contracts/typechain-types/IERC165Upgradeable.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -exports.__esModule = true; diff --git a/desci-contracts/typechain-types/IERC721.js b/desci-contracts/typechain-types/IERC721.js deleted file mode 100644 index 0e345787..00000000 --- a/desci-contracts/typechain-types/IERC721.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -exports.__esModule = true; diff --git a/desci-contracts/typechain-types/IERC721Metadata.js b/desci-contracts/typechain-types/IERC721Metadata.js deleted file mode 100644 index 0e345787..00000000 --- a/desci-contracts/typechain-types/IERC721Metadata.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -exports.__esModule = true; diff --git a/desci-contracts/typechain-types/IERC721MetadataUpgradeable.js b/desci-contracts/typechain-types/IERC721MetadataUpgradeable.js deleted file mode 100644 index 0e345787..00000000 --- a/desci-contracts/typechain-types/IERC721MetadataUpgradeable.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -exports.__esModule = true; diff --git a/desci-contracts/typechain-types/IERC721Receiver.js b/desci-contracts/typechain-types/IERC721Receiver.js deleted file mode 100644 index 0e345787..00000000 --- a/desci-contracts/typechain-types/IERC721Receiver.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -exports.__esModule = true; diff --git a/desci-contracts/typechain-types/IERC721ReceiverUpgradeable.js b/desci-contracts/typechain-types/IERC721ReceiverUpgradeable.js deleted file mode 100644 index 0e345787..00000000 --- a/desci-contracts/typechain-types/IERC721ReceiverUpgradeable.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -exports.__esModule = true; diff --git a/desci-contracts/typechain-types/IERC721Upgradeable.js b/desci-contracts/typechain-types/IERC721Upgradeable.js deleted file mode 100644 index 0e345787..00000000 --- a/desci-contracts/typechain-types/IERC721Upgradeable.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -exports.__esModule = true; diff --git a/desci-contracts/typechain-types/Initializable.js b/desci-contracts/typechain-types/Initializable.js deleted file mode 100644 index 0e345787..00000000 --- a/desci-contracts/typechain-types/Initializable.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -exports.__esModule = true; diff --git a/desci-contracts/typechain-types/OwnableUpgradeable.js b/desci-contracts/typechain-types/OwnableUpgradeable.js deleted file mode 100644 index 0e345787..00000000 --- a/desci-contracts/typechain-types/OwnableUpgradeable.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -exports.__esModule = true; diff --git a/desci-contracts/typechain-types/ResearchObject.js b/desci-contracts/typechain-types/ResearchObject.js deleted file mode 100644 index 0e345787..00000000 --- a/desci-contracts/typechain-types/ResearchObject.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -exports.__esModule = true; diff --git a/desci-contracts/typechain-types/ResearchObjectMigrated.js b/desci-contracts/typechain-types/ResearchObjectMigrated.js deleted file mode 100644 index 0e345787..00000000 --- a/desci-contracts/typechain-types/ResearchObjectMigrated.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -exports.__esModule = true; diff --git a/desci-contracts/typechain-types/ResearchObjectV2.js b/desci-contracts/typechain-types/ResearchObjectV2.js deleted file mode 100644 index 0e345787..00000000 --- a/desci-contracts/typechain-types/ResearchObjectV2.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -exports.__esModule = true; diff --git a/desci-contracts/typechain-types/TestERC721.js b/desci-contracts/typechain-types/TestERC721.js deleted file mode 100644 index 0e345787..00000000 --- a/desci-contracts/typechain-types/TestERC721.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -exports.__esModule = true; diff --git a/desci-contracts/typechain-types/VersionedERC721.js b/desci-contracts/typechain-types/VersionedERC721.js deleted file mode 100644 index 0e345787..00000000 --- a/desci-contracts/typechain-types/VersionedERC721.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -exports.__esModule = true; diff --git a/desci-contracts/typechain-types/VersionedERC721V2.js b/desci-contracts/typechain-types/VersionedERC721V2.js deleted file mode 100644 index 0e345787..00000000 --- a/desci-contracts/typechain-types/VersionedERC721V2.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -exports.__esModule = true; diff --git a/desci-contracts/typechain-types/common.js b/desci-contracts/typechain-types/common.js deleted file mode 100644 index 0e345787..00000000 --- a/desci-contracts/typechain-types/common.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -exports.__esModule = true; diff --git a/desci-contracts/typechain-types/factories/ContextUpgradeable__factory.js b/desci-contracts/typechain-types/factories/ContextUpgradeable__factory.js deleted file mode 100644 index de6769d2..00000000 --- a/desci-contracts/typechain-types/factories/ContextUpgradeable__factory.js +++ /dev/null @@ -1,35 +0,0 @@ -"use strict"; -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -exports.__esModule = true; -exports.ContextUpgradeable__factory = void 0; -var ethers_1 = require("ethers"); -var _abi = [ - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "uint8", - name: "version", - type: "uint8" - }, - ], - name: "Initialized", - type: "event" - }, -]; -var ContextUpgradeable__factory = /** @class */ (function () { - function ContextUpgradeable__factory() { - } - ContextUpgradeable__factory.createInterface = function () { - return new ethers_1.utils.Interface(_abi); - }; - ContextUpgradeable__factory.connect = function (address, signerOrProvider) { - return new ethers_1.Contract(address, _abi, signerOrProvider); - }; - ContextUpgradeable__factory.abi = _abi; - return ContextUpgradeable__factory; -}()); -exports.ContextUpgradeable__factory = ContextUpgradeable__factory; diff --git a/desci-contracts/typechain-types/factories/DpidAliasRegistry__factory.ts b/desci-contracts/typechain-types/factories/DpidAliasRegistry__factory.ts new file mode 100644 index 00000000..122c5f10 --- /dev/null +++ b/desci-contracts/typechain-types/factories/DpidAliasRegistry__factory.ts @@ -0,0 +1,433 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import { Signer, utils, Contract, ContractFactory, Overrides } from "ethers"; +import { Provider, TransactionRequest } from "@ethersproject/providers"; +import type { + DpidAliasRegistry, + DpidAliasRegistryInterface, +} from "../DpidAliasRegistry"; + +const _abi = [ + { + inputs: [], + stateMutability: "nonpayable", + type: "constructor", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "dpid", + type: "uint256", + }, + { + indexed: false, + internalType: "string", + name: "streamID", + type: "string", + }, + ], + name: "DpidMinted", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "dpid", + type: "uint256", + }, + { + components: [ + { + internalType: "address", + name: "owner", + type: "address", + }, + { + components: [ + { + internalType: "string", + name: "cid", + type: "string", + }, + { + internalType: "uint256", + name: "timestamp", + type: "uint256", + }, + ], + internalType: "struct DpidAliasRegistry.LegacyVersion[]", + name: "versions", + type: "tuple[]", + }, + ], + indexed: false, + internalType: "struct DpidAliasRegistry.LegacyDpidEntry", + name: "entry", + type: "tuple", + }, + ], + name: "ImportedDpid", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint8", + name: "version", + type: "uint8", + }, + ], + name: "Initialized", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "previousOwner", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "newOwner", + type: "address", + }, + ], + name: "OwnershipTransferred", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "dpid", + type: "uint256", + }, + { + indexed: false, + internalType: "string", + name: "streamId", + type: "string", + }, + ], + name: "UpgradedDpid", + type: "event", + }, + { + inputs: [ + { + internalType: "uint256", + name: "firstDpid", + type: "uint256", + }, + ], + name: "__DpidAliasRegistry_init", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "_firstDpid", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "dpid", + type: "uint256", + }, + { + components: [ + { + internalType: "address", + name: "owner", + type: "address", + }, + { + components: [ + { + internalType: "string", + name: "cid", + type: "string", + }, + { + internalType: "uint256", + name: "timestamp", + type: "uint256", + }, + ], + internalType: "struct DpidAliasRegistry.LegacyVersion[]", + name: "versions", + type: "tuple[]", + }, + ], + internalType: "struct DpidAliasRegistry.LegacyDpidEntry", + name: "entry", + type: "tuple", + }, + ], + name: "importLegacyDpid", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + name: "legacy", + outputs: [ + { + internalType: "address", + name: "owner", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "dpid", + type: "uint256", + }, + ], + name: "legacyLookup", + outputs: [ + { + components: [ + { + internalType: "address", + name: "owner", + type: "address", + }, + { + components: [ + { + internalType: "string", + name: "cid", + type: "string", + }, + { + internalType: "uint256", + name: "timestamp", + type: "uint256", + }, + ], + internalType: "struct DpidAliasRegistry.LegacyVersion[]", + name: "versions", + type: "tuple[]", + }, + ], + internalType: "struct DpidAliasRegistry.LegacyDpidEntry", + name: "", + type: "tuple", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "dpid", + type: "uint256", + }, + ], + name: "lookup", + outputs: [ + { + internalType: "string", + name: "", + type: "string", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "string", + name: "streamId", + type: "string", + }, + ], + name: "mintDpid", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "nextDpid", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "owner", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + name: "registry", + outputs: [ + { + internalType: "string", + name: "", + type: "string", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "renounceOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "newOwner", + type: "address", + }, + ], + name: "transferOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "dpid", + type: "uint256", + }, + { + internalType: "string", + name: "streamId", + type: "string", + }, + ], + name: "upgradeDpid", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, +]; + +const _bytecode = + "0x60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d3565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000127565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff161015620000ed5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e4919062000149565b60405180910390a15b565b6000620000fe60278362000166565b91506200010b8262000184565b604082019050919050565b620001218162000177565b82525050565b600060208201905081810360008301526200014281620000ef565b9050919050565b600060208201905062000160600083018462000116565b92915050565b600082825260208201905092915050565b600060ff82169050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b6122cb80620001e36000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c8063810a9afa1161008c578063b724de3a11610066578063b724de3a14610212578063dc5d7a2e14610242578063ded8896b14610260578063f2fde38b1461027c576100cf565b8063810a9afa146101a65780638da5cb5b146101d6578063afc26911146101f4576100cf565b80630a874df6146100d4578063144ae85514610104578063362b3e63146101205780635893253c1461013c578063715018a61461016c578063788243d514610176575b600080fd5b6100ee60048036038101906100e99190610dff565b610298565b6040516100fb919061131c565b60405180910390f35b61011e60048036038101906101199190610e80565b61033d565b005b61013a60048036038101906101359190610dff565b6103a5565b005b61015660048036038101906101519190610dff565b6104eb565b604051610163919061131c565b60405180910390f35b61017461058b565b005b610190600480360381019061018b9190610dff565b61059f565b60405161019d91906112e6565b60405180910390f35b6101c060048036038101906101bb9190610dff565b6105dd565b6040516101cd91906113fe565b60405180910390f35b6101de61075b565b6040516101eb91906112e6565b60405180910390f35b6101fc610785565b6040516102099190611420565b60405180910390f35b61022c60048036038101906102279190610dba565b61078b565b6040516102399190611420565b60405180910390f35b61024a610813565b6040516102579190611420565b60405180910390f35b61027a60048036038101906102759190610e28565b610819565b005b61029660048036038101906102919190610d91565b610982565b005b60606067600083815260200190815260200160002080546102b890611c27565b80601f01602080910402602001604051908101604052809291908181526020018280546102e490611c27565b80156103315780601f1061030657610100808354040283529160200191610331565b820191906000526020600020905b81548152906001019060200180831161031457829003601f168201915b50505050509050919050565b610345610a06565b8060686000848152602001908152602001600020818161036591906121ee565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada828260405161039992919061146d565b60405180910390a15050565b60008060019054906101000a900460ff161590508080156103d65750600160008054906101000a900460ff1660ff16105b8061040357506103e530610a84565b1580156104025750600160008054906101000a900460ff1660ff16145b5b610442576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104399061137e565b60405180910390fd5b60016000806101000a81548160ff021916908360ff160217905550801561047f576001600060016101000a81548160ff0219169083151502179055505b610487610aa7565b8160668190555080156104e75760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516104de9190611301565b60405180910390a15b5050565b6067602052806000526040600020600091509050805461050a90611c27565b80601f016020809104026020016040519081016040528092919081815260200182805461053690611c27565b80156105835780601f1061055857610100808354040283529160200191610583565b820191906000526020600020905b81548152906001019060200180831161056657829003601f168201915b505050505081565b610593610a06565b61059d6000610b00565b565b60686020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b6105e5610c2f565b606860008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b8282101561074c57838290600052602060002090600202016040518060400160405290816000820180546106b190611c27565b80601f01602080910402602001604051908101604052809291908181526020018280546106dd90611c27565b801561072a5780601f106106ff5761010080835404028352916020019161072a565b820191906000526020600020905b81548152906001019060200180831161070d57829003601f168201915b505050505081526020016001820154815250508152602001906001019061067e565b50505050815250509050919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60665481565b600080606654905083836067600084815260200190815260200160002091906107b5929190610c5f565b507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d8185856040516107e99392919061143b565b60405180910390a16066600081548092919061080490611c75565b91905055508091505092915050565b60655481565b600060676000858152602001908152602001600020805461083990611c27565b90501461087b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108729061133e565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff166068600085815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461091f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610916906113de565b60405180910390fd5b8181606760008681526020019081526020016000209190610941929190610c5f565b507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c8383836040516109759392919061143b565b60405180910390a1505050565b61098a610a06565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156109fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109f19061135e565b60405180910390fd5b610a0381610b00565b50565b610a0e610bc6565b73ffffffffffffffffffffffffffffffffffffffff16610a2c61075b565b73ffffffffffffffffffffffffffffffffffffffff1614610a82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a799061139e565b60405180910390fd5b565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610af6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aed906113be565b60405180910390fd5b610afe610bce565b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600060019054906101000a900460ff16610c1d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c14906113be565b60405180910390fd5b610c2d610c28610bc6565b610b00565b565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b828054610c6b90611c27565b90600052602060002090601f016020900481019282610c8d5760008555610cd4565b82601f10610ca657803560ff1916838001178555610cd4565b82800160010185558215610cd4579182015b82811115610cd3578235825591602001919060010190610cb8565b5b509050610ce19190610ce5565b5090565b5b80821115610cfe576000816000905550600101610ce6565b5090565b600081359050610d1181612262565b92915050565b60008083601f840112610d2957600080fd5b8235905067ffffffffffffffff811115610d4257600080fd5b602083019150836001820283011115610d5a57600080fd5b9250929050565b600060408284031215610d7357600080fd5b81905092915050565b600081359050610d8b81612279565b92915050565b600060208284031215610da357600080fd5b6000610db184828501610d02565b91505092915050565b60008060208385031215610dcd57600080fd5b600083013567ffffffffffffffff811115610de757600080fd5b610df385828601610d17565b92509250509250929050565b600060208284031215610e1157600080fd5b6000610e1f84828501610d7c565b91505092915050565b600080600060408486031215610e3d57600080fd5b6000610e4b86828701610d7c565b935050602084013567ffffffffffffffff811115610e6857600080fd5b610e7486828701610d17565b92509250509250925092565b60008060408385031215610e9357600080fd5b6000610ea185828601610d7c565b925050602083013567ffffffffffffffff811115610ebe57600080fd5b610eca85828601610d61565b9150509250929050565b6000610ee0838361123c565b905092915050565b6000610ef4838361128b565b905092915050565b610f05816118ad565b82525050565b610f14816118ad565b82525050565b6000610f26838561161b565b935083602084028501610f3884611586565b8060005b87811015610f7c578484038952610f538284611818565b610f5d8582610ed4565b9450610f6883611601565b925060208a01995050600181019050610f3c565b50829750879450505050509392505050565b6000610f99826115d5565b610fa3818561161b565b935083602082028501610fb585611590565b8060005b85811015610ff15784840389528151610fd28582610ee8565b9450610fdd8361160e565b925060208a01995050600181019050610fb9565b50829750879550505050505092915050565b61100c8161199c565b82525050565b600061101e838561162c565b935061102b838584611b59565b61103483611ecc565b840190509392505050565b600061104b838561163d565b9350611058838584611b59565b61106183611ecc565b840190509392505050565b6000611077826115f6565b611081818561162c565b9350611091818560208601611b68565b61109a81611ecc565b840191505092915050565b60006110b0826115f6565b6110ba818561163d565b93506110ca818560208601611b68565b6110d381611ecc565b840191505092915050565b60006110eb60158361163d565b91506110f682611f58565b602082019050919050565b600061110e60268361163d565b915061111982611f81565b604082019050919050565b6000611131602e8361163d565b915061113c82611fd0565b604082019050919050565b600061115460208361163d565b915061115f8261201f565b602082019050919050565b6000611177602b8361163d565b915061118282612048565b604082019050919050565b600061119a60198361163d565b91506111a582612097565b602082019050919050565b6000604083016111c36000840184611753565b6111d06000860182610efc565b506111de602084018461176a565b85830360208701526111f1838284610f1a565b925050508091505092915050565b60006040830160008301516112176000860182610efc565b506020830151848203602086015261122f8282610f8e565b9150508091505092915050565b60006040830161124f60008401846117c1565b8583036000870152611262838284611012565b92505050611273602084018461183c565b61128060208601826112c8565b508091505092915050565b600060408301600083015184820360008601526112a8828261106c565b91505060208301516112bd60208601826112c8565b508091505092915050565b6112d1816118df565b82525050565b6112e0816118df565b82525050565b60006020820190506112fb6000830184610f0b565b92915050565b60006020820190506113166000830184611003565b92915050565b6000602082019050818103600083015261133681846110a5565b905092915050565b60006020820190508181036000830152611357816110de565b9050919050565b6000602082019050818103600083015261137781611101565b9050919050565b6000602082019050818103600083015261139781611124565b9050919050565b600060208201905081810360008301526113b781611147565b9050919050565b600060208201905081810360008301526113d78161116a565b9050919050565b600060208201905081810360008301526113f78161118d565b9050919050565b6000602082019050818103600083015261141881846111ff565b905092915050565b600060208201905061143560008301846112d7565b92915050565b600060408201905061145060008301866112d7565b818103602083015261146381848661103f565b9050949350505050565b600060408201905061148260008301856112d7565b818103602083015261149481846111b0565b90509392505050565b600080833560016020038436030381126114b657600080fd5b80840192508235915067ffffffffffffffff8211156114d457600080fd5b6020830192506020820236038313156114ec57600080fd5b509250929050565b6000808335600160200384360303811261150d57600080fd5b80840192508235915067ffffffffffffffff82111561152b57600080fd5b60208301925060018202360383131561154357600080fd5b509250929050565b60008235600160400383360303811261156357600080fd5b80830191505092915050565b600081905061157f826002611853565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b60208410600081146116a757601f841160018114611677576116708685611c59565b83556116a1565b611680836115b5565b6116956020601f880104820160018301611904565b61169f87856120c0565b505b506116f0565b6116b0826115b5565b6020601f8701048101601f871680156116d1576116d08160018403611d98565b5b6116e36020601f890104840183611904565b6001886002021785555050505b5050505050565b6020831060008114611742576020851060008114611720576117198685611c59565b835561173c565b8360ff1916935083611731846115b5565b556001866002020183555b5061174c565b6001856002020182555b5050505050565b60006117626020840184610d02565b905092915050565b6000808335600160200384360303811261178357600080fd5b83810192508235915060208301925067ffffffffffffffff8211156117a757600080fd5b6020820236038413156117b957600080fd5b509250929050565b600080833560016020038436030381126117da57600080fd5b83810192508235915060208301925067ffffffffffffffff8211156117fe57600080fd5b60018202360384131561181057600080fd5b509250929050565b60008235600160400383360303811261183057600080fd5b82810191505092915050565b600061184b6020840184610d7c565b905092915050565b600061185e826118df565b9150611869836118df565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156118a2576118a1611d0b565b5b828202905092915050565b60006118b8826118bf565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b611901600082611e77565b50565b5b8181101561192357611918600082611f40565b600181019050611905565b5050565b5b818110156119465761193b600082611f22565b600281019050611928565b5050565b818110156119685761195d600082611f40565b60018101905061194a565b5050565b6119796000808301611f04565b611987600060018301611f40565b50565b6000611995826119ae565b9050919050565b60006119a7826118e9565b9050919050565b60006119b9826119c0565b9050919050565b60006119cb826118bf565b9050919050565b60006119dd826118df565b9050919050565b6119ee83836115ca565b6119f88183611e13565b611a0183611586565b611a0a836115a0565b6000805b84811015611a4357611a20848861154b565b611a2b81848661221f565b60208501945060028401935050600181019050611a0e565b5050505050505050565b611a5783836115eb565b67ffffffffffffffff811115611a7057611a6f611d69565b5b611a7a8254611c27565b600080601f8411601f84111715611a9757611a94856115b5565b90505b601f831115611aca576020601f85010481016020851015611ab6578190505b611ac86020601f860104830182611904565b505b601f841160018114611af75760008515611ae5578388013590505b611aef8682611c59565b875550611b4f565b601f1985168260005b82811015611b2557858a01358255600182019150602086019550602081019050611b00565b87831015611b4257858a0135611b3e601f8a1682611cbe565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b83811015611b86578082015181840152602081019050611b6b565b83811115611b95576000848401525b50505050565b600081016000830180611bad81611de7565b9050611bb981846121ab565b5050506001810160208301611bce818561149d565b611bd98183866121ce565b505050505050565b6000810160008301611bf381856114f4565b611bfe8183866121de565b50505050600181016020830180611c1481611dfd565b9050611c2081846121fc565b5050505050565b60006002820490506001821680611c3f57607f821691505b60208210811415611c5357611c52611d3a565b5b50919050565b6000611c658383611cbe565b9150826002028217905092915050565b6000611c80826118df565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415611cb357611cb2611d0b565b5b600182019050919050565b6000611ccf60001984600802611ef7565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611dc87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83602003600802611ef7565b815481168255505050565b6000819050919050565b6000819050919050565b60008135611df481612262565b80915050919050565b60008135611e0a81612279565b80915050919050565b68010000000000000000821115611e2d57611e2c611d69565b5b611e36816115e0565b82825580831015611e7257611e4a8161156f565b611e538461156f565b611e5c846115a0565b818101838201611e6c8183611927565b50505050505b505050565b68010000000000000000821115611e9157611e90611d69565b5b8054611e9c81611c27565b80841115611eb157611eb0848284866116f7565b5b80841015611ec657611ec58482848661164e565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b60008214611f1557611f14611cdc565b5b611f1e816118f6565b5050565b60008214611f3357611f32611cdc565b5b611f3c8161196c565b5050565b611f48612290565b611f5381848461223d565b505050565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b6120c9816115b5565b6120d4838254611c59565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff61210184611edd565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61214384611edd565b9350801983169250808416831791505092915050565b6000600883026121897fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82611eea565b6121938683611eea565b95508019841693508086168417925050509392505050565b6121b48261198a565b6121c76121c082611dd3565b83546120e1565b8255505050565b6121d98383836119e4565b505050565b6121e9838383611a4d565b505050565b6121f88282611b9b565b5050565b612205826119d2565b61221861221182611ddd565b8354612117565b8255505050565b811561222e5761222d611cdc565b5b6122388382611be1565b505050565b612246836119d2565b61225a61225282611ddd565b848454612159565b825550505050565b61226b816118ad565b811461227657600080fd5b50565b612282816118df565b811461228d57600080fd5b50565b60009056fea26469706673582212209d15c5501273e10408c38b0c27c1d9008c55404af21e411dc9d13c190f83a2b364736f6c63430008040033"; + +type DpidAliasRegistryConstructorParams = + | [signer?: Signer] + | ConstructorParameters; + +const isSuperArgs = ( + xs: DpidAliasRegistryConstructorParams +): xs is ConstructorParameters => xs.length > 1; + +export class DpidAliasRegistry__factory extends ContractFactory { + constructor(...args: DpidAliasRegistryConstructorParams) { + if (isSuperArgs(args)) { + super(...args); + } else { + super(_abi, _bytecode, args[0]); + } + this.contractName = "DpidAliasRegistry"; + } + + deploy( + overrides?: Overrides & { from?: string | Promise } + ): Promise { + return super.deploy(overrides || {}) as Promise; + } + getDeployTransaction( + overrides?: Overrides & { from?: string | Promise } + ): TransactionRequest { + return super.getDeployTransaction(overrides || {}); + } + attach(address: string): DpidAliasRegistry { + return super.attach(address) as DpidAliasRegistry; + } + connect(signer: Signer): DpidAliasRegistry__factory { + return super.connect(signer) as DpidAliasRegistry__factory; + } + static readonly contractName: "DpidAliasRegistry"; + public readonly contractName: "DpidAliasRegistry"; + static readonly bytecode = _bytecode; + static readonly abi = _abi; + static createInterface(): DpidAliasRegistryInterface { + return new utils.Interface(_abi) as DpidAliasRegistryInterface; + } + static connect( + address: string, + signerOrProvider: Signer | Provider + ): DpidAliasRegistry { + return new Contract(address, _abi, signerOrProvider) as DpidAliasRegistry; + } +} diff --git a/desci-contracts/typechain-types/factories/DpidRegistry__factory.js b/desci-contracts/typechain-types/factories/DpidRegistry__factory.js deleted file mode 100644 index 0ad9e077..00000000 --- a/desci-contracts/typechain-types/factories/DpidRegistry__factory.js +++ /dev/null @@ -1,483 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - if (typeof b !== "function" && b !== null) - throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -exports.__esModule = true; -exports.DpidRegistry__factory = void 0; -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -var ethers_1 = require("ethers"); -var _abi = [ - { - inputs: [], - stateMutability: "nonpayable", - type: "constructor" - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "uint8", - name: "version", - type: "uint8" - }, - ], - name: "Initialized", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "previousOwner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "newOwner", - type: "address" - }, - ], - name: "OwnershipTransferred", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "bytes32", - name: "prefix", - type: "bytes32" - }, - { - indexed: false, - internalType: "uint256", - name: "entryId", - type: "uint256" - }, - ], - name: "Register", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "bytes32", - name: "prefix", - type: "bytes32" - }, - { - indexed: false, - internalType: "address", - name: "registrant", - type: "address" - }, - { - indexed: false, - internalType: "address[]", - name: "tokenGate", - type: "address[]" - }, - ], - name: "RegisterOrganization", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "bytes32", - name: "prefix", - type: "bytes32" - }, - { - indexed: false, - internalType: "address", - name: "registrant", - type: "address" - }, - { - indexed: false, - internalType: "address[]", - name: "tokenGate", - type: "address[]" - }, - ], - name: "UpdateOrganization", - type: "event" - }, - { - inputs: [ - { - internalType: "bytes32", - name: "prefix", - type: "bytes32" - }, - { - internalType: "uint256", - name: "entryId", - type: "uint256" - }, - ], - name: "exists", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "bytes32", - name: "prefix", - type: "bytes32" - }, - { - internalType: "uint256", - name: "entryId", - type: "uint256" - }, - ], - name: "get", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [], - name: "getFee", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [], - name: "getOrgFee", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "bytes32", - name: "prefix", - type: "bytes32" - }, - ], - name: "getOrganization", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256" - }, - { - internalType: "address", - name: "", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [], - name: "initialize", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "bytes32", - name: "", - type: "bytes32" - }, - ], - name: "organizations", - outputs: [ - { - internalType: "bytes32", - name: "prefix", - type: "bytes32" - }, - { - internalType: "address", - name: "registrant", - type: "address" - }, - { - internalType: "uint256", - name: "count", - type: "uint256" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [], - name: "owner", - outputs: [ - { - internalType: "address", - name: "", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "bytes32", - name: "prefix", - type: "bytes32" - }, - { - internalType: "uint256", - name: "entry", - type: "uint256" - }, - ], - name: "put", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256" - }, - ], - stateMutability: "payable", - type: "function" - }, - { - inputs: [ - { - internalType: "bytes32", - name: "prefix", - type: "bytes32" - }, - ], - name: "registerOrg", - outputs: [], - stateMutability: "payable", - type: "function" - }, - { - inputs: [ - { - internalType: "bytes32", - name: "prefix", - type: "bytes32" - }, - { - internalType: "address[]", - name: "tokenGate", - type: "address[]" - }, - ], - name: "registerOrgWithGate", - outputs: [], - stateMutability: "payable", - type: "function" - }, - { - inputs: [], - name: "renounceOwnership", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "gweiFee", - type: "uint256" - }, - ], - name: "setFee", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "gweiFee", - type: "uint256" - }, - ], - name: "setOrgFee", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "string", - name: "source", - type: "string" - }, - ], - name: "stringToBytes32", - outputs: [ - { - internalType: "bytes32", - name: "result", - type: "bytes32" - }, - ], - stateMutability: "pure", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "newOwner", - type: "address" - }, - ], - name: "transferOwnership", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "bytes32", - name: "prefix", - type: "bytes32" - }, - { - internalType: "address[]", - name: "tokenGate", - type: "address[]" - }, - ], - name: "updateOrg", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "bytes32", - name: "prefix", - type: "bytes32" - }, - ], - name: "validateCharacters", - outputs: [ - { - internalType: "bool", - name: "valid", - type: "bool" - }, - ], - stateMutability: "pure", - type: "function" - }, - { - inputs: [], - name: "withdraw", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, -]; -var _bytecode = "0x60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d3565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000127565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff161015620000ed5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e4919062000149565b60405180910390a15b565b6000620000fe60278362000166565b91506200010b8262000184565b604082019050919050565b620001218162000177565b82525050565b600060208201905081810360008301526200014281620000ef565b9050919050565b600060208201905062000160600083018462000116565b92915050565b600082825260208201905092915050565b600060ff82169050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b61230880620001e36000396000f3fe6080604052600436106101145760003560e01c80638129fc1c116100a0578063ced72f8711610064578063ced72f871461037f578063cef25dbc146103aa578063cfb51928146103c6578063da4a984214610403578063f2fde38b1461043357610114565b80638129fc1c146102aa57806381e104ca146102c15780638da5cb5b146102ec578063a40a990b14610317578063ba51b14e1461034057610114565b80634b22d5d0116100e75780634b22d5d0146101c75780634fb6020e146102045780635cb316351461022d57806369fe0e2d1461026a578063715018a61461029357610114565b80631785b6771461011957806318ae19c21461013557806322b3cd4e146101725780633ccfd60b146101b0575b600080fd5b610133600480360381019061012e9190611889565b61045c565b005b34801561014157600080fd5b5061015c60048036038101906101579190611906565b6104d8565b6040516101699190611e0a565b60405180910390f35b34801561017e57600080fd5b5061019960048036038101906101949190611889565b610568565b6040516101a7929190611e25565b60405180910390f35b3480156101bc57600080fd5b506101c561060e565b005b3480156101d357600080fd5b506101ee60048036038101906101e99190611889565b61066c565b6040516101fb9190611bfb565b60405180910390f35b34801561021057600080fd5b5061022b60048036038101906102269190611983565b610845565b005b34801561023957600080fd5b50610254600480360381019061024f9190611906565b610857565b6040516102619190611bfb565b60405180910390f35b34801561027657600080fd5b50610291600480360381019061028c9190611983565b6108d8565b005b34801561029f57600080fd5b506102a86108ea565b005b3480156102b657600080fd5b506102bf6108fe565b005b3480156102cd57600080fd5b506102d6610cfa565b6040516102e39190611e0a565b60405180910390f35b3480156102f857600080fd5b50610301610d04565b60405161030e9190611be0565b60405180910390f35b34801561032357600080fd5b5061033e600480360381019061033991906118b2565b610d2e565b005b34801561034c57600080fd5b5061036760048036038101906103629190611889565b610e52565b60405161037693929190611c6f565b60405180910390f35b34801561038b57600080fd5b50610394610e9c565b6040516103a19190611e0a565b60405180910390f35b6103c460048036038101906103bf91906118b2565b610ea6565b005b3480156103d257600080fd5b506103ed60048036038101906103e89190611942565b610f41565b6040516103fa9190611c16565b60405180910390f35b61041d60048036038101906104189190611906565b610f6b565b60405161042a9190611e0a565b60405180910390f35b34801561043f57600080fd5b5061045a60048036038101906104559190611860565b611227565b005b6104d581600067ffffffffffffffff8111156104a1577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156104cf5781602001602082028036833780820191505090505b50610ea6565b50565b600082606560008581526020019081526020016000206000015414610532576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052990611d6a565b60405180910390fd5b60006065600085815260200190815260200160002090508060030160008481526020019081526020016000205491505092915050565b600080826065600085815260200190815260200160002060000154146105c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ba90611d6a565b60405180910390fd5b600060656000858152602001908152602001600020905080600401548160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169250925050915091565b6106166112ab565b6000610620610d04565b90508073ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050158015610668573d6000803e3d6000fd5b5050565b600080600090506000806040518060600160405280602781526020016122ac60279139905060005b602060ff1681101561082357600060f81b8682602081106106de577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561071257809250610823565b60005b825181101561080f57828181518110610757577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168783602081106107bd577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156107fc5784806107f490611fcb565b95505061080f565b808061080790611fcb565b915050610715565b50808061081b90611fcb565b915050610694565b50818310156108385760009350505050610840565b600193505050505b919050565b61084d6112ab565b8060678190555050565b6000826065600085815260200190815260200160002060000154146108b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108a890611d6a565b60405180910390fd5b60006065600085815260200190815260200160002090508060040154831091505092915050565b6108e06112ab565b8060668190555050565b6108f26112ab565b6108fc6000611329565b565b60008060019054906101000a900460ff1615905080801561092f5750600160008054906101000a900460ff1660ff16105b8061095c575061093e306113ef565b15801561095b5750600160008054906101000a900460ff1660ff16145b5b61099b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099290611d8a565b60405180910390fd5b60016000806101000a81548160ff021916908360ff16021790555080156109d8576001600060016101000a81548160ff0219169083151502179055505b6601c6bf526340006066819055506706f05b59d3b2000060678190555060008067ffffffffffffffff811115610a37577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051908082528060200260200182016040528015610a655781602001602082028036833780820191505090505b509050610a73600082611412565b610a9d7f647069640000000000000000000000000000000000000000000000000000000082611412565b610ac77f646369746500000000000000000000000000000000000000000000000000000082611412565b610af17f646576000000000000000000000000000000000000000000000000000000000082611412565b610b1b7f737461676500000000000000000000000000000000000000000000000000000082611412565b610b457f626574610000000000000000000000000000000000000000000000000000000082611412565b610b6f7f646573636900000000000000000000000000000000000000000000000000000082611412565b610b997f6e6f64650000000000000000000000000000000000000000000000000000000082611412565b610bc37f6e6f64657300000000000000000000000000000000000000000000000000000082611412565b610bed7f646f69000000000000000000000000000000000000000000000000000000000082611412565b610c177f610000000000000000000000000000000000000000000000000000000000000082611412565b610c417f640000000000000000000000000000000000000000000000000000000000000082611412565b610c6b7f780000000000000000000000000000000000000000000000000000000000000082611412565b610c957f7a0000000000000000000000000000000000000000000000000000000000000082611412565b610c9d6115a5565b508015610cf75760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024986001604051610cee9190611ccf565b60405180910390a15b50565b6000606754905090565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b81610d376115fe565b73ffffffffffffffffffffffffffffffffffffffff166065600083815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610dda576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dd190611d4a565b60405180910390fd5b600060656000858152602001908152602001600020905082816002019080519060200190610e09929190611667565b507f2f78800ab5b47f6617eaf3124043ced0ee3ae49c0b4a77167ee4cd2fbc674f0484610e346115fe565b85604051610e4493929190611c31565b60405180910390a150505050565b60656020528060005260406000206000915090508060000154908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060040154905083565b6000606654905090565b606754341015610eeb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ee290611dea565b60405180910390fd5b610ef48261066c565b610f33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2a90611d6a565b60405180910390fd5b610f3d8282611412565b5050565b600080829050600081511415610f5d576000801b915050610f66565b60208301519150505b919050565b6000606654341015610fb2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fa990611dea565b60405180910390fd5b8260656000858152602001908152602001600020600001541461100a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161100190611d6a565b60405180910390fd5b60006065600085815260200190815260200160002090506000816002018054905011156111a6576000816002018054905090506000805b82811015611162576000846002018281548110611087577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008173ffffffffffffffffffffffffffffffffffffffff166370a082316110da6115fe565b6040518263ffffffff1660e01b81526004016110f69190611be0565b60206040518083038186803b15801561110e57600080fd5b505afa158015611122573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061114691906119ac565b1115611156576001925050611162565b81600101915050611041565b50806111a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119a90611d2a565b60405180910390fd5b50505b60008160040154905083826003016000838152602001908152602001600020819055507fd5fa0e9a716b3ec4895a48223ad309e2d3fa5e27f04d8dc9b3c33cc738a50eb085826040516111fa929190611ca6565b60405180910390a181600401600081548092919061121790611fcb565b9190505550809250505092915050565b61122f6112ab565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561129f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161129690611d0a565b60405180910390fd5b6112a881611329565b50565b6112b36115fe565b73ffffffffffffffffffffffffffffffffffffffff166112d1610d04565b73ffffffffffffffffffffffffffffffffffffffff1614611327576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161131e90611daa565b60405180910390fd5b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6000801b606560008481526020019081526020016000206000015414801561149c5750600073ffffffffffffffffffffffffffffffffffffffff166065600084815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b6114db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114d290611cea565b60405180910390fd5b60006065600084815260200190815260200160002090506114fa6115fe565b8160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508281600001819055508181600201908051906020019061155d929190611667565b507f1603286ac6b9f753cbc1a1d33146ab15a401314d80d8553aa8fb1473df47f3ec836115886115fe565b8460405161159893929190611c31565b60405180910390a1505050565b600060019054906101000a900460ff166115f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115eb90611dca565b60405180910390fd5b6115fc611606565b565b600033905090565b600060019054906101000a900460ff16611655576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161164c90611dca565b60405180910390fd5b6116656116606115fe565b611329565b565b8280548282559060005260206000209081019282156116e0579160200282015b828111156116df5782518260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555091602001919060010190611687565b5b5090506116ed91906116f1565b5090565b5b8082111561170a5760008160009055506001016116f2565b5090565b600061172161171c84611e73565b611e4e565b9050808382526020820190508285602086028201111561174057600080fd5b60005b85811015611770578161175688826117b8565b845260208401935060208301925050600181019050611743565b5050509392505050565b600061178d61178884611e9f565b611e4e565b9050828152602081018484840111156117a557600080fd5b6117b0848285611f8b565b509392505050565b6000813590506117c781612266565b92915050565b600082601f8301126117de57600080fd5b81356117ee84826020860161170e565b91505092915050565b6000813590506118068161227d565b92915050565b600082601f83011261181d57600080fd5b813561182d84826020860161177a565b91505092915050565b60008135905061184581612294565b92915050565b60008151905061185a81612294565b92915050565b60006020828403121561187257600080fd5b6000611880848285016117b8565b91505092915050565b60006020828403121561189b57600080fd5b60006118a9848285016117f7565b91505092915050565b600080604083850312156118c557600080fd5b60006118d3858286016117f7565b925050602083013567ffffffffffffffff8111156118f057600080fd5b6118fc858286016117cd565b9150509250929050565b6000806040838503121561191957600080fd5b6000611927858286016117f7565b925050602061193885828601611836565b9150509250929050565b60006020828403121561195457600080fd5b600082013567ffffffffffffffff81111561196e57600080fd5b61197a8482850161180c565b91505092915050565b60006020828403121561199557600080fd5b60006119a384828501611836565b91505092915050565b6000602082840312156119be57600080fd5b60006119cc8482850161184b565b91505092915050565b60006119e183836119ed565b60208301905092915050565b6119f681611f1a565b82525050565b611a0581611f1a565b82525050565b6000611a1682611ee0565b611a208185611ef8565b9350611a2b83611ed0565b8060005b83811015611a5c578151611a4388826119d5565b9750611a4e83611eeb565b925050600181019050611a2f565b5085935050505092915050565b611a7281611f2c565b82525050565b611a8181611f38565b82525050565b611a9081611f79565b82525050565b6000611aa3600c83611f09565b9150611aae82612083565b602082019050919050565b6000611ac6602683611f09565b9150611ad1826120ac565b604082019050919050565b6000611ae9601883611f09565b9150611af4826120fb565b602082019050919050565b6000611b0c601283611f09565b9150611b1782612124565b602082019050919050565b6000611b2f600e83611f09565b9150611b3a8261214d565b602082019050919050565b6000611b52602e83611f09565b9150611b5d82612176565b604082019050919050565b6000611b75602083611f09565b9150611b80826121c5565b602082019050919050565b6000611b98602b83611f09565b9150611ba3826121ee565b604082019050919050565b6000611bbb600c83611f09565b9150611bc68261223d565b602082019050919050565b611bda81611f62565b82525050565b6000602082019050611bf560008301846119fc565b92915050565b6000602082019050611c106000830184611a69565b92915050565b6000602082019050611c2b6000830184611a78565b92915050565b6000606082019050611c466000830186611a78565b611c5360208301856119fc565b8181036040830152611c658184611a0b565b9050949350505050565b6000606082019050611c846000830186611a78565b611c9160208301856119fc565b611c9e6040830184611bd1565b949350505050565b6000604082019050611cbb6000830185611a78565b611cc86020830184611bd1565b9392505050565b6000602082019050611ce46000830184611a87565b92915050565b60006020820190508181036000830152611d0381611a96565b9050919050565b60006020820190508181036000830152611d2381611ab9565b9050919050565b60006020820190508181036000830152611d4381611adc565b9050919050565b60006020820190508181036000830152611d6381611aff565b9050919050565b60006020820190508181036000830152611d8381611b22565b9050919050565b60006020820190508181036000830152611da381611b45565b9050919050565b60006020820190508181036000830152611dc381611b68565b9050919050565b60006020820190508181036000830152611de381611b8b565b9050919050565b60006020820190508181036000830152611e0381611bae565b9050919050565b6000602082019050611e1f6000830184611bd1565b92915050565b6000604082019050611e3a6000830185611bd1565b611e4760208301846119fc565b9392505050565b6000611e58611e69565b9050611e648282611f9a565b919050565b6000604051905090565b600067ffffffffffffffff821115611e8e57611e8d612043565b5b602082029050602081019050919050565b600067ffffffffffffffff821115611eba57611eb9612043565b5b611ec382612072565b9050602081019050919050565b6000819050602082019050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b6000611f2582611f42565b9050919050565b60008115159050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b6000611f8482611f6c565b9050919050565b82818337600083830152505050565b611fa382612072565b810181811067ffffffffffffffff82111715611fc257611fc1612043565b5b80604052505050565b6000611fd682611f62565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561200957612008612014565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f5072656669782074616b656e0000000000000000000000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f556e617574686f72697a65643a20546f6b656e20676174650000000000000000600082015250565b7f4f6e6c79206f776e657220757064617465730000000000000000000000000000600082015250565b7f496e76616c696420707265666978000000000000000000000000000000000000600082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f4665652072657175697265640000000000000000000000000000000000000000600082015250565b61226f81611f1a565b811461227a57600080fd5b50565b61228681611f38565b811461229157600080fd5b50565b61229d81611f62565b81146122a857600080fd5b5056fe6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5f2ea2646970667358221220b8cac9a8d8f3de013face3e7fec9a14f0a1e3f3d09fe342a5252c76f07a42da364736f6c63430008040033"; -var isSuperArgs = function (xs) { return xs.length > 1; }; -var DpidRegistry__factory = /** @class */ (function (_super) { - __extends(DpidRegistry__factory, _super); - function DpidRegistry__factory() { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - var _this = this; - if (isSuperArgs(args)) { - _this = _super.apply(this, args) || this; - } - else { - _this = _super.call(this, _abi, _bytecode, args[0]) || this; - } - _this.contractName = "DpidRegistry"; - return _this; - } - DpidRegistry__factory.prototype.deploy = function (overrides) { - return _super.prototype.deploy.call(this, overrides || {}); - }; - DpidRegistry__factory.prototype.getDeployTransaction = function (overrides) { - return _super.prototype.getDeployTransaction.call(this, overrides || {}); - }; - DpidRegistry__factory.prototype.attach = function (address) { - return _super.prototype.attach.call(this, address); - }; - DpidRegistry__factory.prototype.connect = function (signer) { - return _super.prototype.connect.call(this, signer); - }; - DpidRegistry__factory.createInterface = function () { - return new ethers_1.utils.Interface(_abi); - }; - DpidRegistry__factory.connect = function (address, signerOrProvider) { - return new ethers_1.Contract(address, _abi, signerOrProvider); - }; - DpidRegistry__factory.bytecode = _bytecode; - DpidRegistry__factory.abi = _abi; - return DpidRegistry__factory; -}(ethers_1.ContractFactory)); -exports.DpidRegistry__factory = DpidRegistry__factory; diff --git a/desci-contracts/typechain-types/factories/ERC165Upgradeable__factory.js b/desci-contracts/typechain-types/factories/ERC165Upgradeable__factory.js deleted file mode 100644 index 114cb68c..00000000 --- a/desci-contracts/typechain-types/factories/ERC165Upgradeable__factory.js +++ /dev/null @@ -1,54 +0,0 @@ -"use strict"; -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -exports.__esModule = true; -exports.ERC165Upgradeable__factory = void 0; -var ethers_1 = require("ethers"); -var _abi = [ - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "uint8", - name: "version", - type: "uint8" - }, - ], - name: "Initialized", - type: "event" - }, - { - inputs: [ - { - internalType: "bytes4", - name: "interfaceId", - type: "bytes4" - }, - ], - name: "supportsInterface", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, -]; -var ERC165Upgradeable__factory = /** @class */ (function () { - function ERC165Upgradeable__factory() { - } - ERC165Upgradeable__factory.createInterface = function () { - return new ethers_1.utils.Interface(_abi); - }; - ERC165Upgradeable__factory.connect = function (address, signerOrProvider) { - return new ethers_1.Contract(address, _abi, signerOrProvider); - }; - ERC165Upgradeable__factory.abi = _abi; - return ERC165Upgradeable__factory; -}()); -exports.ERC165Upgradeable__factory = ERC165Upgradeable__factory; diff --git a/desci-contracts/typechain-types/factories/ERC165__factory.js b/desci-contracts/typechain-types/factories/ERC165__factory.js deleted file mode 100644 index fcb345c0..00000000 --- a/desci-contracts/typechain-types/factories/ERC165__factory.js +++ /dev/null @@ -1,41 +0,0 @@ -"use strict"; -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -exports.__esModule = true; -exports.ERC165__factory = void 0; -var ethers_1 = require("ethers"); -var _abi = [ - { - inputs: [ - { - internalType: "bytes4", - name: "interfaceId", - type: "bytes4" - }, - ], - name: "supportsInterface", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, -]; -var ERC165__factory = /** @class */ (function () { - function ERC165__factory() { - } - ERC165__factory.createInterface = function () { - return new ethers_1.utils.Interface(_abi); - }; - ERC165__factory.connect = function (address, signerOrProvider) { - return new ethers_1.Contract(address, _abi, signerOrProvider); - }; - ERC165__factory.abi = _abi; - return ERC165__factory; -}()); -exports.ERC165__factory = ERC165__factory; diff --git a/desci-contracts/typechain-types/factories/ERC721Upgradeable__factory.js b/desci-contracts/typechain-types/factories/ERC721Upgradeable__factory.js deleted file mode 100644 index 41edaf33..00000000 --- a/desci-contracts/typechain-types/factories/ERC721Upgradeable__factory.js +++ /dev/null @@ -1,409 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - if (typeof b !== "function" && b !== null) - throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -exports.__esModule = true; -exports.ERC721Upgradeable__factory = void 0; -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -var ethers_1 = require("ethers"); -var _abi = [ - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "owner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "approved", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "Approval", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "owner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "operator", - type: "address" - }, - { - indexed: false, - internalType: "bool", - name: "approved", - type: "bool" - }, - ], - name: "ApprovalForAll", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "uint8", - name: "version", - type: "uint8" - }, - ], - name: "Initialized", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "from", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "to", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "Transfer", - type: "event" - }, - { - inputs: [ - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "approve", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - ], - name: "balanceOf", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "getApproved", - outputs: [ - { - internalType: "address", - name: "", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - { - internalType: "address", - name: "operator", - type: "address" - }, - ], - name: "isApprovedForAll", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [], - name: "name", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "ownerOf", - outputs: [ - { - internalType: "address", - name: "", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "safeTransferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - { - internalType: "bytes", - name: "data", - type: "bytes" - }, - ], - name: "safeTransferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "operator", - type: "address" - }, - { - internalType: "bool", - name: "approved", - type: "bool" - }, - ], - name: "setApprovalForAll", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "bytes4", - name: "interfaceId", - type: "bytes4" - }, - ], - name: "supportsInterface", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [], - name: "symbol", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "tokenURI", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "transferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, -]; -var _bytecode = "0x608060405234801561001057600080fd5b5061216f806100206000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c80636352211e1161008c578063a22cb46511610066578063a22cb46514610224578063b88d4fde14610240578063c87b56dd1461025c578063e985e9c51461028c576100cf565b80636352211e146101a657806370a08231146101d657806395d89b4114610206576100cf565b806301ffc9a7146100d457806306fdde0314610104578063081812fc14610122578063095ea7b31461015257806323b872dd1461016e57806342842e0e1461018a575b600080fd5b6100ee60048036038101906100e99190611625565b6102bc565b6040516100fb9190611936565b60405180910390f35b61010c61039e565b6040516101199190611951565b60405180910390f35b61013c60048036038101906101379190611677565b610430565b60405161014991906118cf565b60405180910390f35b61016c600480360381019061016791906115e9565b610476565b005b610188600480360381019061018391906114e3565b61058e565b005b6101a4600480360381019061019f91906114e3565b6105ee565b005b6101c060048036038101906101bb9190611677565b61060e565b6040516101cd91906118cf565b60405180910390f35b6101f060048036038101906101eb919061147e565b6106c0565b6040516101fd9190611a93565b60405180910390f35b61020e610778565b60405161021b9190611951565b60405180910390f35b61023e600480360381019061023991906115ad565b61080a565b005b61025a60048036038101906102559190611532565b610820565b005b61027660048036038101906102719190611677565b610882565b6040516102839190611951565b60405180910390f35b6102a660048036038101906102a191906114a7565b6108ea565b6040516102b39190611936565b60405180910390f35b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061038757507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061039757506103968261097e565b5b9050919050565b6060606580546103ad90611cb8565b80601f01602080910402602001604051908101604052809291908181526020018280546103d990611cb8565b80156104265780601f106103fb57610100808354040283529160200191610426565b820191906000526020600020905b81548152906001019060200180831161040957829003601f168201915b5050505050905090565b600061043b826109e8565b6069600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006104818261060e565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156104f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104e990611a53565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610511610a33565b73ffffffffffffffffffffffffffffffffffffffff161480610540575061053f8161053a610a33565b6108ea565b5b61057f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057690611a13565b60405180910390fd5b6105898383610a3b565b505050565b61059f610599610a33565b82610af4565b6105de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105d590611a73565b60405180910390fd5b6105e9838383610b89565b505050565b61060983838360405180602001604052806000815250610820565b505050565b6000806067600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156106b7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106ae90611a33565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610731576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610728906119f3565b60405180910390fd5b606860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60606066805461078790611cb8565b80601f01602080910402602001604051908101604052809291908181526020018280546107b390611cb8565b80156108005780601f106107d557610100808354040283529160200191610800565b820191906000526020600020905b8154815290600101906020018083116107e357829003601f168201915b5050505050905090565b61081c610815610a33565b8383610df0565b5050565b61083161082b610a33565b83610af4565b610870576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161086790611a73565b60405180910390fd5b61087c84848484610f5d565b50505050565b606061088d826109e8565b6000610897610fb9565b905060008151116108b757604051806020016040528060008152506108e2565b806108c184610fd0565b6040516020016108d29291906118ab565b6040516020818303038152906040525b915050919050565b6000606a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6109f18161117d565b610a30576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a2790611a33565b60405180910390fd5b50565b600033905090565b816069600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16610aae8361060e565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610b008361060e565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480610b425750610b4181856108ea565b5b80610b8057508373ffffffffffffffffffffffffffffffffffffffff16610b6884610430565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16610ba98261060e565b73ffffffffffffffffffffffffffffffffffffffff1614610bff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bf690611993565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610c6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c66906119b3565b60405180910390fd5b610c7a8383836111e9565b610c85600082610a3b565b6001606860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610cd59190611bce565b925050819055506001606860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610d2c9190611b47565b92505081905550816067600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610deb8383836111ee565b505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610e5f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e56906119d3565b60405180910390fd5b80606a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610f509190611936565b60405180910390a3505050565b610f68848484610b89565b610f74848484846111f3565b610fb3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610faa90611973565b60405180910390fd5b50505050565b606060405180602001604052806000815250905090565b60606000821415611018576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050611178565b600082905060005b6000821461104a57808061103390611d1b565b915050600a826110439190611b9d565b9150611020565b60008167ffffffffffffffff81111561108c577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156110be5781602001600182028036833780820191505090505b5090505b60008514611171576001826110d79190611bce565b9150600a856110e69190611d64565b60306110f29190611b47565b60f81b81838151811061112e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8561116a9190611b9d565b94506110c2565b8093505050505b919050565b60008073ffffffffffffffffffffffffffffffffffffffff166067600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b505050565b505050565b60006112148473ffffffffffffffffffffffffffffffffffffffff1661138a565b1561137d578373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261123d610a33565b8786866040518563ffffffff1660e01b815260040161125f94939291906118ea565b602060405180830381600087803b15801561127957600080fd5b505af19250505080156112aa57506040513d601f19601f820116820180604052508101906112a7919061164e565b60015b61132d573d80600081146112da576040519150601f19603f3d011682016040523d82523d6000602084013e6112df565b606091505b50600081511415611325576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161131c90611973565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050611382565b600190505b949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60006113c06113bb84611ad3565b611aae565b9050828152602081018484840111156113d857600080fd5b6113e3848285611c76565b509392505050565b6000813590506113fa816120dd565b92915050565b60008135905061140f816120f4565b92915050565b6000813590506114248161210b565b92915050565b6000815190506114398161210b565b92915050565b600082601f83011261145057600080fd5b81356114608482602086016113ad565b91505092915050565b60008135905061147881612122565b92915050565b60006020828403121561149057600080fd5b600061149e848285016113eb565b91505092915050565b600080604083850312156114ba57600080fd5b60006114c8858286016113eb565b92505060206114d9858286016113eb565b9150509250929050565b6000806000606084860312156114f857600080fd5b6000611506868287016113eb565b9350506020611517868287016113eb565b925050604061152886828701611469565b9150509250925092565b6000806000806080858703121561154857600080fd5b6000611556878288016113eb565b9450506020611567878288016113eb565b935050604061157887828801611469565b925050606085013567ffffffffffffffff81111561159557600080fd5b6115a18782880161143f565b91505092959194509250565b600080604083850312156115c057600080fd5b60006115ce858286016113eb565b92505060206115df85828601611400565b9150509250929050565b600080604083850312156115fc57600080fd5b600061160a858286016113eb565b925050602061161b85828601611469565b9150509250929050565b60006020828403121561163757600080fd5b600061164584828501611415565b91505092915050565b60006020828403121561166057600080fd5b600061166e8482850161142a565b91505092915050565b60006020828403121561168957600080fd5b600061169784828501611469565b91505092915050565b6116a981611c02565b82525050565b6116b881611c14565b82525050565b60006116c982611b04565b6116d38185611b1a565b93506116e3818560208601611c85565b6116ec81611e51565b840191505092915050565b600061170282611b0f565b61170c8185611b2b565b935061171c818560208601611c85565b61172581611e51565b840191505092915050565b600061173b82611b0f565b6117458185611b3c565b9350611755818560208601611c85565b80840191505092915050565b600061176e603283611b2b565b915061177982611e62565b604082019050919050565b6000611791602583611b2b565b915061179c82611eb1565b604082019050919050565b60006117b4602483611b2b565b91506117bf82611f00565b604082019050919050565b60006117d7601983611b2b565b91506117e282611f4f565b602082019050919050565b60006117fa602983611b2b565b915061180582611f78565b604082019050919050565b600061181d603e83611b2b565b915061182882611fc7565b604082019050919050565b6000611840601883611b2b565b915061184b82612016565b602082019050919050565b6000611863602183611b2b565b915061186e8261203f565b604082019050919050565b6000611886602e83611b2b565b91506118918261208e565b604082019050919050565b6118a581611c6c565b82525050565b60006118b78285611730565b91506118c38284611730565b91508190509392505050565b60006020820190506118e460008301846116a0565b92915050565b60006080820190506118ff60008301876116a0565b61190c60208301866116a0565b611919604083018561189c565b818103606083015261192b81846116be565b905095945050505050565b600060208201905061194b60008301846116af565b92915050565b6000602082019050818103600083015261196b81846116f7565b905092915050565b6000602082019050818103600083015261198c81611761565b9050919050565b600060208201905081810360008301526119ac81611784565b9050919050565b600060208201905081810360008301526119cc816117a7565b9050919050565b600060208201905081810360008301526119ec816117ca565b9050919050565b60006020820190508181036000830152611a0c816117ed565b9050919050565b60006020820190508181036000830152611a2c81611810565b9050919050565b60006020820190508181036000830152611a4c81611833565b9050919050565b60006020820190508181036000830152611a6c81611856565b9050919050565b60006020820190508181036000830152611a8c81611879565b9050919050565b6000602082019050611aa8600083018461189c565b92915050565b6000611ab8611ac9565b9050611ac48282611cea565b919050565b6000604051905090565b600067ffffffffffffffff821115611aee57611aed611e22565b5b611af782611e51565b9050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6000611b5282611c6c565b9150611b5d83611c6c565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115611b9257611b91611d95565b5b828201905092915050565b6000611ba882611c6c565b9150611bb383611c6c565b925082611bc357611bc2611dc4565b5b828204905092915050565b6000611bd982611c6c565b9150611be483611c6c565b925082821015611bf757611bf6611d95565b5b828203905092915050565b6000611c0d82611c4c565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015611ca3578082015181840152602081019050611c88565b83811115611cb2576000848401525b50505050565b60006002820490506001821680611cd057607f821691505b60208210811415611ce457611ce3611df3565b5b50919050565b611cf382611e51565b810181811067ffffffffffffffff82111715611d1257611d11611e22565b5b80604052505050565b6000611d2682611c6c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415611d5957611d58611d95565b5b600182019050919050565b6000611d6f82611c6c565b9150611d7a83611c6c565b925082611d8a57611d89611dc4565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b6120e681611c02565b81146120f157600080fd5b50565b6120fd81611c14565b811461210857600080fd5b50565b61211481611c20565b811461211f57600080fd5b50565b61212b81611c6c565b811461213657600080fd5b5056fea264697066735822122033c0e2c374b1f5e89ce566a3837920ba4aa13f7ad9687f77ce9ba6a56535776064736f6c63430008040033"; -var isSuperArgs = function (xs) { return xs.length > 1; }; -var ERC721Upgradeable__factory = /** @class */ (function (_super) { - __extends(ERC721Upgradeable__factory, _super); - function ERC721Upgradeable__factory() { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - var _this = this; - if (isSuperArgs(args)) { - _this = _super.apply(this, args) || this; - } - else { - _this = _super.call(this, _abi, _bytecode, args[0]) || this; - } - _this.contractName = "ERC721Upgradeable"; - return _this; - } - ERC721Upgradeable__factory.prototype.deploy = function (overrides) { - return _super.prototype.deploy.call(this, overrides || {}); - }; - ERC721Upgradeable__factory.prototype.getDeployTransaction = function (overrides) { - return _super.prototype.getDeployTransaction.call(this, overrides || {}); - }; - ERC721Upgradeable__factory.prototype.attach = function (address) { - return _super.prototype.attach.call(this, address); - }; - ERC721Upgradeable__factory.prototype.connect = function (signer) { - return _super.prototype.connect.call(this, signer); - }; - ERC721Upgradeable__factory.createInterface = function () { - return new ethers_1.utils.Interface(_abi); - }; - ERC721Upgradeable__factory.connect = function (address, signerOrProvider) { - return new ethers_1.Contract(address, _abi, signerOrProvider); - }; - ERC721Upgradeable__factory.bytecode = _bytecode; - ERC721Upgradeable__factory.abi = _abi; - return ERC721Upgradeable__factory; -}(ethers_1.ContractFactory)); -exports.ERC721Upgradeable__factory = ERC721Upgradeable__factory; diff --git a/desci-contracts/typechain-types/factories/ERC721__factory.js b/desci-contracts/typechain-types/factories/ERC721__factory.js deleted file mode 100644 index 0f23c0c0..00000000 --- a/desci-contracts/typechain-types/factories/ERC721__factory.js +++ /dev/null @@ -1,412 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - if (typeof b !== "function" && b !== null) - throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -exports.__esModule = true; -exports.ERC721__factory = void 0; -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -var ethers_1 = require("ethers"); -var _abi = [ - { - inputs: [ - { - internalType: "string", - name: "name_", - type: "string" - }, - { - internalType: "string", - name: "symbol_", - type: "string" - }, - ], - stateMutability: "nonpayable", - type: "constructor" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "owner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "approved", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "Approval", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "owner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "operator", - type: "address" - }, - { - indexed: false, - internalType: "bool", - name: "approved", - type: "bool" - }, - ], - name: "ApprovalForAll", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "from", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "to", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "Transfer", - type: "event" - }, - { - inputs: [ - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "approve", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - ], - name: "balanceOf", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "getApproved", - outputs: [ - { - internalType: "address", - name: "", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - { - internalType: "address", - name: "operator", - type: "address" - }, - ], - name: "isApprovedForAll", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [], - name: "name", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "ownerOf", - outputs: [ - { - internalType: "address", - name: "", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "safeTransferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - { - internalType: "bytes", - name: "data", - type: "bytes" - }, - ], - name: "safeTransferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "operator", - type: "address" - }, - { - internalType: "bool", - name: "approved", - type: "bool" - }, - ], - name: "setApprovalForAll", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "bytes4", - name: "interfaceId", - type: "bytes4" - }, - ], - name: "supportsInterface", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [], - name: "symbol", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "tokenURI", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "transferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, -]; -var _bytecode = "0x60806040523480156200001157600080fd5b506040516200276538038062002765833981810160405281019062000037919062000193565b81600090805190602001906200004f92919062000071565b5080600190805190602001906200006892919062000071565b50505062000376565b8280546200007f906200029b565b90600052602060002090601f016020900481019282620000a35760008555620000ef565b82601f10620000be57805160ff1916838001178555620000ef565b82800160010185558215620000ef579182015b82811115620000ee578251825591602001919060010190620000d1565b5b509050620000fe919062000102565b5090565b5b808211156200011d57600081600090555060010162000103565b5090565b60006200013862000132846200022f565b62000206565b9050828152602081018484840111156200015157600080fd5b6200015e84828562000265565b509392505050565b600082601f8301126200017857600080fd5b81516200018a84826020860162000121565b91505092915050565b60008060408385031215620001a757600080fd5b600083015167ffffffffffffffff811115620001c257600080fd5b620001d08582860162000166565b925050602083015167ffffffffffffffff811115620001ee57600080fd5b620001fc8582860162000166565b9150509250929050565b60006200021262000225565b9050620002208282620002d1565b919050565b6000604051905090565b600067ffffffffffffffff8211156200024d576200024c62000336565b5b620002588262000365565b9050602081019050919050565b60005b838110156200028557808201518184015260208101905062000268565b8381111562000295576000848401525b50505050565b60006002820490506001821680620002b457607f821691505b60208210811415620002cb57620002ca62000307565b5b50919050565b620002dc8262000365565b810181811067ffffffffffffffff82111715620002fe57620002fd62000336565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b6123df80620003866000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c80636352211e1161008c578063a22cb46511610066578063a22cb46514610224578063b88d4fde14610240578063c87b56dd1461025c578063e985e9c51461028c576100cf565b80636352211e146101a657806370a08231146101d657806395d89b4114610206576100cf565b806301ffc9a7146100d457806306fdde0314610104578063081812fc14610122578063095ea7b31461015257806323b872dd1461016e57806342842e0e1461018a575b600080fd5b6100ee60048036038101906100e9919061196f565b6102bc565b6040516100fb9190611c80565b60405180910390f35b61010c61039e565b6040516101199190611c9b565b60405180910390f35b61013c600480360381019061013791906119c1565b610430565b6040516101499190611c19565b60405180910390f35b61016c60048036038101906101679190611933565b610476565b005b6101886004803603810190610183919061182d565b61058e565b005b6101a4600480360381019061019f919061182d565b6105ee565b005b6101c060048036038101906101bb91906119c1565b61060e565b6040516101cd9190611c19565b60405180910390f35b6101f060048036038101906101eb91906117c8565b610695565b6040516101fd9190611ddd565b60405180910390f35b61020e61074d565b60405161021b9190611c9b565b60405180910390f35b61023e600480360381019061023991906118f7565b6107df565b005b61025a6004803603810190610255919061187c565b6107f5565b005b610276600480360381019061027191906119c1565b610857565b6040516102839190611c9b565b60405180910390f35b6102a660048036038101906102a191906117f1565b6108bf565b6040516102b39190611c80565b60405180910390f35b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061038757507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610397575061039682610953565b5b9050919050565b6060600080546103ad90611fd1565b80601f01602080910402602001604051908101604052809291908181526020018280546103d990611fd1565b80156104265780601f106103fb57610100808354040283529160200191610426565b820191906000526020600020905b81548152906001019060200180831161040957829003601f168201915b5050505050905090565b600061043b826109bd565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006104818261060e565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156104f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104e990611d9d565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610511610a08565b73ffffffffffffffffffffffffffffffffffffffff161480610540575061053f8161053a610a08565b6108bf565b5b61057f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057690611dbd565b60405180910390fd5b6105898383610a10565b505050565b61059f610599610a08565b82610ac9565b6105de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105d590611cbd565b60405180910390fd5b6105e9838383610b5e565b505050565b610609838383604051806020016040528060008152506107f5565b505050565b60008061061a83610e58565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561068c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161068390611d7d565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610706576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106fd90611d5d565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60606001805461075c90611fd1565b80601f016020809104026020016040519081016040528092919081815260200182805461078890611fd1565b80156107d55780601f106107aa576101008083540402835291602001916107d5565b820191906000526020600020905b8154815290600101906020018083116107b857829003601f168201915b5050505050905090565b6107f16107ea610a08565b8383610e95565b5050565b610806610800610a08565b83610ac9565b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161083c90611cbd565b60405180910390fd5b61085184848484611002565b50505050565b6060610862826109bd565b600061086c61105e565b9050600081511161088c57604051806020016040528060008152506108b7565b8061089684611075565b6040516020016108a7929190611bf5565b6040516020818303038152906040525b915050919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6109c681611199565b610a05576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109fc90611d7d565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16610a838361060e565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610ad58361060e565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480610b175750610b1681856108bf565b5b80610b5557508373ffffffffffffffffffffffffffffffffffffffff16610b3d84610430565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16610b7e8261060e565b73ffffffffffffffffffffffffffffffffffffffff1614610bd4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bcb90611cfd565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610c44576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3b90611d1d565b60405180910390fd5b610c5183838360016111da565b8273ffffffffffffffffffffffffffffffffffffffff16610c718261060e565b73ffffffffffffffffffffffffffffffffffffffff1614610cc7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cbe90611cfd565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610e538383836001611300565b505050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610f04576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610efb90611d3d565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610ff59190611c80565b60405180910390a3505050565b61100d848484610b5e565b61101984848484611306565b611058576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161104f90611cdd565b60405180910390fd5b50505050565b606060405180602001604052806000815250905090565b6060600060016110848461149d565b01905060008167ffffffffffffffff8111156110c9577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156110fb5781602001600182028036833780820191505090505b509050600082602001820190505b60011561118e578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611178577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b04945060008514156111895761118e565b611109565b819350505050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166111bb83610e58565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b60018111156112fa57600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461126e5780600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546112669190611ee7565b925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146112f95780600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546112f19190611e91565b925050819055505b5b50505050565b50505050565b60006113278473ffffffffffffffffffffffffffffffffffffffff166116d4565b15611490578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611350610a08565b8786866040518563ffffffff1660e01b81526004016113729493929190611c34565b602060405180830381600087803b15801561138c57600080fd5b505af19250505080156113bd57506040513d601f19601f820116820180604052508101906113ba9190611998565b60015b611440573d80600081146113ed576040519150601f19603f3d011682016040523d82523d6000602084013e6113f2565b606091505b50600081511415611438576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161142f90611cdd565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050611495565b600190505b949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310611521577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381611517577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611584576d04ee2d6d415b85acef8100000000838161157a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b0492506020810190505b662386f26fc1000083106115d957662386f26fc1000083816115cf577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b0492506010810190505b6305f5e1008310611628576305f5e100838161161e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b0492506008810190505b6127108310611673576127108381611669577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b0492506004810190505b606483106116bc57606483816116b2577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b0492506002810190505b600a83106116cb576001810190505b80915050919050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600061170a61170584611e1d565b611df8565b90508281526020810184848401111561172257600080fd5b61172d848285611f8f565b509392505050565b6000813590506117448161234d565b92915050565b60008135905061175981612364565b92915050565b60008135905061176e8161237b565b92915050565b6000815190506117838161237b565b92915050565b600082601f83011261179a57600080fd5b81356117aa8482602086016116f7565b91505092915050565b6000813590506117c281612392565b92915050565b6000602082840312156117da57600080fd5b60006117e884828501611735565b91505092915050565b6000806040838503121561180457600080fd5b600061181285828601611735565b925050602061182385828601611735565b9150509250929050565b60008060006060848603121561184257600080fd5b600061185086828701611735565b935050602061186186828701611735565b9250506040611872868287016117b3565b9150509250925092565b6000806000806080858703121561189257600080fd5b60006118a087828801611735565b94505060206118b187828801611735565b93505060406118c2878288016117b3565b925050606085013567ffffffffffffffff8111156118df57600080fd5b6118eb87828801611789565b91505092959194509250565b6000806040838503121561190a57600080fd5b600061191885828601611735565b92505060206119298582860161174a565b9150509250929050565b6000806040838503121561194657600080fd5b600061195485828601611735565b9250506020611965858286016117b3565b9150509250929050565b60006020828403121561198157600080fd5b600061198f8482850161175f565b91505092915050565b6000602082840312156119aa57600080fd5b60006119b884828501611774565b91505092915050565b6000602082840312156119d357600080fd5b60006119e1848285016117b3565b91505092915050565b6119f381611f1b565b82525050565b611a0281611f2d565b82525050565b6000611a1382611e4e565b611a1d8185611e64565b9350611a2d818560208601611f9e565b611a36816120c1565b840191505092915050565b6000611a4c82611e59565b611a568185611e75565b9350611a66818560208601611f9e565b611a6f816120c1565b840191505092915050565b6000611a8582611e59565b611a8f8185611e86565b9350611a9f818560208601611f9e565b80840191505092915050565b6000611ab8602d83611e75565b9150611ac3826120d2565b604082019050919050565b6000611adb603283611e75565b9150611ae682612121565b604082019050919050565b6000611afe602583611e75565b9150611b0982612170565b604082019050919050565b6000611b21602483611e75565b9150611b2c826121bf565b604082019050919050565b6000611b44601983611e75565b9150611b4f8261220e565b602082019050919050565b6000611b67602983611e75565b9150611b7282612237565b604082019050919050565b6000611b8a601883611e75565b9150611b9582612286565b602082019050919050565b6000611bad602183611e75565b9150611bb8826122af565b604082019050919050565b6000611bd0603d83611e75565b9150611bdb826122fe565b604082019050919050565b611bef81611f85565b82525050565b6000611c018285611a7a565b9150611c0d8284611a7a565b91508190509392505050565b6000602082019050611c2e60008301846119ea565b92915050565b6000608082019050611c4960008301876119ea565b611c5660208301866119ea565b611c636040830185611be6565b8181036060830152611c758184611a08565b905095945050505050565b6000602082019050611c9560008301846119f9565b92915050565b60006020820190508181036000830152611cb58184611a41565b905092915050565b60006020820190508181036000830152611cd681611aab565b9050919050565b60006020820190508181036000830152611cf681611ace565b9050919050565b60006020820190508181036000830152611d1681611af1565b9050919050565b60006020820190508181036000830152611d3681611b14565b9050919050565b60006020820190508181036000830152611d5681611b37565b9050919050565b60006020820190508181036000830152611d7681611b5a565b9050919050565b60006020820190508181036000830152611d9681611b7d565b9050919050565b60006020820190508181036000830152611db681611ba0565b9050919050565b60006020820190508181036000830152611dd681611bc3565b9050919050565b6000602082019050611df26000830184611be6565b92915050565b6000611e02611e13565b9050611e0e8282612003565b919050565b6000604051905090565b600067ffffffffffffffff821115611e3857611e37612092565b5b611e41826120c1565b9050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6000611e9c82611f85565b9150611ea783611f85565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115611edc57611edb612034565b5b828201905092915050565b6000611ef282611f85565b9150611efd83611f85565b925082821015611f1057611f0f612034565b5b828203905092915050565b6000611f2682611f65565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015611fbc578082015181840152602081019050611fa1565b83811115611fcb576000848401525b50505050565b60006002820490506001821680611fe957607f821691505b60208210811415611ffd57611ffc612063565b5b50919050565b61200c826120c1565b810181811067ffffffffffffffff8211171561202b5761202a612092565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b61235681611f1b565b811461236157600080fd5b50565b61236d81611f2d565b811461237857600080fd5b50565b61238481611f39565b811461238f57600080fd5b50565b61239b81611f85565b81146123a657600080fd5b5056fea2646970667358221220655f8874a44849536c27d3d91af607a2536bac828e59188fefce18ad471c90b164736f6c63430008040033"; -var isSuperArgs = function (xs) { return xs.length > 1; }; -var ERC721__factory = /** @class */ (function (_super) { - __extends(ERC721__factory, _super); - function ERC721__factory() { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - var _this = this; - if (isSuperArgs(args)) { - _this = _super.apply(this, args) || this; - } - else { - _this = _super.call(this, _abi, _bytecode, args[0]) || this; - } - _this.contractName = "ERC721"; - return _this; - } - ERC721__factory.prototype.deploy = function (name_, symbol_, overrides) { - return _super.prototype.deploy.call(this, name_, symbol_, overrides || {}); - }; - ERC721__factory.prototype.getDeployTransaction = function (name_, symbol_, overrides) { - return _super.prototype.getDeployTransaction.call(this, name_, symbol_, overrides || {}); - }; - ERC721__factory.prototype.attach = function (address) { - return _super.prototype.attach.call(this, address); - }; - ERC721__factory.prototype.connect = function (signer) { - return _super.prototype.connect.call(this, signer); - }; - ERC721__factory.createInterface = function () { - return new ethers_1.utils.Interface(_abi); - }; - ERC721__factory.connect = function (address, signerOrProvider) { - return new ethers_1.Contract(address, _abi, signerOrProvider); - }; - ERC721__factory.bytecode = _bytecode; - ERC721__factory.abi = _abi; - return ERC721__factory; -}(ethers_1.ContractFactory)); -exports.ERC721__factory = ERC721__factory; diff --git a/desci-contracts/typechain-types/factories/IDpidRegistry__factory.js b/desci-contracts/typechain-types/factories/IDpidRegistry__factory.js deleted file mode 100644 index bdedaa14..00000000 --- a/desci-contracts/typechain-types/factories/IDpidRegistry__factory.js +++ /dev/null @@ -1,94 +0,0 @@ -"use strict"; -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -exports.__esModule = true; -exports.IDpidRegistry__factory = void 0; -var ethers_1 = require("ethers"); -var _abi = [ - { - inputs: [ - { - internalType: "bytes32", - name: "prefix", - type: "bytes32" - }, - { - internalType: "uint256", - name: "entryId", - type: "uint256" - }, - ], - name: "get", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "bytes32", - name: "prefix", - type: "bytes32" - }, - ], - name: "getOrganization", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256" - }, - { - internalType: "address", - name: "", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "bytes32", - name: "prefix", - type: "bytes32" - }, - { - internalType: "uint256", - name: "entry", - type: "uint256" - }, - ], - name: "put", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256" - }, - ], - stateMutability: "payable", - type: "function" - }, -]; -var IDpidRegistry__factory = /** @class */ (function () { - function IDpidRegistry__factory() { - } - IDpidRegistry__factory.createInterface = function () { - return new ethers_1.utils.Interface(_abi); - }; - IDpidRegistry__factory.connect = function (address, signerOrProvider) { - return new ethers_1.Contract(address, _abi, signerOrProvider); - }; - IDpidRegistry__factory.abi = _abi; - return IDpidRegistry__factory; -}()); -exports.IDpidRegistry__factory = IDpidRegistry__factory; diff --git a/desci-contracts/typechain-types/factories/IERC165Upgradeable__factory.js b/desci-contracts/typechain-types/factories/IERC165Upgradeable__factory.js deleted file mode 100644 index 623a8e0f..00000000 --- a/desci-contracts/typechain-types/factories/IERC165Upgradeable__factory.js +++ /dev/null @@ -1,41 +0,0 @@ -"use strict"; -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -exports.__esModule = true; -exports.IERC165Upgradeable__factory = void 0; -var ethers_1 = require("ethers"); -var _abi = [ - { - inputs: [ - { - internalType: "bytes4", - name: "interfaceId", - type: "bytes4" - }, - ], - name: "supportsInterface", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, -]; -var IERC165Upgradeable__factory = /** @class */ (function () { - function IERC165Upgradeable__factory() { - } - IERC165Upgradeable__factory.createInterface = function () { - return new ethers_1.utils.Interface(_abi); - }; - IERC165Upgradeable__factory.connect = function (address, signerOrProvider) { - return new ethers_1.Contract(address, _abi, signerOrProvider); - }; - IERC165Upgradeable__factory.abi = _abi; - return IERC165Upgradeable__factory; -}()); -exports.IERC165Upgradeable__factory = IERC165Upgradeable__factory; diff --git a/desci-contracts/typechain-types/factories/IERC165__factory.js b/desci-contracts/typechain-types/factories/IERC165__factory.js deleted file mode 100644 index 2957cbad..00000000 --- a/desci-contracts/typechain-types/factories/IERC165__factory.js +++ /dev/null @@ -1,41 +0,0 @@ -"use strict"; -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -exports.__esModule = true; -exports.IERC165__factory = void 0; -var ethers_1 = require("ethers"); -var _abi = [ - { - inputs: [ - { - internalType: "bytes4", - name: "interfaceId", - type: "bytes4" - }, - ], - name: "supportsInterface", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, -]; -var IERC165__factory = /** @class */ (function () { - function IERC165__factory() { - } - IERC165__factory.createInterface = function () { - return new ethers_1.utils.Interface(_abi); - }; - IERC165__factory.connect = function (address, signerOrProvider) { - return new ethers_1.Contract(address, _abi, signerOrProvider); - }; - IERC165__factory.abi = _abi; - return IERC165__factory; -}()); -exports.IERC165__factory = IERC165__factory; diff --git a/desci-contracts/typechain-types/factories/IERC721MetadataUpgradeable__factory.js b/desci-contracts/typechain-types/factories/IERC721MetadataUpgradeable__factory.js deleted file mode 100644 index 9f0fbe49..00000000 --- a/desci-contracts/typechain-types/factories/IERC721MetadataUpgradeable__factory.js +++ /dev/null @@ -1,352 +0,0 @@ -"use strict"; -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -exports.__esModule = true; -exports.IERC721MetadataUpgradeable__factory = void 0; -var ethers_1 = require("ethers"); -var _abi = [ - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "owner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "approved", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "Approval", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "owner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "operator", - type: "address" - }, - { - indexed: false, - internalType: "bool", - name: "approved", - type: "bool" - }, - ], - name: "ApprovalForAll", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "from", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "to", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "Transfer", - type: "event" - }, - { - inputs: [ - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "approve", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - ], - name: "balanceOf", - outputs: [ - { - internalType: "uint256", - name: "balance", - type: "uint256" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "getApproved", - outputs: [ - { - internalType: "address", - name: "operator", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - { - internalType: "address", - name: "operator", - type: "address" - }, - ], - name: "isApprovedForAll", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [], - name: "name", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "ownerOf", - outputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "safeTransferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - { - internalType: "bytes", - name: "data", - type: "bytes" - }, - ], - name: "safeTransferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "operator", - type: "address" - }, - { - internalType: "bool", - name: "_approved", - type: "bool" - }, - ], - name: "setApprovalForAll", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "bytes4", - name: "interfaceId", - type: "bytes4" - }, - ], - name: "supportsInterface", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [], - name: "symbol", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "tokenURI", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "transferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, -]; -var IERC721MetadataUpgradeable__factory = /** @class */ (function () { - function IERC721MetadataUpgradeable__factory() { - } - IERC721MetadataUpgradeable__factory.createInterface = function () { - return new ethers_1.utils.Interface(_abi); - }; - IERC721MetadataUpgradeable__factory.connect = function (address, signerOrProvider) { - return new ethers_1.Contract(address, _abi, signerOrProvider); - }; - IERC721MetadataUpgradeable__factory.abi = _abi; - return IERC721MetadataUpgradeable__factory; -}()); -exports.IERC721MetadataUpgradeable__factory = IERC721MetadataUpgradeable__factory; diff --git a/desci-contracts/typechain-types/factories/IERC721Metadata__factory.js b/desci-contracts/typechain-types/factories/IERC721Metadata__factory.js deleted file mode 100644 index fdebc69b..00000000 --- a/desci-contracts/typechain-types/factories/IERC721Metadata__factory.js +++ /dev/null @@ -1,352 +0,0 @@ -"use strict"; -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -exports.__esModule = true; -exports.IERC721Metadata__factory = void 0; -var ethers_1 = require("ethers"); -var _abi = [ - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "owner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "approved", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "Approval", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "owner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "operator", - type: "address" - }, - { - indexed: false, - internalType: "bool", - name: "approved", - type: "bool" - }, - ], - name: "ApprovalForAll", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "from", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "to", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "Transfer", - type: "event" - }, - { - inputs: [ - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "approve", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - ], - name: "balanceOf", - outputs: [ - { - internalType: "uint256", - name: "balance", - type: "uint256" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "getApproved", - outputs: [ - { - internalType: "address", - name: "operator", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - { - internalType: "address", - name: "operator", - type: "address" - }, - ], - name: "isApprovedForAll", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [], - name: "name", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "ownerOf", - outputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "safeTransferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - { - internalType: "bytes", - name: "data", - type: "bytes" - }, - ], - name: "safeTransferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "operator", - type: "address" - }, - { - internalType: "bool", - name: "_approved", - type: "bool" - }, - ], - name: "setApprovalForAll", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "bytes4", - name: "interfaceId", - type: "bytes4" - }, - ], - name: "supportsInterface", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [], - name: "symbol", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "tokenURI", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "transferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, -]; -var IERC721Metadata__factory = /** @class */ (function () { - function IERC721Metadata__factory() { - } - IERC721Metadata__factory.createInterface = function () { - return new ethers_1.utils.Interface(_abi); - }; - IERC721Metadata__factory.connect = function (address, signerOrProvider) { - return new ethers_1.Contract(address, _abi, signerOrProvider); - }; - IERC721Metadata__factory.abi = _abi; - return IERC721Metadata__factory; -}()); -exports.IERC721Metadata__factory = IERC721Metadata__factory; diff --git a/desci-contracts/typechain-types/factories/IERC721ReceiverUpgradeable__factory.js b/desci-contracts/typechain-types/factories/IERC721ReceiverUpgradeable__factory.js deleted file mode 100644 index 6dcbf9b1..00000000 --- a/desci-contracts/typechain-types/factories/IERC721ReceiverUpgradeable__factory.js +++ /dev/null @@ -1,56 +0,0 @@ -"use strict"; -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -exports.__esModule = true; -exports.IERC721ReceiverUpgradeable__factory = void 0; -var ethers_1 = require("ethers"); -var _abi = [ - { - inputs: [ - { - internalType: "address", - name: "operator", - type: "address" - }, - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - { - internalType: "bytes", - name: "data", - type: "bytes" - }, - ], - name: "onERC721Received", - outputs: [ - { - internalType: "bytes4", - name: "", - type: "bytes4" - }, - ], - stateMutability: "nonpayable", - type: "function" - }, -]; -var IERC721ReceiverUpgradeable__factory = /** @class */ (function () { - function IERC721ReceiverUpgradeable__factory() { - } - IERC721ReceiverUpgradeable__factory.createInterface = function () { - return new ethers_1.utils.Interface(_abi); - }; - IERC721ReceiverUpgradeable__factory.connect = function (address, signerOrProvider) { - return new ethers_1.Contract(address, _abi, signerOrProvider); - }; - IERC721ReceiverUpgradeable__factory.abi = _abi; - return IERC721ReceiverUpgradeable__factory; -}()); -exports.IERC721ReceiverUpgradeable__factory = IERC721ReceiverUpgradeable__factory; diff --git a/desci-contracts/typechain-types/factories/IERC721Receiver__factory.js b/desci-contracts/typechain-types/factories/IERC721Receiver__factory.js deleted file mode 100644 index f6208cee..00000000 --- a/desci-contracts/typechain-types/factories/IERC721Receiver__factory.js +++ /dev/null @@ -1,56 +0,0 @@ -"use strict"; -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -exports.__esModule = true; -exports.IERC721Receiver__factory = void 0; -var ethers_1 = require("ethers"); -var _abi = [ - { - inputs: [ - { - internalType: "address", - name: "operator", - type: "address" - }, - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - { - internalType: "bytes", - name: "data", - type: "bytes" - }, - ], - name: "onERC721Received", - outputs: [ - { - internalType: "bytes4", - name: "", - type: "bytes4" - }, - ], - stateMutability: "nonpayable", - type: "function" - }, -]; -var IERC721Receiver__factory = /** @class */ (function () { - function IERC721Receiver__factory() { - } - IERC721Receiver__factory.createInterface = function () { - return new ethers_1.utils.Interface(_abi); - }; - IERC721Receiver__factory.connect = function (address, signerOrProvider) { - return new ethers_1.Contract(address, _abi, signerOrProvider); - }; - IERC721Receiver__factory.abi = _abi; - return IERC721Receiver__factory; -}()); -exports.IERC721Receiver__factory = IERC721Receiver__factory; diff --git a/desci-contracts/typechain-types/factories/IERC721Upgradeable__factory.js b/desci-contracts/typechain-types/factories/IERC721Upgradeable__factory.js deleted file mode 100644 index 2f144bf7..00000000 --- a/desci-contracts/typechain-types/factories/IERC721Upgradeable__factory.js +++ /dev/null @@ -1,307 +0,0 @@ -"use strict"; -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -exports.__esModule = true; -exports.IERC721Upgradeable__factory = void 0; -var ethers_1 = require("ethers"); -var _abi = [ - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "owner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "approved", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "Approval", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "owner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "operator", - type: "address" - }, - { - indexed: false, - internalType: "bool", - name: "approved", - type: "bool" - }, - ], - name: "ApprovalForAll", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "from", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "to", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "Transfer", - type: "event" - }, - { - inputs: [ - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "approve", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - ], - name: "balanceOf", - outputs: [ - { - internalType: "uint256", - name: "balance", - type: "uint256" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "getApproved", - outputs: [ - { - internalType: "address", - name: "operator", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - { - internalType: "address", - name: "operator", - type: "address" - }, - ], - name: "isApprovedForAll", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "ownerOf", - outputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "safeTransferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - { - internalType: "bytes", - name: "data", - type: "bytes" - }, - ], - name: "safeTransferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "operator", - type: "address" - }, - { - internalType: "bool", - name: "_approved", - type: "bool" - }, - ], - name: "setApprovalForAll", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "bytes4", - name: "interfaceId", - type: "bytes4" - }, - ], - name: "supportsInterface", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "transferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, -]; -var IERC721Upgradeable__factory = /** @class */ (function () { - function IERC721Upgradeable__factory() { - } - IERC721Upgradeable__factory.createInterface = function () { - return new ethers_1.utils.Interface(_abi); - }; - IERC721Upgradeable__factory.connect = function (address, signerOrProvider) { - return new ethers_1.Contract(address, _abi, signerOrProvider); - }; - IERC721Upgradeable__factory.abi = _abi; - return IERC721Upgradeable__factory; -}()); -exports.IERC721Upgradeable__factory = IERC721Upgradeable__factory; diff --git a/desci-contracts/typechain-types/factories/IERC721__factory.js b/desci-contracts/typechain-types/factories/IERC721__factory.js deleted file mode 100644 index 5c9e78b9..00000000 --- a/desci-contracts/typechain-types/factories/IERC721__factory.js +++ /dev/null @@ -1,307 +0,0 @@ -"use strict"; -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -exports.__esModule = true; -exports.IERC721__factory = void 0; -var ethers_1 = require("ethers"); -var _abi = [ - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "owner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "approved", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "Approval", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "owner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "operator", - type: "address" - }, - { - indexed: false, - internalType: "bool", - name: "approved", - type: "bool" - }, - ], - name: "ApprovalForAll", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "from", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "to", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "Transfer", - type: "event" - }, - { - inputs: [ - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "approve", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - ], - name: "balanceOf", - outputs: [ - { - internalType: "uint256", - name: "balance", - type: "uint256" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "getApproved", - outputs: [ - { - internalType: "address", - name: "operator", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - { - internalType: "address", - name: "operator", - type: "address" - }, - ], - name: "isApprovedForAll", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "ownerOf", - outputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "safeTransferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - { - internalType: "bytes", - name: "data", - type: "bytes" - }, - ], - name: "safeTransferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "operator", - type: "address" - }, - { - internalType: "bool", - name: "_approved", - type: "bool" - }, - ], - name: "setApprovalForAll", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "bytes4", - name: "interfaceId", - type: "bytes4" - }, - ], - name: "supportsInterface", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "transferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, -]; -var IERC721__factory = /** @class */ (function () { - function IERC721__factory() { - } - IERC721__factory.createInterface = function () { - return new ethers_1.utils.Interface(_abi); - }; - IERC721__factory.connect = function (address, signerOrProvider) { - return new ethers_1.Contract(address, _abi, signerOrProvider); - }; - IERC721__factory.abi = _abi; - return IERC721__factory; -}()); -exports.IERC721__factory = IERC721__factory; diff --git a/desci-contracts/typechain-types/factories/Initializable__factory.js b/desci-contracts/typechain-types/factories/Initializable__factory.js deleted file mode 100644 index 04087930..00000000 --- a/desci-contracts/typechain-types/factories/Initializable__factory.js +++ /dev/null @@ -1,35 +0,0 @@ -"use strict"; -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -exports.__esModule = true; -exports.Initializable__factory = void 0; -var ethers_1 = require("ethers"); -var _abi = [ - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "uint8", - name: "version", - type: "uint8" - }, - ], - name: "Initialized", - type: "event" - }, -]; -var Initializable__factory = /** @class */ (function () { - function Initializable__factory() { - } - Initializable__factory.createInterface = function () { - return new ethers_1.utils.Interface(_abi); - }; - Initializable__factory.connect = function (address, signerOrProvider) { - return new ethers_1.Contract(address, _abi, signerOrProvider); - }; - Initializable__factory.abi = _abi; - return Initializable__factory; -}()); -exports.Initializable__factory = Initializable__factory; diff --git a/desci-contracts/typechain-types/factories/OwnableUpgradeable__factory.js b/desci-contracts/typechain-types/factories/OwnableUpgradeable__factory.js deleted file mode 100644 index 9b9ec679..00000000 --- a/desci-contracts/typechain-types/factories/OwnableUpgradeable__factory.js +++ /dev/null @@ -1,87 +0,0 @@ -"use strict"; -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -exports.__esModule = true; -exports.OwnableUpgradeable__factory = void 0; -var ethers_1 = require("ethers"); -var _abi = [ - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "uint8", - name: "version", - type: "uint8" - }, - ], - name: "Initialized", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "previousOwner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "newOwner", - type: "address" - }, - ], - name: "OwnershipTransferred", - type: "event" - }, - { - inputs: [], - name: "owner", - outputs: [ - { - internalType: "address", - name: "", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [], - name: "renounceOwnership", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "newOwner", - type: "address" - }, - ], - name: "transferOwnership", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, -]; -var OwnableUpgradeable__factory = /** @class */ (function () { - function OwnableUpgradeable__factory() { - } - OwnableUpgradeable__factory.createInterface = function () { - return new ethers_1.utils.Interface(_abi); - }; - OwnableUpgradeable__factory.connect = function (address, signerOrProvider) { - return new ethers_1.Contract(address, _abi, signerOrProvider); - }; - OwnableUpgradeable__factory.abi = _abi; - return OwnableUpgradeable__factory; -}()); -exports.OwnableUpgradeable__factory = OwnableUpgradeable__factory; diff --git a/desci-contracts/typechain-types/factories/ResearchObjectMigrated__factory.js b/desci-contracts/typechain-types/factories/ResearchObjectMigrated__factory.js deleted file mode 100644 index 903ff476..00000000 --- a/desci-contracts/typechain-types/factories/ResearchObjectMigrated__factory.js +++ /dev/null @@ -1,790 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - if (typeof b !== "function" && b !== null) - throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -exports.__esModule = true; -exports.ResearchObjectMigrated__factory = void 0; -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -var ethers_1 = require("ethers"); -var _abi = [ - { - inputs: [], - stateMutability: "nonpayable", - type: "constructor" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "owner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "approved", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "Approval", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "owner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "operator", - type: "address" - }, - { - indexed: false, - internalType: "bool", - name: "approved", - type: "bool" - }, - ], - name: "ApprovalForAll", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "uint8", - name: "version", - type: "uint8" - }, - ], - name: "Initialized", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "previousOwner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "newOwner", - type: "address" - }, - ], - name: "OwnershipTransferred", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "from", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "to", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "Transfer", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "_from", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "_uuid", - type: "uint256" - }, - { - indexed: false, - internalType: "bytes", - name: "_cid", - type: "bytes" - }, - ], - name: "VersionPush", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "_from", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "_uuid", - type: "uint256" - }, - { - indexed: false, - internalType: "bytes", - name: "_cid", - type: "bytes" - }, - { - indexed: false, - internalType: "uint256", - name: "_migration_timestamp", - type: "uint256" - }, - ], - name: "VersionPushMigrated", - type: "event" - }, - { - inputs: [ - { - internalType: "address", - name: "dpidRegistry", - type: "address" - }, - ], - name: "__ResearchObjectV2_init", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "string", - name: "name", - type: "string" - }, - { - internalType: "string", - name: "symbol", - type: "string" - }, - ], - name: "__VersionedERC721V2_init", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [], - name: "_dpidRegistry", - outputs: [ - { - internalType: "address", - name: "", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - components: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "uint256", - name: "uuid", - type: "uint256" - }, - { - internalType: "bytes", - name: "cid", - type: "bytes" - }, - { - internalType: "uint256", - name: "timestamp", - type: "uint256" - }, - { - internalType: "uint256", - name: "dpid", - type: "uint256" - }, - ], - internalType: "struct MigrationData[]", - name: "importData", - type: "tuple[]" - }, - { - internalType: "bytes32", - name: "defaultPrefix", - type: "bytes32" - }, - ], - name: "_importChunk", - outputs: [], - stateMutability: "payable", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "uuid", - type: "uint256" - }, - { - internalType: "bytes", - name: "cid", - type: "bytes" - }, - { - internalType: "bytes32", - name: "prefix", - type: "bytes32" - }, - { - internalType: "uint256", - name: "expectedDpid", - type: "uint256" - }, - { - internalType: "uint256", - name: "timestamp", - type: "uint256" - }, - { - internalType: "address", - name: "targetAccount", - type: "address" - }, - ], - name: "_importWithDpid", - outputs: [], - stateMutability: "payable", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "", - type: "uint256" - }, - ], - name: "_metadata", - outputs: [ - { - internalType: "bytes", - name: "", - type: "bytes" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "approve", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - ], - name: "balanceOf", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "exists", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "getApproved", - outputs: [ - { - internalType: "address", - name: "", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "dpidRegistry", - type: "address" - }, - ], - name: "initialize", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - { - internalType: "address", - name: "operator", - type: "address" - }, - ], - name: "isApprovedForAll", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "uuid", - type: "uint256" - }, - { - internalType: "bytes", - name: "cid", - type: "bytes" - }, - ], - name: "mint", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "uuid", - type: "uint256" - }, - { - internalType: "bytes", - name: "cid", - type: "bytes" - }, - { - internalType: "bytes32", - name: "prefix", - type: "bytes32" - }, - { - internalType: "uint256", - name: "expectedDpid", - type: "uint256" - }, - ], - name: "mintWithDpid", - outputs: [], - stateMutability: "payable", - type: "function" - }, - { - inputs: [], - name: "name", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [], - name: "owner", - outputs: [ - { - internalType: "address", - name: "", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "ownerOf", - outputs: [ - { - internalType: "address", - name: "", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [], - name: "renounceOwnership", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "safeTransferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - { - internalType: "bytes", - name: "data", - type: "bytes" - }, - ], - name: "safeTransferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "operator", - type: "address" - }, - { - internalType: "bool", - name: "approved", - type: "bool" - }, - ], - name: "setApprovalForAll", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "dpidRegistry", - type: "address" - }, - ], - name: "setRegistry", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "string", - name: "uri", - type: "string" - }, - ], - name: "setURI", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "bytes4", - name: "interfaceId", - type: "bytes4" - }, - ], - name: "supportsInterface", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [], - name: "symbol", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "tokenURI", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "transferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "newOwner", - type: "address" - }, - ], - name: "transferOwnership", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - { - internalType: "bytes", - name: "cid", - type: "bytes" - }, - ], - name: "updateMetadata", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, -]; -var _bytecode = "0x60806040523480156200001157600080fd5b50620000226200003860201b60201c565b620000326200003860201b60201c565b620001e3565b600060019054906101000a900460ff16156200008b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000829062000137565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff161015620000fd5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000f4919062000159565b60405180910390a15b565b60006200010e60278362000176565b91506200011b8262000194565b604082019050919050565b620001318162000187565b82525050565b600060208201905081810360008301526200015281620000ff565b9050919050565b600060208201905062000170600083018462000126565b92915050565b600082825260208201905092915050565b600060ff82169050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b6142be80620001f36000396000f3fe6080604052600436106101c25760003560e01c806385198761116100f7578063b88d4fde11610095578063db7fd40811610064578063db7fd40814610623578063e985e9c51461064c578063f2fde38b14610689578063ffe77b0f146106b2576101c2565b8063b88d4fde14610578578063c4d66de8146105a1578063c87b56dd146105ca578063c88efd1514610607576101c2565b80639a7fad40116100d15780639a7fad40146104d4578063a22cb465146104fd578063a91ee0dc14610526578063af3ba9c11461054f576101c2565b806385198761146104625780638da5cb5b1461047e57806395d89b41146104a9576101c2565b80633dcd3236116101645780634f558e791161013e5780634f558e79146103945780636352211e146103d157806370a082311461040e578063715018a61461044b576101c2565b80633dcd3236146103245780633e8513181461034f57806342842e0e1461036b576101c2565b8063081812fc116101a0578063081812fc14610258578063095ea7b31461029557806313859f46146102be57806323b872dd146102fb576101c2565b806301ffc9a7146101c757806302fe53051461020457806306fdde031461022d575b600080fd5b3480156101d357600080fd5b506101ee60048036038101906101e99190612f42565b6106db565b6040516101fb919061364f565b60405180910390f35b34801561021057600080fd5b5061022b60048036038101906102269190612f94565b6107bd565b005b34801561023957600080fd5b506102426107df565b60405161024f9190613700565b60405180910390f35b34801561026457600080fd5b5061027f600480360381019061027a9190613041565b610871565b60405161028c91906135e8565b60405180910390f35b3480156102a157600080fd5b506102bc60048036038101906102b79190612eb2565b6108b7565b005b3480156102ca57600080fd5b506102e560048036038101906102e09190613041565b6109cf565b6040516102f29190613693565b60405180910390f35b34801561030757600080fd5b50610322600480360381019061031d9190612dac565b610a6f565b005b34801561033057600080fd5b50610339610acf565b60405161034691906135e8565b60405180910390f35b610369600480360381019061036491906131bf565b610af5565b005b34801561037757600080fd5b50610392600480360381019061038d9190612dac565b610d1e565b005b3480156103a057600080fd5b506103bb60048036038101906103b69190613041565b610d3e565b6040516103c8919061364f565b60405180910390f35b3480156103dd57600080fd5b506103f860048036038101906103f39190613041565b610d50565b60405161040591906135e8565b60405180910390f35b34801561041a57600080fd5b5061043560048036038101906104309190612d47565b610e02565b6040516104429190613962565b60405180910390f35b34801561045757600080fd5b50610460610eba565b005b61047c60048036038101906104779190612eee565b610ece565b005b34801561048a57600080fd5b50610493610f62565b6040516104a091906135e8565b60405180910390f35b3480156104b557600080fd5b506104be610f8c565b6040516104cb9190613700565b60405180910390f35b3480156104e057600080fd5b506104fb60048036038101906104f6919061316b565b61101e565b005b34801561050957600080fd5b50610524600480360381019061051f9190612e76565b61113c565b005b34801561053257600080fd5b5061054d60048036038101906105489190612d47565b611152565b005b34801561055b57600080fd5b5061057660048036038101906105719190612fd5565b61119e565b005b34801561058457600080fd5b5061059f600480360381019061059a9190612dfb565b6111fb565b005b3480156105ad57600080fd5b506105c860048036038101906105c39190612d47565b61125d565b005b3480156105d657600080fd5b506105f160048036038101906105ec9190613041565b6113e6565b6040516105fe9190613700565b60405180910390f35b610621600480360381019061061c91906130eb565b61144e565b005b34801561062f57600080fd5b5061064a60048036038101906106459190613093565b61155d565b005b34801561065857600080fd5b50610673600480360381019061066e9190612d70565b6115cd565b604051610680919061364f565b60405180910390f35b34801561069557600080fd5b506106b060048036038101906106ab9190612d47565b611661565b005b3480156106be57600080fd5b506106d960048036038101906106d49190612d47565b6116e5565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806107a657507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806107b657506107b5826118d9565b5b9050919050565b6107c5611943565b8060ca90805190602001906107db929190612921565b5050565b6060606580546107ee90613c0d565b80601f016020809104026020016040519081016040528092919081815260200182805461081a90613c0d565b80156108675780601f1061083c57610100808354040283529160200191610867565b820191906000526020600020905b81548152906001019060200180831161084a57829003601f168201915b5050505050905090565b600061087c826119c1565b6069600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006108c282610d50565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610933576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161092a90613902565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610952611a0c565b73ffffffffffffffffffffffffffffffffffffffff16148061098157506109808161097b611a0c565b6115cd565b5b6109c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109b790613862565b60405180910390fd5b6109ca8383611a14565b505050565b609760205280600052604060002060009150905080546109ee90613c0d565b80601f0160208091040260200160405190810160405280929190818152602001828054610a1a90613c0d565b8015610a675780601f10610a3c57610100808354040283529160200191610a67565b820191906000526020600020905b815481529060010190602001808311610a4a57829003601f168201915b505050505081565b610a80610a7a611a0c565b82611acd565b610abf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ab690613942565b60405180910390fd5b610aca838383611b62565b505050565b60cb60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610afd611943565b600060cb60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008173ffffffffffffffffffffffffffffffffffffffff166318ae19c287876040518363ffffffff1660e01b8152600401610b6192919061366a565b60206040518083038186803b158015610b7957600080fd5b505afa158015610b8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb1919061306a565b9050600083905060008990506000831415610cb75760008473ffffffffffffffffffffffffffffffffffffffff1663da4a9842348b8e6040518463ffffffff1660e01b8152600401610c0492919061366a565b6020604051808303818588803b158015610c1d57600080fd5b505af1158015610c31573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610c56919061306a565b9050808814610c9a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c91906137a2565b60405180910390fd5b610ca48383611dc9565b610cb5610caf611a0c565b83611a14565b505b610cc18a8a61101e565b808273ffffffffffffffffffffffffffffffffffffffff167f4c2f0fd1019fdc5963138c1513932ae5dca836a3b35e8bd71a68803dec00ea1d8b89604051610d0a9291906136b5565b60405180910390a350505050505050505050565b610d39838383604051806020016040528060008152506111fb565b505050565b6000610d4982611de7565b9050919050565b6000806067600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610df9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610df0906138e2565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610e73576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6a90613822565b60405180910390fd5b606860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b610ec2611943565b610ecc6000611e53565b565b610ed6611943565b60005b8251811015610f5d576000838281518110610f1d577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101519050610f498160200151826040015185846080015185606001518660000151610af5565b508080610f5590613c70565b915050610ed9565b505050565b6000609860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060668054610f9b90613c0d565b80601f0160208091040260200160405190810160405280929190818152602001828054610fc790613c0d565b80156110145780601f10610fe957610100808354040283529160200191611014565b820191906000526020600020905b815481529060010190602001808311610ff757829003601f168201915b5050505050905090565b816000611029611a0c565b905060008173ffffffffffffffffffffffffffffffffffffffff1661104d84610d50565b73ffffffffffffffffffffffffffffffffffffffff16148061107557506110748284611acd565b5b9050806110b7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110ae906138a2565b60405180910390fd5b836097600087815260200190815260200160002090805190602001906110de9291906129a7565b50846110e8611a0c565b73ffffffffffffffffffffffffffffffffffffffff167fabddf73bfc8efbf8287a09ea355e43cf6c0c22880ce0470affeba5271c0a76948660405161112d9190613693565b60405180910390a35050505050565b61114e611147611a0c565b8383611f19565b5050565b61115a611943565b8060cb60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600060019054906101000a900460ff166111ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111e490613922565b60405180910390fd5b6111f78282612086565b5050565b61120c611206611a0c565b83611acd565b61124b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124290613942565b60405180910390fd5b611257848484846120e3565b50505050565b60008060019054906101000a900460ff1615905080801561128e5750600160008054906101000a900460ff1660ff16105b806112bb575061129d3061213f565b1580156112ba5750600160008054906101000a900460ff1660ff16145b5b6112fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112f190613842565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015611337576001600060016101000a81548160ff0219169083151502179055505b611340826116e5565b611348612162565b8160cb60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080156113e25760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516113d991906136e5565b60405180910390a15b5050565b60606113f1826119c1565b60006113fb6121bb565b9050600081511161141b5760405180602001604052806000815250611446565b806114258461224d565b6040516020016114369291906135c4565b6040516020818303038152906040525b915050919050565b600060cb60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008173ffffffffffffffffffffffffffffffffffffffff1663da4a984234868a6040518463ffffffff1660e01b81526004016114b392919061366a565b6020604051808303818588803b1580156114cc57600080fd5b505af11580156114e0573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611505919061306a565b9050808314611549576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611540906137a2565b60405180910390fd5b61155487878761155d565b50505050505050565b6000611567611a0c565b905060008490506115788282611dc9565b6115c68585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061101e565b5050505050565b6000606a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611669611943565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156116d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116d090613742565b60405180910390fd5b6116e281611e53565b50565b60008060019054906101000a900460ff161590508080156117165750600160008054906101000a900460ff1660ff16105b8061174357506117253061213f565b1580156117425750600160008054906101000a900460ff1660ff16145b5b611782576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161177990613842565b60405180910390fd5b60016000806101000a81548160ff021916908360ff16021790555080156117bf576001600060016101000a81548160ff0219169083151502179055505b6118336040518060400160405280601581526020017f4465536369205265736561726368204f626a65637400000000000000000000008152506040518060400160405280600a81526020017f44655363692d4e6f64650000000000000000000000000000000000000000000081525061119e565b61183b612162565b8160cb60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080156118d55760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516118cc91906136e5565b60405180910390a15b5050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b61194b611a0c565b73ffffffffffffffffffffffffffffffffffffffff16611969610f62565b73ffffffffffffffffffffffffffffffffffffffff16146119bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119b6906138c2565b60405180910390fd5b565b6119ca81611de7565b611a09576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a00906138e2565b60405180910390fd5b50565b600033905090565b816069600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611a8783610d50565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080611ad983610d50565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611b1b5750611b1a81856115cd565b5b80611b5957508373ffffffffffffffffffffffffffffffffffffffff16611b4184610871565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611b8282610d50565b73ffffffffffffffffffffffffffffffffffffffff1614611bd8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bcf90613762565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611c48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c3f906137c2565b60405180910390fd5b611c538383836123fa565b611c5e600082611a14565b6001606860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611cae9190613afa565b925050819055506001606860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d059190613a73565b92505081905550816067600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611dc483838361246e565b505050565b611de3828260405180602001604052806000815250612473565b5050565b60008073ffffffffffffffffffffffffffffffffffffffff166067600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6000609860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081609860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611f88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f7f906137e2565b60405180910390fd5b80606a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612079919061364f565b60405180910390a3505050565b600060019054906101000a900460ff166120d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120cc90613922565b60405180910390fd5b6120df82826124ce565b5050565b6120ee848484611b62565b6120fa8484848461254f565b612139576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161213090613722565b60405180910390fd5b50505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff166121b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121a890613922565b60405180910390fd5b6121b96126e6565b565b606060ca80546121ca90613c0d565b80601f01602080910402602001604051908101604052809291908181526020018280546121f690613c0d565b80156122435780601f1061221857610100808354040283529160200191612243565b820191906000526020600020905b81548152906001019060200180831161222657829003601f168201915b5050505050905090565b60606000821415612295576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506123f5565b600082905060005b600082146122c75780806122b090613c70565b915050600a826122c09190613ac9565b915061229d565b60008167ffffffffffffffff811115612309577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f19166020018201604052801561233b5781602001600182028036833780820191505090505b5090505b600085146123ee576001826123549190613afa565b9150600a856123639190613cb9565b603061236f9190613a73565b60f81b8183815181106123ab577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856123e79190613ac9565b945061233f565b8093505050505b919050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614612469576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161246090613802565b60405180910390fd5b505050565b505050565b61247d8383612747565b61248a600084848461254f565b6124c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124c090613722565b60405180910390fd5b505050565b600060019054906101000a900460ff1661251d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161251490613922565b60405180910390fd5b8160659080519060200190612533929190612921565b50806066908051906020019061254a929190612921565b505050565b60006125708473ffffffffffffffffffffffffffffffffffffffff1661213f565b156126d9578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612599611a0c565b8786866040518563ffffffff1660e01b81526004016125bb9493929190613603565b602060405180830381600087803b1580156125d557600080fd5b505af192505050801561260657506040513d601f19601f820116820180604052508101906126039190612f6b565b60015b612689573d8060008114612636576040519150601f19603f3d011682016040523d82523d6000602084013e61263b565b606091505b50600081511415612681576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161267890613722565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149150506126de565b600190505b949350505050565b600060019054906101000a900460ff16612735576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161272c90613922565b60405180910390fd5b612745612740611a0c565b611e53565b565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156127b7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127ae90613882565b60405180910390fd5b6127c081611de7565b15612800576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127f790613782565b60405180910390fd5b61280c600083836123fa565b6001606860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461285c9190613a73565b92505081905550816067600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461291d6000838361246e565b5050565b82805461292d90613c0d565b90600052602060002090601f01602090048101928261294f5760008555612996565b82601f1061296857805160ff1916838001178555612996565b82800160010185558215612996579182015b8281111561299557825182559160200191906001019061297a565b5b5090506129a39190612a2d565b5090565b8280546129b390613c0d565b90600052602060002090601f0160209004810192826129d55760008555612a1c565b82601f106129ee57805160ff1916838001178555612a1c565b82800160010185558215612a1c579182015b82811115612a1b578251825591602001919060010190612a00565b5b509050612a299190612a2d565b5090565b5b80821115612a46576000816000905550600101612a2e565b5090565b6000612a5d612a58846139a2565b61397d565b90508083825260208201905082856020860282011115612a7c57600080fd5b60005b85811015612ac657813567ffffffffffffffff811115612a9e57600080fd5b808601612aab8982612c7d565b85526020850194506020840193505050600181019050612a7f565b5050509392505050565b6000612ae3612ade846139ce565b61397d565b905082815260208101848484011115612afb57600080fd5b612b06848285613bcb565b509392505050565b6000612b21612b1c846139ff565b61397d565b905082815260208101848484011115612b3957600080fd5b612b44848285613bcb565b509392505050565b600081359050612b5b81614215565b92915050565b600082601f830112612b7257600080fd5b8135612b82848260208601612a4a565b91505092915050565b600081359050612b9a8161422c565b92915050565b600081359050612baf81614243565b92915050565b600081359050612bc48161425a565b92915050565b600081519050612bd98161425a565b92915050565b60008083601f840112612bf157600080fd5b8235905067ffffffffffffffff811115612c0a57600080fd5b602083019150836001820283011115612c2257600080fd5b9250929050565b600082601f830112612c3a57600080fd5b8135612c4a848260208601612ad0565b91505092915050565b600082601f830112612c6457600080fd5b8135612c74848260208601612b0e565b91505092915050565b600060a08284031215612c8f57600080fd5b612c9960a061397d565b90506000612ca984828501612b4c565b6000830152506020612cbd84828501612d1d565b602083015250604082013567ffffffffffffffff811115612cdd57600080fd5b612ce984828501612c29565b6040830152506060612cfd84828501612d1d565b6060830152506080612d1184828501612d1d565b60808301525092915050565b600081359050612d2c81614271565b92915050565b600081519050612d4181614271565b92915050565b600060208284031215612d5957600080fd5b6000612d6784828501612b4c565b91505092915050565b60008060408385031215612d8357600080fd5b6000612d9185828601612b4c565b9250506020612da285828601612b4c565b9150509250929050565b600080600060608486031215612dc157600080fd5b6000612dcf86828701612b4c565b9350506020612de086828701612b4c565b9250506040612df186828701612d1d565b9150509250925092565b60008060008060808587031215612e1157600080fd5b6000612e1f87828801612b4c565b9450506020612e3087828801612b4c565b9350506040612e4187828801612d1d565b925050606085013567ffffffffffffffff811115612e5e57600080fd5b612e6a87828801612c29565b91505092959194509250565b60008060408385031215612e8957600080fd5b6000612e9785828601612b4c565b9250506020612ea885828601612b8b565b9150509250929050565b60008060408385031215612ec557600080fd5b6000612ed385828601612b4c565b9250506020612ee485828601612d1d565b9150509250929050565b60008060408385031215612f0157600080fd5b600083013567ffffffffffffffff811115612f1b57600080fd5b612f2785828601612b61565b9250506020612f3885828601612ba0565b9150509250929050565b600060208284031215612f5457600080fd5b6000612f6284828501612bb5565b91505092915050565b600060208284031215612f7d57600080fd5b6000612f8b84828501612bca565b91505092915050565b600060208284031215612fa657600080fd5b600082013567ffffffffffffffff811115612fc057600080fd5b612fcc84828501612c53565b91505092915050565b60008060408385031215612fe857600080fd5b600083013567ffffffffffffffff81111561300257600080fd5b61300e85828601612c53565b925050602083013567ffffffffffffffff81111561302b57600080fd5b61303785828601612c53565b9150509250929050565b60006020828403121561305357600080fd5b600061306184828501612d1d565b91505092915050565b60006020828403121561307c57600080fd5b600061308a84828501612d32565b91505092915050565b6000806000604084860312156130a857600080fd5b60006130b686828701612d1d565b935050602084013567ffffffffffffffff8111156130d357600080fd5b6130df86828701612bdf565b92509250509250925092565b60008060008060006080868803121561310357600080fd5b600061311188828901612d1d565b955050602086013567ffffffffffffffff81111561312e57600080fd5b61313a88828901612bdf565b9450945050604061314d88828901612ba0565b925050606061315e88828901612d1d565b9150509295509295909350565b6000806040838503121561317e57600080fd5b600061318c85828601612d1d565b925050602083013567ffffffffffffffff8111156131a957600080fd5b6131b585828601612c29565b9150509250929050565b60008060008060008060c087890312156131d857600080fd5b60006131e689828a01612d1d565b965050602087013567ffffffffffffffff81111561320357600080fd5b61320f89828a01612c29565b955050604061322089828a01612ba0565b945050606061323189828a01612d1d565b935050608061324289828a01612d1d565b92505060a061325389828a01612b4c565b9150509295509295509295565b61326981613b2e565b82525050565b61327881613b40565b82525050565b61328781613b4c565b82525050565b600061329882613a30565b6132a28185613a46565b93506132b2818560208601613bda565b6132bb81613da6565b840191505092915050565b6132cf81613bb9565b82525050565b60006132e082613a3b565b6132ea8185613a57565b93506132fa818560208601613bda565b61330381613da6565b840191505092915050565b600061331982613a3b565b6133238185613a68565b9350613333818560208601613bda565b80840191505092915050565b600061334c603283613a57565b915061335782613db7565b604082019050919050565b600061336f602683613a57565b915061337a82613e06565b604082019050919050565b6000613392602583613a57565b915061339d82613e55565b604082019050919050565b60006133b5601c83613a57565b91506133c082613ea4565b602082019050919050565b60006133d8600f83613a57565b91506133e382613ecd565b602082019050919050565b60006133fb602483613a57565b915061340682613ef6565b604082019050919050565b600061341e601983613a57565b915061342982613f45565b602082019050919050565b6000613441600b83613a57565b915061344c82613f6e565b602082019050919050565b6000613464602983613a57565b915061346f82613f97565b604082019050919050565b6000613487602e83613a57565b915061349282613fe6565b604082019050919050565b60006134aa603e83613a57565b91506134b582614035565b604082019050919050565b60006134cd602083613a57565b91506134d882614084565b602082019050919050565b60006134f0600d83613a57565b91506134fb826140ad565b602082019050919050565b6000613513602083613a57565b915061351e826140d6565b602082019050919050565b6000613536601883613a57565b9150613541826140ff565b602082019050919050565b6000613559602183613a57565b915061356482614128565b604082019050919050565b600061357c602b83613a57565b915061358782614177565b604082019050919050565b600061359f602e83613a57565b91506135aa826141c6565b604082019050919050565b6135be81613ba2565b82525050565b60006135d0828561330e565b91506135dc828461330e565b91508190509392505050565b60006020820190506135fd6000830184613260565b92915050565b60006080820190506136186000830187613260565b6136256020830186613260565b61363260408301856135b5565b8181036060830152613644818461328d565b905095945050505050565b6000602082019050613664600083018461326f565b92915050565b600060408201905061367f600083018561327e565b61368c60208301846135b5565b9392505050565b600060208201905081810360008301526136ad818461328d565b905092915050565b600060408201905081810360008301526136cf818561328d565b90506136de60208301846135b5565b9392505050565b60006020820190506136fa60008301846132c6565b92915050565b6000602082019050818103600083015261371a81846132d5565b905092915050565b6000602082019050818103600083015261373b8161333f565b9050919050565b6000602082019050818103600083015261375b81613362565b9050919050565b6000602082019050818103600083015261377b81613385565b9050919050565b6000602082019050818103600083015261379b816133a8565b9050919050565b600060208201905081810360008301526137bb816133cb565b9050919050565b600060208201905081810360008301526137db816133ee565b9050919050565b600060208201905081810360008301526137fb81613411565b9050919050565b6000602082019050818103600083015261381b81613434565b9050919050565b6000602082019050818103600083015261383b81613457565b9050919050565b6000602082019050818103600083015261385b8161347a565b9050919050565b6000602082019050818103600083015261387b8161349d565b9050919050565b6000602082019050818103600083015261389b816134c0565b9050919050565b600060208201905081810360008301526138bb816134e3565b9050919050565b600060208201905081810360008301526138db81613506565b9050919050565b600060208201905081810360008301526138fb81613529565b9050919050565b6000602082019050818103600083015261391b8161354c565b9050919050565b6000602082019050818103600083015261393b8161356f565b9050919050565b6000602082019050818103600083015261395b81613592565b9050919050565b600060208201905061397760008301846135b5565b92915050565b6000613987613998565b90506139938282613c3f565b919050565b6000604051905090565b600067ffffffffffffffff8211156139bd576139bc613d77565b5b602082029050602081019050919050565b600067ffffffffffffffff8211156139e9576139e8613d77565b5b6139f282613da6565b9050602081019050919050565b600067ffffffffffffffff821115613a1a57613a19613d77565b5b613a2382613da6565b9050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6000613a7e82613ba2565b9150613a8983613ba2565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613abe57613abd613cea565b5b828201905092915050565b6000613ad482613ba2565b9150613adf83613ba2565b925082613aef57613aee613d19565b5b828204905092915050565b6000613b0582613ba2565b9150613b1083613ba2565b925082821015613b2357613b22613cea565b5b828203905092915050565b6000613b3982613b82565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b6000613bc482613bac565b9050919050565b82818337600083830152505050565b60005b83811015613bf8578082015181840152602081019050613bdd565b83811115613c07576000848401525b50505050565b60006002820490506001821680613c2557607f821691505b60208210811415613c3957613c38613d48565b5b50919050565b613c4882613da6565b810181811067ffffffffffffffff82111715613c6757613c66613d77565b5b80604052505050565b6000613c7b82613ba2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613cae57613cad613cea565b5b600182019050919050565b6000613cc482613ba2565b9150613ccf83613ba2565b925082613cdf57613cde613d19565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f556e657870656374656420645049440000000000000000000000000000000000600082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f6e6f207472616e73666572000000000000000000000000000000000000000000600082015250565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f4e6f207065726d697373696f6e00000000000000000000000000000000000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b61421e81613b2e565b811461422957600080fd5b50565b61423581613b40565b811461424057600080fd5b50565b61424c81613b4c565b811461425757600080fd5b50565b61426381613b56565b811461426e57600080fd5b50565b61427a81613ba2565b811461428557600080fd5b5056fea2646970667358221220e147c9d6b61e5e0fe6fd6c5970956c393da31e1955617ef35149fc909ab6e77a64736f6c63430008040033"; -var isSuperArgs = function (xs) { return xs.length > 1; }; -var ResearchObjectMigrated__factory = /** @class */ (function (_super) { - __extends(ResearchObjectMigrated__factory, _super); - function ResearchObjectMigrated__factory() { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - var _this = this; - if (isSuperArgs(args)) { - _this = _super.apply(this, args) || this; - } - else { - _this = _super.call(this, _abi, _bytecode, args[0]) || this; - } - _this.contractName = "ResearchObjectMigrated"; - return _this; - } - ResearchObjectMigrated__factory.prototype.deploy = function (overrides) { - return _super.prototype.deploy.call(this, overrides || {}); - }; - ResearchObjectMigrated__factory.prototype.getDeployTransaction = function (overrides) { - return _super.prototype.getDeployTransaction.call(this, overrides || {}); - }; - ResearchObjectMigrated__factory.prototype.attach = function (address) { - return _super.prototype.attach.call(this, address); - }; - ResearchObjectMigrated__factory.prototype.connect = function (signer) { - return _super.prototype.connect.call(this, signer); - }; - ResearchObjectMigrated__factory.createInterface = function () { - return new ethers_1.utils.Interface(_abi); - }; - ResearchObjectMigrated__factory.connect = function (address, signerOrProvider) { - return new ethers_1.Contract(address, _abi, signerOrProvider); - }; - ResearchObjectMigrated__factory.bytecode = _bytecode; - ResearchObjectMigrated__factory.abi = _abi; - return ResearchObjectMigrated__factory; -}(ethers_1.ContractFactory)); -exports.ResearchObjectMigrated__factory = ResearchObjectMigrated__factory; diff --git a/desci-contracts/typechain-types/factories/ResearchObjectV2__factory.js b/desci-contracts/typechain-types/factories/ResearchObjectV2__factory.js deleted file mode 100644 index 8abcd706..00000000 --- a/desci-contracts/typechain-types/factories/ResearchObjectV2__factory.js +++ /dev/null @@ -1,663 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - if (typeof b !== "function" && b !== null) - throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -exports.__esModule = true; -exports.ResearchObjectV2__factory = void 0; -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -var ethers_1 = require("ethers"); -var _abi = [ - { - inputs: [], - stateMutability: "nonpayable", - type: "constructor" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "owner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "approved", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "Approval", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "owner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "operator", - type: "address" - }, - { - indexed: false, - internalType: "bool", - name: "approved", - type: "bool" - }, - ], - name: "ApprovalForAll", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "uint8", - name: "version", - type: "uint8" - }, - ], - name: "Initialized", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "previousOwner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "newOwner", - type: "address" - }, - ], - name: "OwnershipTransferred", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "from", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "to", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "Transfer", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "_from", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "_uuid", - type: "uint256" - }, - { - indexed: false, - internalType: "bytes", - name: "_cid", - type: "bytes" - }, - ], - name: "VersionPush", - type: "event" - }, - { - inputs: [ - { - internalType: "address", - name: "dpidRegistry", - type: "address" - }, - ], - name: "__ResearchObjectV2_init", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "string", - name: "name", - type: "string" - }, - { - internalType: "string", - name: "symbol", - type: "string" - }, - ], - name: "__VersionedERC721V2_init", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [], - name: "_dpidRegistry", - outputs: [ - { - internalType: "address", - name: "", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "", - type: "uint256" - }, - ], - name: "_metadata", - outputs: [ - { - internalType: "bytes", - name: "", - type: "bytes" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "approve", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - ], - name: "balanceOf", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "exists", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "getApproved", - outputs: [ - { - internalType: "address", - name: "", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - { - internalType: "address", - name: "operator", - type: "address" - }, - ], - name: "isApprovedForAll", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "uuid", - type: "uint256" - }, - { - internalType: "bytes", - name: "cid", - type: "bytes" - }, - ], - name: "mint", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "uuid", - type: "uint256" - }, - { - internalType: "bytes", - name: "cid", - type: "bytes" - }, - { - internalType: "bytes32", - name: "prefix", - type: "bytes32" - }, - { - internalType: "uint256", - name: "expectedDpid", - type: "uint256" - }, - ], - name: "mintWithDpid", - outputs: [], - stateMutability: "payable", - type: "function" - }, - { - inputs: [], - name: "name", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [], - name: "owner", - outputs: [ - { - internalType: "address", - name: "", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "ownerOf", - outputs: [ - { - internalType: "address", - name: "", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [], - name: "renounceOwnership", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "safeTransferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - { - internalType: "bytes", - name: "data", - type: "bytes" - }, - ], - name: "safeTransferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "operator", - type: "address" - }, - { - internalType: "bool", - name: "approved", - type: "bool" - }, - ], - name: "setApprovalForAll", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "dpidRegistry", - type: "address" - }, - ], - name: "setRegistry", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "string", - name: "uri", - type: "string" - }, - ], - name: "setURI", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "bytes4", - name: "interfaceId", - type: "bytes4" - }, - ], - name: "supportsInterface", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [], - name: "symbol", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "tokenURI", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "transferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "newOwner", - type: "address" - }, - ], - name: "transferOwnership", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - { - internalType: "bytes", - name: "cid", - type: "bytes" - }, - ], - name: "updateMetadata", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, -]; -var _bytecode = "0x60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d3565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000127565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff161015620000ed5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e4919062000149565b60405180910390a15b565b6000620000fe60278362000166565b91506200010b8262000184565b604082019050919050565b620001218162000177565b82525050565b600060208201905081810360008301526200014281620000ef565b9050919050565b600060208201905062000160600083018462000116565b92915050565b600082825260208201905092915050565b600060ff82169050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b613b3580620001e36000396000f3fe6080604052600436106101815760003560e01c80638da5cb5b116100d1578063b88d4fde1161008a578063db7fd40811610064578063db7fd40814610581578063e985e9c5146105aa578063f2fde38b146105e7578063ffe77b0f1461061057610181565b8063b88d4fde146104ff578063c87b56dd14610528578063c88efd151461056557610181565b80638da5cb5b1461040557806395d89b41146104305780639a7fad401461045b578063a22cb46514610484578063a91ee0dc146104ad578063af3ba9c1146104d657610181565b806323b872dd1161013e5780634f558e79116101185780634f558e79146103375780636352211e1461037457806370a08231146103b1578063715018a6146103ee57610181565b806323b872dd146102ba5780633dcd3236146102e357806342842e0e1461030e57610181565b806301ffc9a71461018657806302fe5305146101c357806306fdde03146101ec578063081812fc14610217578063095ea7b31461025457806313859f461461027d575b600080fd5b34801561019257600080fd5b506101ad60048036038101906101a891906128b6565b610639565b6040516101ba9190612f22565b60405180910390f35b3480156101cf57600080fd5b506101ea60048036038101906101e59190612908565b61071b565b005b3480156101f857600080fd5b5061020161073d565b60405161020e9190612fa3565b60405180910390f35b34801561022357600080fd5b5061023e600480360381019061023991906129b5565b6107cf565b60405161024b9190612ebb565b60405180910390f35b34801561026057600080fd5b5061027b6004803603810190610276919061287a565b610815565b005b34801561028957600080fd5b506102a4600480360381019061029f91906129b5565b61092d565b6040516102b19190612f66565b60405180910390f35b3480156102c657600080fd5b506102e160048036038101906102dc9190612774565b6109cd565b005b3480156102ef57600080fd5b506102f8610a2d565b6040516103059190612ebb565b60405180910390f35b34801561031a57600080fd5b5061033560048036038101906103309190612774565b610a53565b005b34801561034357600080fd5b5061035e600480360381019061035991906129b5565b610a73565b60405161036b9190612f22565b60405180910390f35b34801561038057600080fd5b5061039b600480360381019061039691906129b5565b610a85565b6040516103a89190612ebb565b60405180910390f35b3480156103bd57600080fd5b506103d860048036038101906103d3919061270f565b610b37565b6040516103e59190613205565b60405180910390f35b3480156103fa57600080fd5b50610403610bef565b005b34801561041157600080fd5b5061041a610c03565b6040516104279190612ebb565b60405180910390f35b34801561043c57600080fd5b50610445610c2d565b6040516104529190612fa3565b60405180910390f35b34801561046757600080fd5b50610482600480360381019061047d9190612adf565b610cbf565b005b34801561049057600080fd5b506104ab60048036038101906104a6919061283e565b610ddd565b005b3480156104b957600080fd5b506104d460048036038101906104cf919061270f565b610df3565b005b3480156104e257600080fd5b506104fd60048036038101906104f89190612949565b610e3f565b005b34801561050b57600080fd5b50610526600480360381019061052191906127c3565b610e9c565b005b34801561053457600080fd5b5061054f600480360381019061054a91906129b5565b610efe565b60405161055c9190612fa3565b60405180910390f35b61057f600480360381019061057a9190612a5f565b610f66565b005b34801561058d57600080fd5b506105a860048036038101906105a39190612a07565b611075565b005b3480156105b657600080fd5b506105d160048036038101906105cc9190612738565b6110e5565b6040516105de9190612f22565b60405180910390f35b3480156105f357600080fd5b5061060e6004803603810190610609919061270f565b611179565b005b34801561061c57600080fd5b506106376004803603810190610632919061270f565b6111fd565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061070457507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806107145750610713826113f1565b5b9050919050565b61072361145b565b8060ca9080519060200190610739929190612439565b5050565b60606065805461074c90613484565b80601f016020809104026020016040519081016040528092919081815260200182805461077890613484565b80156107c55780601f1061079a576101008083540402835291602001916107c5565b820191906000526020600020905b8154815290600101906020018083116107a857829003601f168201915b5050505050905090565b60006107da826114d9565b6069600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061082082610a85565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610891576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610888906131a5565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166108b0611524565b73ffffffffffffffffffffffffffffffffffffffff1614806108df57506108de816108d9611524565b6110e5565b5b61091e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091590613105565b60405180910390fd5b610928838361152c565b505050565b6097602052806000526040600020600091509050805461094c90613484565b80601f016020809104026020016040519081016040528092919081815260200182805461097890613484565b80156109c55780601f1061099a576101008083540402835291602001916109c5565b820191906000526020600020905b8154815290600101906020018083116109a857829003601f168201915b505050505081565b6109de6109d8611524565b826115e5565b610a1d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a14906131e5565b60405180910390fd5b610a2883838361167a565b505050565b60cb60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610a6e83838360405180602001604052806000815250610e9c565b505050565b6000610a7e826118e1565b9050919050565b6000806067600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610b2e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b2590613185565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610ba8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b9f906130c5565b60405180910390fd5b606860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b610bf761145b565b610c01600061194d565b565b6000609860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060668054610c3c90613484565b80601f0160208091040260200160405190810160405280929190818152602001828054610c6890613484565b8015610cb55780601f10610c8a57610100808354040283529160200191610cb5565b820191906000526020600020905b815481529060010190602001808311610c9857829003601f168201915b5050505050905090565b816000610cca611524565b905060008173ffffffffffffffffffffffffffffffffffffffff16610cee84610a85565b73ffffffffffffffffffffffffffffffffffffffff161480610d165750610d1582846115e5565b5b905080610d58576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d4f90613145565b60405180910390fd5b83609760008781526020019081526020016000209080519060200190610d7f9291906124bf565b5084610d89611524565b73ffffffffffffffffffffffffffffffffffffffff167fabddf73bfc8efbf8287a09ea355e43cf6c0c22880ce0470affeba5271c0a769486604051610dce9190612f66565b60405180910390a35050505050565b610def610de8611524565b8383611a13565b5050565b610dfb61145b565b8060cb60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600060019054906101000a900460ff16610e8e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e85906131c5565b60405180910390fd5b610e988282611b80565b5050565b610ead610ea7611524565b836115e5565b610eec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ee3906131e5565b60405180910390fd5b610ef884848484611bdd565b50505050565b6060610f09826114d9565b6000610f13611c39565b90506000815111610f335760405180602001604052806000815250610f5e565b80610f3d84611ccb565b604051602001610f4e929190612e97565b6040516020818303038152906040525b915050919050565b600060cb60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008173ffffffffffffffffffffffffffffffffffffffff1663da4a984234868a6040518463ffffffff1660e01b8152600401610fcb929190612f3d565b6020604051808303818588803b158015610fe457600080fd5b505af1158015610ff8573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061101d91906129de565b9050808314611061576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105890613045565b60405180910390fd5b61106c878787611075565b50505050505050565b600061107f611524565b905060008490506110908282611e78565b6110de8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610cbf565b5050505050565b6000606a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61118161145b565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156111f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111e890612fe5565b60405180910390fd5b6111fa8161194d565b50565b60008060019054906101000a900460ff1615905080801561122e5750600160008054906101000a900460ff1660ff16105b8061125b575061123d30611e96565b15801561125a5750600160008054906101000a900460ff1660ff16145b5b61129a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611291906130e5565b60405180910390fd5b60016000806101000a81548160ff021916908360ff16021790555080156112d7576001600060016101000a81548160ff0219169083151502179055505b61134b6040518060400160405280601581526020017f4465536369205265736561726368204f626a65637400000000000000000000008152506040518060400160405280600a81526020017f44655363692d4e6f646500000000000000000000000000000000000000000000815250610e3f565b611353611eb9565b8160cb60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080156113ed5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516113e49190612f88565b60405180910390a15b5050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b611463611524565b73ffffffffffffffffffffffffffffffffffffffff16611481610c03565b73ffffffffffffffffffffffffffffffffffffffff16146114d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114ce90613165565b60405180910390fd5b565b6114e2816118e1565b611521576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161151890613185565b60405180910390fd5b50565b600033905090565b816069600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff1661159f83610a85565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000806115f183610a85565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611633575061163281856110e5565b5b8061167157508373ffffffffffffffffffffffffffffffffffffffff16611659846107cf565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661169a82610a85565b73ffffffffffffffffffffffffffffffffffffffff16146116f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116e790613005565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611760576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161175790613065565b60405180910390fd5b61176b838383611f12565b61177660008261152c565b6001606860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546117c69190613371565b925050819055506001606860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461181d91906132ea565b92505081905550816067600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46118dc838383611f86565b505050565b60008073ffffffffffffffffffffffffffffffffffffffff166067600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6000609860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081609860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611a82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a7990613085565b60405180910390fd5b80606a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611b739190612f22565b60405180910390a3505050565b600060019054906101000a900460ff16611bcf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bc6906131c5565b60405180910390fd5b611bd98282611f8b565b5050565b611be884848461167a565b611bf48484848461200c565b611c33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c2a90612fc5565b60405180910390fd5b50505050565b606060ca8054611c4890613484565b80601f0160208091040260200160405190810160405280929190818152602001828054611c7490613484565b8015611cc15780601f10611c9657610100808354040283529160200191611cc1565b820191906000526020600020905b815481529060010190602001808311611ca457829003601f168201915b5050505050905090565b60606000821415611d13576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050611e73565b600082905060005b60008214611d45578080611d2e906134e7565b915050600a82611d3e9190613340565b9150611d1b565b60008167ffffffffffffffff811115611d87577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611db95781602001600182028036833780820191505090505b5090505b60008514611e6c57600182611dd29190613371565b9150600a85611de19190613530565b6030611ded91906132ea565b60f81b818381518110611e29577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85611e659190613340565b9450611dbd565b8093505050505b919050565b611e928282604051806020016040528060008152506121a3565b5050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16611f08576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eff906131c5565b60405180910390fd5b611f106121fe565b565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614611f81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f78906130a5565b60405180910390fd5b505050565b505050565b600060019054906101000a900460ff16611fda576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fd1906131c5565b60405180910390fd5b8160659080519060200190611ff0929190612439565b508060669080519060200190612007929190612439565b505050565b600061202d8473ffffffffffffffffffffffffffffffffffffffff16611e96565b15612196578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612056611524565b8786866040518563ffffffff1660e01b81526004016120789493929190612ed6565b602060405180830381600087803b15801561209257600080fd5b505af19250505080156120c357506040513d601f19601f820116820180604052508101906120c091906128df565b60015b612146573d80600081146120f3576040519150601f19603f3d011682016040523d82523d6000602084013e6120f8565b606091505b5060008151141561213e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161213590612fc5565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061219b565b600190505b949350505050565b6121ad838361225f565b6121ba600084848461200c565b6121f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121f090612fc5565b60405180910390fd5b505050565b600060019054906101000a900460ff1661224d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612244906131c5565b60405180910390fd5b61225d612258611524565b61194d565b565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156122cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c690613125565b60405180910390fd5b6122d8816118e1565b15612318576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161230f90613025565b60405180910390fd5b61232460008383611f12565b6001606860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461237491906132ea565b92505081905550816067600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461243560008383611f86565b5050565b82805461244590613484565b90600052602060002090601f01602090048101928261246757600085556124ae565b82601f1061248057805160ff19168380011785556124ae565b828001600101855582156124ae579182015b828111156124ad578251825591602001919060010190612492565b5b5090506124bb9190612545565b5090565b8280546124cb90613484565b90600052602060002090601f0160209004810192826124ed5760008555612534565b82601f1061250657805160ff1916838001178555612534565b82800160010185558215612534579182015b82811115612533578251825591602001919060010190612518565b5b5090506125419190612545565b5090565b5b8082111561255e576000816000905550600101612546565b5090565b600061257561257084613245565b613220565b90508281526020810184848401111561258d57600080fd5b612598848285613442565b509392505050565b60006125b36125ae84613276565b613220565b9050828152602081018484840111156125cb57600080fd5b6125d6848285613442565b509392505050565b6000813590506125ed81613a8c565b92915050565b60008135905061260281613aa3565b92915050565b60008135905061261781613aba565b92915050565b60008135905061262c81613ad1565b92915050565b60008151905061264181613ad1565b92915050565b60008083601f84011261265957600080fd5b8235905067ffffffffffffffff81111561267257600080fd5b60208301915083600182028301111561268a57600080fd5b9250929050565b600082601f8301126126a257600080fd5b81356126b2848260208601612562565b91505092915050565b600082601f8301126126cc57600080fd5b81356126dc8482602086016125a0565b91505092915050565b6000813590506126f481613ae8565b92915050565b60008151905061270981613ae8565b92915050565b60006020828403121561272157600080fd5b600061272f848285016125de565b91505092915050565b6000806040838503121561274b57600080fd5b6000612759858286016125de565b925050602061276a858286016125de565b9150509250929050565b60008060006060848603121561278957600080fd5b6000612797868287016125de565b93505060206127a8868287016125de565b92505060406127b9868287016126e5565b9150509250925092565b600080600080608085870312156127d957600080fd5b60006127e7878288016125de565b94505060206127f8878288016125de565b9350506040612809878288016126e5565b925050606085013567ffffffffffffffff81111561282657600080fd5b61283287828801612691565b91505092959194509250565b6000806040838503121561285157600080fd5b600061285f858286016125de565b9250506020612870858286016125f3565b9150509250929050565b6000806040838503121561288d57600080fd5b600061289b858286016125de565b92505060206128ac858286016126e5565b9150509250929050565b6000602082840312156128c857600080fd5b60006128d68482850161261d565b91505092915050565b6000602082840312156128f157600080fd5b60006128ff84828501612632565b91505092915050565b60006020828403121561291a57600080fd5b600082013567ffffffffffffffff81111561293457600080fd5b612940848285016126bb565b91505092915050565b6000806040838503121561295c57600080fd5b600083013567ffffffffffffffff81111561297657600080fd5b612982858286016126bb565b925050602083013567ffffffffffffffff81111561299f57600080fd5b6129ab858286016126bb565b9150509250929050565b6000602082840312156129c757600080fd5b60006129d5848285016126e5565b91505092915050565b6000602082840312156129f057600080fd5b60006129fe848285016126fa565b91505092915050565b600080600060408486031215612a1c57600080fd5b6000612a2a868287016126e5565b935050602084013567ffffffffffffffff811115612a4757600080fd5b612a5386828701612647565b92509250509250925092565b600080600080600060808688031215612a7757600080fd5b6000612a85888289016126e5565b955050602086013567ffffffffffffffff811115612aa257600080fd5b612aae88828901612647565b94509450506040612ac188828901612608565b9250506060612ad2888289016126e5565b9150509295509295909350565b60008060408385031215612af257600080fd5b6000612b00858286016126e5565b925050602083013567ffffffffffffffff811115612b1d57600080fd5b612b2985828601612691565b9150509250929050565b612b3c816133a5565b82525050565b612b4b816133b7565b82525050565b612b5a816133c3565b82525050565b6000612b6b826132a7565b612b7581856132bd565b9350612b85818560208601613451565b612b8e8161361d565b840191505092915050565b612ba281613430565b82525050565b6000612bb3826132b2565b612bbd81856132ce565b9350612bcd818560208601613451565b612bd68161361d565b840191505092915050565b6000612bec826132b2565b612bf681856132df565b9350612c06818560208601613451565b80840191505092915050565b6000612c1f6032836132ce565b9150612c2a8261362e565b604082019050919050565b6000612c426026836132ce565b9150612c4d8261367d565b604082019050919050565b6000612c656025836132ce565b9150612c70826136cc565b604082019050919050565b6000612c88601c836132ce565b9150612c938261371b565b602082019050919050565b6000612cab600f836132ce565b9150612cb682613744565b602082019050919050565b6000612cce6024836132ce565b9150612cd98261376d565b604082019050919050565b6000612cf16019836132ce565b9150612cfc826137bc565b602082019050919050565b6000612d14600b836132ce565b9150612d1f826137e5565b602082019050919050565b6000612d376029836132ce565b9150612d428261380e565b604082019050919050565b6000612d5a602e836132ce565b9150612d658261385d565b604082019050919050565b6000612d7d603e836132ce565b9150612d88826138ac565b604082019050919050565b6000612da06020836132ce565b9150612dab826138fb565b602082019050919050565b6000612dc3600d836132ce565b9150612dce82613924565b602082019050919050565b6000612de66020836132ce565b9150612df18261394d565b602082019050919050565b6000612e096018836132ce565b9150612e1482613976565b602082019050919050565b6000612e2c6021836132ce565b9150612e378261399f565b604082019050919050565b6000612e4f602b836132ce565b9150612e5a826139ee565b604082019050919050565b6000612e72602e836132ce565b9150612e7d82613a3d565b604082019050919050565b612e9181613419565b82525050565b6000612ea38285612be1565b9150612eaf8284612be1565b91508190509392505050565b6000602082019050612ed06000830184612b33565b92915050565b6000608082019050612eeb6000830187612b33565b612ef86020830186612b33565b612f056040830185612e88565b8181036060830152612f178184612b60565b905095945050505050565b6000602082019050612f376000830184612b42565b92915050565b6000604082019050612f526000830185612b51565b612f5f6020830184612e88565b9392505050565b60006020820190508181036000830152612f808184612b60565b905092915050565b6000602082019050612f9d6000830184612b99565b92915050565b60006020820190508181036000830152612fbd8184612ba8565b905092915050565b60006020820190508181036000830152612fde81612c12565b9050919050565b60006020820190508181036000830152612ffe81612c35565b9050919050565b6000602082019050818103600083015261301e81612c58565b9050919050565b6000602082019050818103600083015261303e81612c7b565b9050919050565b6000602082019050818103600083015261305e81612c9e565b9050919050565b6000602082019050818103600083015261307e81612cc1565b9050919050565b6000602082019050818103600083015261309e81612ce4565b9050919050565b600060208201905081810360008301526130be81612d07565b9050919050565b600060208201905081810360008301526130de81612d2a565b9050919050565b600060208201905081810360008301526130fe81612d4d565b9050919050565b6000602082019050818103600083015261311e81612d70565b9050919050565b6000602082019050818103600083015261313e81612d93565b9050919050565b6000602082019050818103600083015261315e81612db6565b9050919050565b6000602082019050818103600083015261317e81612dd9565b9050919050565b6000602082019050818103600083015261319e81612dfc565b9050919050565b600060208201905081810360008301526131be81612e1f565b9050919050565b600060208201905081810360008301526131de81612e42565b9050919050565b600060208201905081810360008301526131fe81612e65565b9050919050565b600060208201905061321a6000830184612e88565b92915050565b600061322a61323b565b905061323682826134b6565b919050565b6000604051905090565b600067ffffffffffffffff8211156132605761325f6135ee565b5b6132698261361d565b9050602081019050919050565b600067ffffffffffffffff821115613291576132906135ee565b5b61329a8261361d565b9050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b60006132f582613419565b915061330083613419565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561333557613334613561565b5b828201905092915050565b600061334b82613419565b915061335683613419565b92508261336657613365613590565b5b828204905092915050565b600061337c82613419565b915061338783613419565b92508282101561339a57613399613561565b5b828203905092915050565b60006133b0826133f9565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b600061343b82613423565b9050919050565b82818337600083830152505050565b60005b8381101561346f578082015181840152602081019050613454565b8381111561347e576000848401525b50505050565b6000600282049050600182168061349c57607f821691505b602082108114156134b0576134af6135bf565b5b50919050565b6134bf8261361d565b810181811067ffffffffffffffff821117156134de576134dd6135ee565b5b80604052505050565b60006134f282613419565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561352557613524613561565b5b600182019050919050565b600061353b82613419565b915061354683613419565b92508261355657613555613590565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f556e657870656374656420645049440000000000000000000000000000000000600082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f6e6f207472616e73666572000000000000000000000000000000000000000000600082015250565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f4e6f207065726d697373696f6e00000000000000000000000000000000000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b613a95816133a5565b8114613aa057600080fd5b50565b613aac816133b7565b8114613ab757600080fd5b50565b613ac3816133c3565b8114613ace57600080fd5b50565b613ada816133cd565b8114613ae557600080fd5b50565b613af181613419565b8114613afc57600080fd5b5056fea2646970667358221220448f67f11695953978b8db1358e26068f93ba3d14c1086e8e7334058afa9d92664736f6c63430008040033"; -var isSuperArgs = function (xs) { return xs.length > 1; }; -var ResearchObjectV2__factory = /** @class */ (function (_super) { - __extends(ResearchObjectV2__factory, _super); - function ResearchObjectV2__factory() { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - var _this = this; - if (isSuperArgs(args)) { - _this = _super.apply(this, args) || this; - } - else { - _this = _super.call(this, _abi, _bytecode, args[0]) || this; - } - _this.contractName = "ResearchObjectV2"; - return _this; - } - ResearchObjectV2__factory.prototype.deploy = function (overrides) { - return _super.prototype.deploy.call(this, overrides || {}); - }; - ResearchObjectV2__factory.prototype.getDeployTransaction = function (overrides) { - return _super.prototype.getDeployTransaction.call(this, overrides || {}); - }; - ResearchObjectV2__factory.prototype.attach = function (address) { - return _super.prototype.attach.call(this, address); - }; - ResearchObjectV2__factory.prototype.connect = function (signer) { - return _super.prototype.connect.call(this, signer); - }; - ResearchObjectV2__factory.createInterface = function () { - return new ethers_1.utils.Interface(_abi); - }; - ResearchObjectV2__factory.connect = function (address, signerOrProvider) { - return new ethers_1.Contract(address, _abi, signerOrProvider); - }; - ResearchObjectV2__factory.bytecode = _bytecode; - ResearchObjectV2__factory.abi = _abi; - return ResearchObjectV2__factory; -}(ethers_1.ContractFactory)); -exports.ResearchObjectV2__factory = ResearchObjectV2__factory; diff --git a/desci-contracts/typechain-types/factories/ResearchObject__factory.js b/desci-contracts/typechain-types/factories/ResearchObject__factory.js deleted file mode 100644 index 36bd9bcb..00000000 --- a/desci-contracts/typechain-types/factories/ResearchObject__factory.js +++ /dev/null @@ -1,663 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - if (typeof b !== "function" && b !== null) - throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -exports.__esModule = true; -exports.ResearchObject__factory = void 0; -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -var ethers_1 = require("ethers"); -var _abi = [ - { - inputs: [], - stateMutability: "nonpayable", - type: "constructor" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "owner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "approved", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "Approval", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "owner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "operator", - type: "address" - }, - { - indexed: false, - internalType: "bool", - name: "approved", - type: "bool" - }, - ], - name: "ApprovalForAll", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "uint8", - name: "version", - type: "uint8" - }, - ], - name: "Initialized", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "previousOwner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "newOwner", - type: "address" - }, - ], - name: "OwnershipTransferred", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "from", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "to", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "Transfer", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "_from", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "_uuid", - type: "uint256" - }, - { - indexed: false, - internalType: "bytes", - name: "_cid", - type: "bytes" - }, - ], - name: "VersionPush", - type: "event" - }, - { - inputs: [ - { - internalType: "string", - name: "name", - type: "string" - }, - { - internalType: "string", - name: "symbol", - type: "string" - }, - ], - name: "__VersionedERC721_init", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [], - name: "_dpidRegistry", - outputs: [ - { - internalType: "address", - name: "", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "", - type: "uint256" - }, - ], - name: "_metadata", - outputs: [ - { - internalType: "bytes", - name: "", - type: "bytes" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "approve", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - ], - name: "balanceOf", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "exists", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "getApproved", - outputs: [ - { - internalType: "address", - name: "", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "dpidRegistry", - type: "address" - }, - ], - name: "initialize", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - { - internalType: "address", - name: "operator", - type: "address" - }, - ], - name: "isApprovedForAll", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "uuid", - type: "uint256" - }, - { - internalType: "bytes", - name: "cid", - type: "bytes" - }, - ], - name: "mint", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "uuid", - type: "uint256" - }, - { - internalType: "bytes", - name: "cid", - type: "bytes" - }, - { - internalType: "bytes32", - name: "prefix", - type: "bytes32" - }, - { - internalType: "uint256", - name: "expectedDpid", - type: "uint256" - }, - ], - name: "mintWithDpid", - outputs: [], - stateMutability: "payable", - type: "function" - }, - { - inputs: [], - name: "name", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [], - name: "owner", - outputs: [ - { - internalType: "address", - name: "", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "ownerOf", - outputs: [ - { - internalType: "address", - name: "", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [], - name: "renounceOwnership", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "safeTransferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - { - internalType: "bytes", - name: "data", - type: "bytes" - }, - ], - name: "safeTransferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "operator", - type: "address" - }, - { - internalType: "bool", - name: "approved", - type: "bool" - }, - ], - name: "setApprovalForAll", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "dpidRegistry", - type: "address" - }, - ], - name: "setRegistry", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "string", - name: "uri", - type: "string" - }, - ], - name: "setURI", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "bytes4", - name: "interfaceId", - type: "bytes4" - }, - ], - name: "supportsInterface", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [], - name: "symbol", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "tokenURI", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "transferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "newOwner", - type: "address" - }, - ], - name: "transferOwnership", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - { - internalType: "bytes", - name: "cid", - type: "bytes" - }, - ], - name: "updateMetadata", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, -]; -var _bytecode = "0x60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d3565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000127565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff161015620000ed5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e4919062000149565b60405180910390a15b565b6000620000fe60278362000166565b91506200010b8262000184565b604082019050919050565b620001218162000177565b82525050565b600060208201905081810360008301526200014281620000ef565b9050919050565b600060208201905062000160600083018462000116565b92915050565b600082825260208201905092915050565b600060ff82169050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b613b2480620001e36000396000f3fe6080604052600436106101815760003560e01c8063715018a6116100d1578063b88d4fde1161008a578063c88efd1511610064578063c88efd151461058e578063db7fd408146105aa578063e985e9c5146105d3578063f2fde38b1461061057610181565b8063b88d4fde146104ff578063c4d66de814610528578063c87b56dd1461055157610181565b8063715018a6146104175780638da5cb5b1461042e57806395d89b41146104595780639a7fad4014610484578063a22cb465146104ad578063a91ee0dc146104d657610181565b806323b872dd1161013e5780634f558e79116101185780634f558e7914610337578063599ad936146103745780636352211e1461039d57806370a08231146103da57610181565b806323b872dd146102ba5780633dcd3236146102e357806342842e0e1461030e57610181565b806301ffc9a71461018657806302fe5305146101c357806306fdde03146101ec578063081812fc14610217578063095ea7b31461025457806313859f461461027d575b600080fd5b34801561019257600080fd5b506101ad60048036038101906101a891906128a5565b610639565b6040516101ba9190612f11565b60405180910390f35b3480156101cf57600080fd5b506101ea60048036038101906101e591906128f7565b61071b565b005b3480156101f857600080fd5b5061020161073d565b60405161020e9190612f92565b60405180910390f35b34801561022357600080fd5b5061023e600480360381019061023991906129a4565b6107cf565b60405161024b9190612eaa565b60405180910390f35b34801561026057600080fd5b5061027b60048036038101906102769190612869565b610815565b005b34801561028957600080fd5b506102a4600480360381019061029f91906129a4565b61092d565b6040516102b19190612f55565b60405180910390f35b3480156102c657600080fd5b506102e160048036038101906102dc9190612763565b6109cd565b005b3480156102ef57600080fd5b506102f8610a2d565b6040516103059190612eaa565b60405180910390f35b34801561031a57600080fd5b5061033560048036038101906103309190612763565b610a53565b005b34801561034357600080fd5b5061035e600480360381019061035991906129a4565b610a73565b60405161036b9190612f11565b60405180910390f35b34801561038057600080fd5b5061039b60048036038101906103969190612938565b610a85565b005b3480156103a957600080fd5b506103c460048036038101906103bf91906129a4565b610ae2565b6040516103d19190612eaa565b60405180910390f35b3480156103e657600080fd5b5061040160048036038101906103fc91906126fe565b610b94565b60405161040e91906131f4565b60405180910390f35b34801561042357600080fd5b5061042c610c4c565b005b34801561043a57600080fd5b50610443610c60565b6040516104509190612eaa565b60405180910390f35b34801561046557600080fd5b5061046e610c8a565b60405161047b9190612f92565b60405180910390f35b34801561049057600080fd5b506104ab60048036038101906104a69190612ace565b610d1c565b005b3480156104b957600080fd5b506104d460048036038101906104cf919061282d565b610e29565b005b3480156104e257600080fd5b506104fd60048036038101906104f891906126fe565b610e3f565b005b34801561050b57600080fd5b50610526600480360381019061052191906127b2565b610e8b565b005b34801561053457600080fd5b5061054f600480360381019061054a91906126fe565b610eed565b005b34801561055d57600080fd5b50610578600480360381019061057391906129a4565b6110e1565b6040516105859190612f92565b60405180910390f35b6105a860048036038101906105a39190612a4e565b611149565b005b3480156105b657600080fd5b506105d160048036038101906105cc91906129f6565b611258565b005b3480156105df57600080fd5b506105fa60048036038101906105f59190612727565b6112c8565b6040516106079190612f11565b60405180910390f35b34801561061c57600080fd5b50610637600480360381019061063291906126fe565b61135c565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061070457507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806107145750610713826113e0565b5b9050919050565b61072361144a565b8060ca9080519060200190610739929190612428565b5050565b60606065805461074c90613473565b80601f016020809104026020016040519081016040528092919081815260200182805461077890613473565b80156107c55780601f1061079a576101008083540402835291602001916107c5565b820191906000526020600020905b8154815290600101906020018083116107a857829003601f168201915b5050505050905090565b60006107da826114c8565b6069600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061082082610ae2565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610891576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161088890613194565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166108b0611513565b73ffffffffffffffffffffffffffffffffffffffff1614806108df57506108de816108d9611513565b6112c8565b5b61091e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610915906130f4565b60405180910390fd5b610928838361151b565b505050565b6097602052806000526040600020600091509050805461094c90613473565b80601f016020809104026020016040519081016040528092919081815260200182805461097890613473565b80156109c55780601f1061099a576101008083540402835291602001916109c5565b820191906000526020600020905b8154815290600101906020018083116109a857829003601f168201915b505050505081565b6109de6109d8611513565b826115d4565b610a1d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a14906131d4565b60405180910390fd5b610a28838383611669565b505050565b60cb60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610a6e83838360405180602001604052806000815250610e8b565b505050565b6000610a7e826118d0565b9050919050565b600060019054906101000a900460ff16610ad4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610acb906131b4565b60405180910390fd5b610ade828261193c565b5050565b6000806067600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610b8b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b8290613174565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610c05576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bfc906130b4565b60405180910390fd5b606860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b610c5461144a565b610c5e6000611999565b565b6000609860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060668054610c9990613473565b80601f0160208091040260200160405190810160405280929190818152602001828054610cc590613473565b8015610d125780601f10610ce757610100808354040283529160200191610d12565b820191906000526020600020905b815481529060010190602001808311610cf557829003601f168201915b5050505050905090565b816000610d27611513565b905060008173ffffffffffffffffffffffffffffffffffffffff16610d4b84610ae2565b73ffffffffffffffffffffffffffffffffffffffff1614905080610da4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d9b90613134565b60405180910390fd5b83609760008781526020019081526020016000209080519060200190610dcb9291906124ae565b5084610dd5611513565b73ffffffffffffffffffffffffffffffffffffffff167fabddf73bfc8efbf8287a09ea355e43cf6c0c22880ce0470affeba5271c0a769486604051610e1a9190612f55565b60405180910390a35050505050565b610e3b610e34611513565b8383611a5f565b5050565b610e4761144a565b8060cb60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b610e9c610e96611513565b836115d4565b610edb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed2906131d4565b60405180910390fd5b610ee784848484611bcc565b50505050565b60008060019054906101000a900460ff16159050808015610f1e5750600160008054906101000a900460ff1660ff16105b80610f4b5750610f2d30611c28565b158015610f4a5750600160008054906101000a900460ff1660ff16145b5b610f8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f81906130d4565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015610fc7576001600060016101000a81548160ff0219169083151502179055505b61103b6040518060400160405280601581526020017f4465536369205265736561726368204f626a65637400000000000000000000008152506040518060400160405280600a81526020017f44655363692d4e6f646500000000000000000000000000000000000000000000815250610a85565b611043611c4b565b8160cb60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080156110dd5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516110d49190612f77565b60405180910390a15b5050565b60606110ec826114c8565b60006110f6611ca4565b905060008151116111165760405180602001604052806000815250611141565b8061112084611d36565b604051602001611131929190612e86565b6040516020818303038152906040525b915050919050565b600060cb60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008173ffffffffffffffffffffffffffffffffffffffff1663da4a984234868a6040518463ffffffff1660e01b81526004016111ae929190612f2c565b6020604051808303818588803b1580156111c757600080fd5b505af11580156111db573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061120091906129cd565b9050808314611244576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161123b90613034565b60405180910390fd5b61124f878787611258565b50505050505050565b6000611262611513565b905060008490506112738282611ee3565b6112c18585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610d1c565b5050505050565b6000606a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61136461144a565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156113d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113cb90612fd4565b60405180910390fd5b6113dd81611999565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b611452611513565b73ffffffffffffffffffffffffffffffffffffffff16611470610c60565b73ffffffffffffffffffffffffffffffffffffffff16146114c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114bd90613154565b60405180910390fd5b565b6114d1816118d0565b611510576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161150790613174565b60405180910390fd5b50565b600033905090565b816069600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff1661158e83610ae2565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000806115e083610ae2565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611622575061162181856112c8565b5b8061166057508373ffffffffffffffffffffffffffffffffffffffff16611648846107cf565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661168982610ae2565b73ffffffffffffffffffffffffffffffffffffffff16146116df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116d690612ff4565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561174f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161174690613054565b60405180910390fd5b61175a838383611f01565b61176560008261151b565b6001606860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546117b59190613360565b925050819055506001606860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461180c91906132d9565b92505081905550816067600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46118cb838383611f75565b505050565b60008073ffffffffffffffffffffffffffffffffffffffff166067600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600060019054906101000a900460ff1661198b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611982906131b4565b60405180910390fd5b6119958282611f7a565b5050565b6000609860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081609860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611ace576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac590613074565b60405180910390fd5b80606a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611bbf9190612f11565b60405180910390a3505050565b611bd7848484611669565b611be384848484611ffb565b611c22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c1990612fb4565b60405180910390fd5b50505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16611c9a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c91906131b4565b60405180910390fd5b611ca2612192565b565b606060ca8054611cb390613473565b80601f0160208091040260200160405190810160405280929190818152602001828054611cdf90613473565b8015611d2c5780601f10611d0157610100808354040283529160200191611d2c565b820191906000526020600020905b815481529060010190602001808311611d0f57829003601f168201915b5050505050905090565b60606000821415611d7e576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050611ede565b600082905060005b60008214611db0578080611d99906134d6565b915050600a82611da9919061332f565b9150611d86565b60008167ffffffffffffffff811115611df2577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611e245781602001600182028036833780820191505090505b5090505b60008514611ed757600182611e3d9190613360565b9150600a85611e4c919061351f565b6030611e5891906132d9565b60f81b818381518110611e94577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85611ed0919061332f565b9450611e28565b8093505050505b919050565b611efd8282604051806020016040528060008152506121f3565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614611f70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6790613094565b60405180910390fd5b505050565b505050565b600060019054906101000a900460ff16611fc9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fc0906131b4565b60405180910390fd5b8160659080519060200190611fdf929190612428565b508060669080519060200190611ff6929190612428565b505050565b600061201c8473ffffffffffffffffffffffffffffffffffffffff16611c28565b15612185578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612045611513565b8786866040518563ffffffff1660e01b81526004016120679493929190612ec5565b602060405180830381600087803b15801561208157600080fd5b505af19250505080156120b257506040513d601f19601f820116820180604052508101906120af91906128ce565b60015b612135573d80600081146120e2576040519150601f19603f3d011682016040523d82523d6000602084013e6120e7565b606091505b5060008151141561212d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161212490612fb4565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061218a565b600190505b949350505050565b600060019054906101000a900460ff166121e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121d8906131b4565b60405180910390fd5b6121f16121ec611513565b611999565b565b6121fd838361224e565b61220a6000848484611ffb565b612249576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161224090612fb4565b60405180910390fd5b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156122be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b590613114565b60405180910390fd5b6122c7816118d0565b15612307576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122fe90613014565b60405180910390fd5b61231360008383611f01565b6001606860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461236391906132d9565b92505081905550816067600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461242460008383611f75565b5050565b82805461243490613473565b90600052602060002090601f016020900481019282612456576000855561249d565b82601f1061246f57805160ff191683800117855561249d565b8280016001018555821561249d579182015b8281111561249c578251825591602001919060010190612481565b5b5090506124aa9190612534565b5090565b8280546124ba90613473565b90600052602060002090601f0160209004810192826124dc5760008555612523565b82601f106124f557805160ff1916838001178555612523565b82800160010185558215612523579182015b82811115612522578251825591602001919060010190612507565b5b5090506125309190612534565b5090565b5b8082111561254d576000816000905550600101612535565b5090565b600061256461255f84613234565b61320f565b90508281526020810184848401111561257c57600080fd5b612587848285613431565b509392505050565b60006125a261259d84613265565b61320f565b9050828152602081018484840111156125ba57600080fd5b6125c5848285613431565b509392505050565b6000813590506125dc81613a7b565b92915050565b6000813590506125f181613a92565b92915050565b60008135905061260681613aa9565b92915050565b60008135905061261b81613ac0565b92915050565b60008151905061263081613ac0565b92915050565b60008083601f84011261264857600080fd5b8235905067ffffffffffffffff81111561266157600080fd5b60208301915083600182028301111561267957600080fd5b9250929050565b600082601f83011261269157600080fd5b81356126a1848260208601612551565b91505092915050565b600082601f8301126126bb57600080fd5b81356126cb84826020860161258f565b91505092915050565b6000813590506126e381613ad7565b92915050565b6000815190506126f881613ad7565b92915050565b60006020828403121561271057600080fd5b600061271e848285016125cd565b91505092915050565b6000806040838503121561273a57600080fd5b6000612748858286016125cd565b9250506020612759858286016125cd565b9150509250929050565b60008060006060848603121561277857600080fd5b6000612786868287016125cd565b9350506020612797868287016125cd565b92505060406127a8868287016126d4565b9150509250925092565b600080600080608085870312156127c857600080fd5b60006127d6878288016125cd565b94505060206127e7878288016125cd565b93505060406127f8878288016126d4565b925050606085013567ffffffffffffffff81111561281557600080fd5b61282187828801612680565b91505092959194509250565b6000806040838503121561284057600080fd5b600061284e858286016125cd565b925050602061285f858286016125e2565b9150509250929050565b6000806040838503121561287c57600080fd5b600061288a858286016125cd565b925050602061289b858286016126d4565b9150509250929050565b6000602082840312156128b757600080fd5b60006128c58482850161260c565b91505092915050565b6000602082840312156128e057600080fd5b60006128ee84828501612621565b91505092915050565b60006020828403121561290957600080fd5b600082013567ffffffffffffffff81111561292357600080fd5b61292f848285016126aa565b91505092915050565b6000806040838503121561294b57600080fd5b600083013567ffffffffffffffff81111561296557600080fd5b612971858286016126aa565b925050602083013567ffffffffffffffff81111561298e57600080fd5b61299a858286016126aa565b9150509250929050565b6000602082840312156129b657600080fd5b60006129c4848285016126d4565b91505092915050565b6000602082840312156129df57600080fd5b60006129ed848285016126e9565b91505092915050565b600080600060408486031215612a0b57600080fd5b6000612a19868287016126d4565b935050602084013567ffffffffffffffff811115612a3657600080fd5b612a4286828701612636565b92509250509250925092565b600080600080600060808688031215612a6657600080fd5b6000612a74888289016126d4565b955050602086013567ffffffffffffffff811115612a9157600080fd5b612a9d88828901612636565b94509450506040612ab0888289016125f7565b9250506060612ac1888289016126d4565b9150509295509295909350565b60008060408385031215612ae157600080fd5b6000612aef858286016126d4565b925050602083013567ffffffffffffffff811115612b0c57600080fd5b612b1885828601612680565b9150509250929050565b612b2b81613394565b82525050565b612b3a816133a6565b82525050565b612b49816133b2565b82525050565b6000612b5a82613296565b612b6481856132ac565b9350612b74818560208601613440565b612b7d8161360c565b840191505092915050565b612b918161341f565b82525050565b6000612ba2826132a1565b612bac81856132bd565b9350612bbc818560208601613440565b612bc58161360c565b840191505092915050565b6000612bdb826132a1565b612be581856132ce565b9350612bf5818560208601613440565b80840191505092915050565b6000612c0e6032836132bd565b9150612c198261361d565b604082019050919050565b6000612c316026836132bd565b9150612c3c8261366c565b604082019050919050565b6000612c546025836132bd565b9150612c5f826136bb565b604082019050919050565b6000612c77601c836132bd565b9150612c828261370a565b602082019050919050565b6000612c9a600f836132bd565b9150612ca582613733565b602082019050919050565b6000612cbd6024836132bd565b9150612cc88261375c565b604082019050919050565b6000612ce06019836132bd565b9150612ceb826137ab565b602082019050919050565b6000612d03600b836132bd565b9150612d0e826137d4565b602082019050919050565b6000612d266029836132bd565b9150612d31826137fd565b604082019050919050565b6000612d49602e836132bd565b9150612d548261384c565b604082019050919050565b6000612d6c603e836132bd565b9150612d778261389b565b604082019050919050565b6000612d8f6020836132bd565b9150612d9a826138ea565b602082019050919050565b6000612db2600d836132bd565b9150612dbd82613913565b602082019050919050565b6000612dd56020836132bd565b9150612de08261393c565b602082019050919050565b6000612df86018836132bd565b9150612e0382613965565b602082019050919050565b6000612e1b6021836132bd565b9150612e268261398e565b604082019050919050565b6000612e3e602b836132bd565b9150612e49826139dd565b604082019050919050565b6000612e61602e836132bd565b9150612e6c82613a2c565b604082019050919050565b612e8081613408565b82525050565b6000612e928285612bd0565b9150612e9e8284612bd0565b91508190509392505050565b6000602082019050612ebf6000830184612b22565b92915050565b6000608082019050612eda6000830187612b22565b612ee76020830186612b22565b612ef46040830185612e77565b8181036060830152612f068184612b4f565b905095945050505050565b6000602082019050612f266000830184612b31565b92915050565b6000604082019050612f416000830185612b40565b612f4e6020830184612e77565b9392505050565b60006020820190508181036000830152612f6f8184612b4f565b905092915050565b6000602082019050612f8c6000830184612b88565b92915050565b60006020820190508181036000830152612fac8184612b97565b905092915050565b60006020820190508181036000830152612fcd81612c01565b9050919050565b60006020820190508181036000830152612fed81612c24565b9050919050565b6000602082019050818103600083015261300d81612c47565b9050919050565b6000602082019050818103600083015261302d81612c6a565b9050919050565b6000602082019050818103600083015261304d81612c8d565b9050919050565b6000602082019050818103600083015261306d81612cb0565b9050919050565b6000602082019050818103600083015261308d81612cd3565b9050919050565b600060208201905081810360008301526130ad81612cf6565b9050919050565b600060208201905081810360008301526130cd81612d19565b9050919050565b600060208201905081810360008301526130ed81612d3c565b9050919050565b6000602082019050818103600083015261310d81612d5f565b9050919050565b6000602082019050818103600083015261312d81612d82565b9050919050565b6000602082019050818103600083015261314d81612da5565b9050919050565b6000602082019050818103600083015261316d81612dc8565b9050919050565b6000602082019050818103600083015261318d81612deb565b9050919050565b600060208201905081810360008301526131ad81612e0e565b9050919050565b600060208201905081810360008301526131cd81612e31565b9050919050565b600060208201905081810360008301526131ed81612e54565b9050919050565b60006020820190506132096000830184612e77565b92915050565b600061321961322a565b905061322582826134a5565b919050565b6000604051905090565b600067ffffffffffffffff82111561324f5761324e6135dd565b5b6132588261360c565b9050602081019050919050565b600067ffffffffffffffff8211156132805761327f6135dd565b5b6132898261360c565b9050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b60006132e482613408565b91506132ef83613408565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561332457613323613550565b5b828201905092915050565b600061333a82613408565b915061334583613408565b9250826133555761335461357f565b5b828204905092915050565b600061336b82613408565b915061337683613408565b92508282101561338957613388613550565b5b828203905092915050565b600061339f826133e8565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b600061342a82613412565b9050919050565b82818337600083830152505050565b60005b8381101561345e578082015181840152602081019050613443565b8381111561346d576000848401525b50505050565b6000600282049050600182168061348b57607f821691505b6020821081141561349f5761349e6135ae565b5b50919050565b6134ae8261360c565b810181811067ffffffffffffffff821117156134cd576134cc6135dd565b5b80604052505050565b60006134e182613408565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561351457613513613550565b5b600182019050919050565b600061352a82613408565b915061353583613408565b9250826135455761354461357f565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f556e657870656374656420645049440000000000000000000000000000000000600082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f6e6f207472616e73666572000000000000000000000000000000000000000000600082015250565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f4e6f207065726d697373696f6e00000000000000000000000000000000000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b613a8481613394565b8114613a8f57600080fd5b50565b613a9b816133a6565b8114613aa657600080fd5b50565b613ab2816133b2565b8114613abd57600080fd5b50565b613ac9816133bc565b8114613ad457600080fd5b50565b613ae081613408565b8114613aeb57600080fd5b5056fea2646970667358221220fd45769375da65a7b72b174103a35892b9105a217010be05d215a49590f1c9f564736f6c63430008040033"; -var isSuperArgs = function (xs) { return xs.length > 1; }; -var ResearchObject__factory = /** @class */ (function (_super) { - __extends(ResearchObject__factory, _super); - function ResearchObject__factory() { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - var _this = this; - if (isSuperArgs(args)) { - _this = _super.apply(this, args) || this; - } - else { - _this = _super.call(this, _abi, _bytecode, args[0]) || this; - } - _this.contractName = "ResearchObject"; - return _this; - } - ResearchObject__factory.prototype.deploy = function (overrides) { - return _super.prototype.deploy.call(this, overrides || {}); - }; - ResearchObject__factory.prototype.getDeployTransaction = function (overrides) { - return _super.prototype.getDeployTransaction.call(this, overrides || {}); - }; - ResearchObject__factory.prototype.attach = function (address) { - return _super.prototype.attach.call(this, address); - }; - ResearchObject__factory.prototype.connect = function (signer) { - return _super.prototype.connect.call(this, signer); - }; - ResearchObject__factory.createInterface = function () { - return new ethers_1.utils.Interface(_abi); - }; - ResearchObject__factory.connect = function (address, signerOrProvider) { - return new ethers_1.Contract(address, _abi, signerOrProvider); - }; - ResearchObject__factory.bytecode = _bytecode; - ResearchObject__factory.abi = _abi; - return ResearchObject__factory; -}(ethers_1.ContractFactory)); -exports.ResearchObject__factory = ResearchObject__factory; diff --git a/desci-contracts/typechain-types/factories/TestERC721__factory.js b/desci-contracts/typechain-types/factories/TestERC721__factory.js deleted file mode 100644 index 89d7ac74..00000000 --- a/desci-contracts/typechain-types/factories/TestERC721__factory.js +++ /dev/null @@ -1,425 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - if (typeof b !== "function" && b !== null) - throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -exports.__esModule = true; -exports.TestERC721__factory = void 0; -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -var ethers_1 = require("ethers"); -var _abi = [ - { - inputs: [ - { - internalType: "string", - name: "name", - type: "string" - }, - { - internalType: "string", - name: "symbol", - type: "string" - }, - ], - stateMutability: "nonpayable", - type: "constructor" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "owner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "approved", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "Approval", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "owner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "operator", - type: "address" - }, - { - indexed: false, - internalType: "bool", - name: "approved", - type: "bool" - }, - ], - name: "ApprovalForAll", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "from", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "to", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "Transfer", - type: "event" - }, - { - inputs: [ - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "approve", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - ], - name: "balanceOf", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "getApproved", - outputs: [ - { - internalType: "address", - name: "", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - { - internalType: "address", - name: "operator", - type: "address" - }, - ], - name: "isApprovedForAll", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "to", - type: "address" - }, - ], - name: "mint", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [], - name: "name", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "ownerOf", - outputs: [ - { - internalType: "address", - name: "", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "safeTransferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - { - internalType: "bytes", - name: "data", - type: "bytes" - }, - ], - name: "safeTransferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "operator", - type: "address" - }, - { - internalType: "bool", - name: "approved", - type: "bool" - }, - ], - name: "setApprovalForAll", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "bytes4", - name: "interfaceId", - type: "bytes4" - }, - ], - name: "supportsInterface", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [], - name: "symbol", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "tokenURI", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "transferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, -]; -var _bytecode = "0x608060405260006006553480156200001657600080fd5b5060405162002b8038038062002b8083398181016040528101906200003c91906200019c565b81818160009080519060200190620000569291906200007a565b5080600190805190602001906200006f9291906200007a565b50505050506200037f565b8280546200008890620002a4565b90600052602060002090601f016020900481019282620000ac5760008555620000f8565b82601f10620000c757805160ff1916838001178555620000f8565b82800160010185558215620000f8579182015b82811115620000f7578251825591602001919060010190620000da565b5b5090506200010791906200010b565b5090565b5b80821115620001265760008160009055506001016200010c565b5090565b6000620001416200013b8462000238565b6200020f565b9050828152602081018484840111156200015a57600080fd5b620001678482856200026e565b509392505050565b600082601f8301126200018157600080fd5b8151620001938482602086016200012a565b91505092915050565b60008060408385031215620001b057600080fd5b600083015167ffffffffffffffff811115620001cb57600080fd5b620001d9858286016200016f565b925050602083015167ffffffffffffffff811115620001f757600080fd5b62000205858286016200016f565b9150509250929050565b60006200021b6200022e565b9050620002298282620002da565b919050565b6000604051905090565b600067ffffffffffffffff8211156200025657620002556200033f565b5b62000261826200036e565b9050602081019050919050565b60005b838110156200028e57808201518184015260208101905062000271565b838111156200029e576000848401525b50505050565b60006002820490506001821680620002bd57607f821691505b60208210811415620002d457620002d362000310565b5b50919050565b620002e5826200036e565b810181811067ffffffffffffffff821117156200030757620003066200033f565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b6127f1806200038f6000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80636a6278421161008c578063a22cb46511610066578063a22cb4651461025b578063b88d4fde14610277578063c87b56dd14610293578063e985e9c5146102c3576100ea565b80636a627842146101f157806370a082311461020d57806395d89b411461023d576100ea565b8063095ea7b3116100c8578063095ea7b31461016d57806323b872dd1461018957806342842e0e146101a55780636352211e146101c1576100ea565b806301ffc9a7146100ef57806306fdde031461011f578063081812fc1461013d575b600080fd5b61010960048036038101906101049190611c60565b6102f3565b6040516101169190611fb7565b60405180910390f35b6101276103d5565b6040516101349190611fd2565b60405180910390f35b61015760048036038101906101529190611cb2565b610467565b6040516101649190611f50565b60405180910390f35b61018760048036038101906101829190611c24565b6104ad565b005b6101a3600480360381019061019e9190611b1e565b6105c5565b005b6101bf60048036038101906101ba9190611b1e565b610625565b005b6101db60048036038101906101d69190611cb2565b610645565b6040516101e89190611f50565b60405180910390f35b61020b60048036038101906102069190611ab9565b6106cc565b005b61022760048036038101906102229190611ab9565b6106ef565b6040516102349190612154565b60405180910390f35b6102456107a7565b6040516102529190611fd2565b60405180910390f35b61027560048036038101906102709190611be8565b610839565b005b610291600480360381019061028c9190611b6d565b61084f565b005b6102ad60048036038101906102a89190611cb2565b6108b1565b6040516102ba9190611fd2565b60405180910390f35b6102dd60048036038101906102d89190611ae2565b610919565b6040516102ea9190611fb7565b60405180910390f35b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806103be57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806103ce57506103cd826109ad565b5b9050919050565b6060600080546103e490612348565b80601f016020809104026020016040519081016040528092919081815260200182805461041090612348565b801561045d5780601f106104325761010080835404028352916020019161045d565b820191906000526020600020905b81548152906001019060200180831161044057829003601f168201915b5050505050905090565b600061047282610a17565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006104b882610645565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610529576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052090612114565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610548610a62565b73ffffffffffffffffffffffffffffffffffffffff161480610577575061057681610571610a62565b610919565b5b6105b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ad90612134565b60405180910390fd5b6105c08383610a6a565b505050565b6105d66105d0610a62565b82610b23565b610615576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060c90611ff4565b60405180910390fd5b610620838383610bb8565b505050565b6106408383836040518060200160405280600081525061084f565b505050565b60008061065183610eb2565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156106c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106ba906120f4565b60405180910390fd5b80915050919050565b6106ec81600660008154809291906106e3906123ab565b91905055610eef565b50565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610760576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610757906120b4565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6060600180546107b690612348565b80601f01602080910402602001604051908101604052809291908181526020018280546107e290612348565b801561082f5780601f106108045761010080835404028352916020019161082f565b820191906000526020600020905b81548152906001019060200180831161081257829003601f168201915b5050505050905090565b61084b610844610a62565b8383610f0d565b5050565b61086061085a610a62565b83610b23565b61089f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161089690611ff4565b60405180910390fd5b6108ab8484848461107a565b50505050565b60606108bc82610a17565b60006108c66110d6565b905060008151116108e65760405180602001604052806000815250610911565b806108f0846110ed565b604051602001610901929190611f2c565b6040516020818303038152906040525b915050919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b610a2081611211565b610a5f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a56906120f4565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16610add83610645565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610b2f83610645565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480610b715750610b708185610919565b5b80610baf57508373ffffffffffffffffffffffffffffffffffffffff16610b9784610467565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16610bd882610645565b73ffffffffffffffffffffffffffffffffffffffff1614610c2e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2590612034565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610c9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c9590612074565b60405180910390fd5b610cab8383836001611252565b8273ffffffffffffffffffffffffffffffffffffffff16610ccb82610645565b73ffffffffffffffffffffffffffffffffffffffff1614610d21576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d1890612034565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610ead8383836001611378565b505050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b610f0982826040518060200160405280600081525061137e565b5050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610f7c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f7390612094565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161106d9190611fb7565b60405180910390a3505050565b611085848484610bb8565b611091848484846113d9565b6110d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110c790612014565b60405180910390fd5b50505050565b606060405180602001604052806000815250905090565b6060600060016110fc84611570565b01905060008167ffffffffffffffff811115611141577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156111735781602001600182028036833780820191505090505b509050600082602001820190505b600115611206578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816111f0577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b049450600085141561120157611206565b611181565b819350505050919050565b60008073ffffffffffffffffffffffffffffffffffffffff1661123383610eb2565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600181111561137257600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146112e65780600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546112de919061225e565b925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146113715780600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546113699190612208565b925050819055505b5b50505050565b50505050565b61138883836117a7565b61139560008484846113d9565b6113d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113cb90612014565b60405180910390fd5b505050565b60006113fa8473ffffffffffffffffffffffffffffffffffffffff166119c5565b15611563578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611423610a62565b8786866040518563ffffffff1660e01b81526004016114459493929190611f6b565b602060405180830381600087803b15801561145f57600080fd5b505af192505050801561149057506040513d601f19601f8201168201806040525081019061148d9190611c89565b60015b611513573d80600081146114c0576040519150601f19603f3d011682016040523d82523d6000602084013e6114c5565b606091505b5060008151141561150b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161150290612014565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050611568565b600190505b949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106115f4577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816115ea577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611657576d04ee2d6d415b85acef8100000000838161164d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b0492506020810190505b662386f26fc1000083106116ac57662386f26fc1000083816116a2577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b0492506010810190505b6305f5e10083106116fb576305f5e10083816116f1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b0492506008810190505b612710831061174657612710838161173c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b0492506004810190505b6064831061178f5760648381611785577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b0492506002810190505b600a831061179e576001810190505b80915050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611817576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161180e906120d4565b60405180910390fd5b61182081611211565b15611860576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161185790612054565b60405180910390fd5b61186e600083836001611252565b61187781611211565b156118b7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118ae90612054565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46119c1600083836001611378565b5050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60006119fb6119f684612194565b61216f565b905082815260208101848484011115611a1357600080fd5b611a1e848285612306565b509392505050565b600081359050611a358161275f565b92915050565b600081359050611a4a81612776565b92915050565b600081359050611a5f8161278d565b92915050565b600081519050611a748161278d565b92915050565b600082601f830112611a8b57600080fd5b8135611a9b8482602086016119e8565b91505092915050565b600081359050611ab3816127a4565b92915050565b600060208284031215611acb57600080fd5b6000611ad984828501611a26565b91505092915050565b60008060408385031215611af557600080fd5b6000611b0385828601611a26565b9250506020611b1485828601611a26565b9150509250929050565b600080600060608486031215611b3357600080fd5b6000611b4186828701611a26565b9350506020611b5286828701611a26565b9250506040611b6386828701611aa4565b9150509250925092565b60008060008060808587031215611b8357600080fd5b6000611b9187828801611a26565b9450506020611ba287828801611a26565b9350506040611bb387828801611aa4565b925050606085013567ffffffffffffffff811115611bd057600080fd5b611bdc87828801611a7a565b91505092959194509250565b60008060408385031215611bfb57600080fd5b6000611c0985828601611a26565b9250506020611c1a85828601611a3b565b9150509250929050565b60008060408385031215611c3757600080fd5b6000611c4585828601611a26565b9250506020611c5685828601611aa4565b9150509250929050565b600060208284031215611c7257600080fd5b6000611c8084828501611a50565b91505092915050565b600060208284031215611c9b57600080fd5b6000611ca984828501611a65565b91505092915050565b600060208284031215611cc457600080fd5b6000611cd284828501611aa4565b91505092915050565b611ce481612292565b82525050565b611cf3816122a4565b82525050565b6000611d04826121c5565b611d0e81856121db565b9350611d1e818560208601612315565b611d2781612481565b840191505092915050565b6000611d3d826121d0565b611d4781856121ec565b9350611d57818560208601612315565b611d6081612481565b840191505092915050565b6000611d76826121d0565b611d8081856121fd565b9350611d90818560208601612315565b80840191505092915050565b6000611da9602d836121ec565b9150611db482612492565b604082019050919050565b6000611dcc6032836121ec565b9150611dd7826124e1565b604082019050919050565b6000611def6025836121ec565b9150611dfa82612530565b604082019050919050565b6000611e12601c836121ec565b9150611e1d8261257f565b602082019050919050565b6000611e356024836121ec565b9150611e40826125a8565b604082019050919050565b6000611e586019836121ec565b9150611e63826125f7565b602082019050919050565b6000611e7b6029836121ec565b9150611e8682612620565b604082019050919050565b6000611e9e6020836121ec565b9150611ea98261266f565b602082019050919050565b6000611ec16018836121ec565b9150611ecc82612698565b602082019050919050565b6000611ee46021836121ec565b9150611eef826126c1565b604082019050919050565b6000611f07603d836121ec565b9150611f1282612710565b604082019050919050565b611f26816122fc565b82525050565b6000611f388285611d6b565b9150611f448284611d6b565b91508190509392505050565b6000602082019050611f656000830184611cdb565b92915050565b6000608082019050611f806000830187611cdb565b611f8d6020830186611cdb565b611f9a6040830185611f1d565b8181036060830152611fac8184611cf9565b905095945050505050565b6000602082019050611fcc6000830184611cea565b92915050565b60006020820190508181036000830152611fec8184611d32565b905092915050565b6000602082019050818103600083015261200d81611d9c565b9050919050565b6000602082019050818103600083015261202d81611dbf565b9050919050565b6000602082019050818103600083015261204d81611de2565b9050919050565b6000602082019050818103600083015261206d81611e05565b9050919050565b6000602082019050818103600083015261208d81611e28565b9050919050565b600060208201905081810360008301526120ad81611e4b565b9050919050565b600060208201905081810360008301526120cd81611e6e565b9050919050565b600060208201905081810360008301526120ed81611e91565b9050919050565b6000602082019050818103600083015261210d81611eb4565b9050919050565b6000602082019050818103600083015261212d81611ed7565b9050919050565b6000602082019050818103600083015261214d81611efa565b9050919050565b60006020820190506121696000830184611f1d565b92915050565b600061217961218a565b9050612185828261237a565b919050565b6000604051905090565b600067ffffffffffffffff8211156121af576121ae612452565b5b6121b882612481565b9050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6000612213826122fc565b915061221e836122fc565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612253576122526123f4565b5b828201905092915050565b6000612269826122fc565b9150612274836122fc565b925082821015612287576122866123f4565b5b828203905092915050565b600061229d826122dc565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015612333578082015181840152602081019050612318565b83811115612342576000848401525b50505050565b6000600282049050600182168061236057607f821691505b6020821081141561237457612373612423565b5b50919050565b61238382612481565b810181811067ffffffffffffffff821117156123a2576123a1612452565b5b80604052505050565b60006123b6826122fc565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156123e9576123e86123f4565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b61276881612292565b811461277357600080fd5b50565b61277f816122a4565b811461278a57600080fd5b50565b612796816122b0565b81146127a157600080fd5b50565b6127ad816122fc565b81146127b857600080fd5b5056fea264697066735822122081cc551bc6d29594eaf36ece0da52af221587575fe93fcb37decc025948e4fc364736f6c63430008040033"; -var isSuperArgs = function (xs) { return xs.length > 1; }; -var TestERC721__factory = /** @class */ (function (_super) { - __extends(TestERC721__factory, _super); - function TestERC721__factory() { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - var _this = this; - if (isSuperArgs(args)) { - _this = _super.apply(this, args) || this; - } - else { - _this = _super.call(this, _abi, _bytecode, args[0]) || this; - } - _this.contractName = "TestERC721"; - return _this; - } - TestERC721__factory.prototype.deploy = function (name, symbol, overrides) { - return _super.prototype.deploy.call(this, name, symbol, overrides || {}); - }; - TestERC721__factory.prototype.getDeployTransaction = function (name, symbol, overrides) { - return _super.prototype.getDeployTransaction.call(this, name, symbol, overrides || {}); - }; - TestERC721__factory.prototype.attach = function (address) { - return _super.prototype.attach.call(this, address); - }; - TestERC721__factory.prototype.connect = function (signer) { - return _super.prototype.connect.call(this, signer); - }; - TestERC721__factory.createInterface = function () { - return new ethers_1.utils.Interface(_abi); - }; - TestERC721__factory.connect = function (address, signerOrProvider) { - return new ethers_1.Contract(address, _abi, signerOrProvider); - }; - TestERC721__factory.bytecode = _bytecode; - TestERC721__factory.abi = _abi; - return TestERC721__factory; -}(ethers_1.ContractFactory)); -exports.TestERC721__factory = TestERC721__factory; diff --git a/desci-contracts/typechain-types/factories/VersionedERC721V2__factory.js b/desci-contracts/typechain-types/factories/VersionedERC721V2__factory.js deleted file mode 100644 index da52e72d..00000000 --- a/desci-contracts/typechain-types/factories/VersionedERC721V2__factory.js +++ /dev/null @@ -1,508 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - if (typeof b !== "function" && b !== null) - throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -exports.__esModule = true; -exports.VersionedERC721V2__factory = void 0; -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -var ethers_1 = require("ethers"); -var _abi = [ - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "owner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "approved", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "Approval", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "owner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "operator", - type: "address" - }, - { - indexed: false, - internalType: "bool", - name: "approved", - type: "bool" - }, - ], - name: "ApprovalForAll", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "uint8", - name: "version", - type: "uint8" - }, - ], - name: "Initialized", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "from", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "to", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "Transfer", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "_from", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "_uuid", - type: "uint256" - }, - { - indexed: false, - internalType: "bytes", - name: "_cid", - type: "bytes" - }, - ], - name: "VersionPush", - type: "event" - }, - { - inputs: [ - { - internalType: "string", - name: "name", - type: "string" - }, - { - internalType: "string", - name: "symbol", - type: "string" - }, - ], - name: "__VersionedERC721V2_init", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "", - type: "uint256" - }, - ], - name: "_metadata", - outputs: [ - { - internalType: "bytes", - name: "", - type: "bytes" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "approve", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - ], - name: "balanceOf", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "exists", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "getApproved", - outputs: [ - { - internalType: "address", - name: "", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - { - internalType: "address", - name: "operator", - type: "address" - }, - ], - name: "isApprovedForAll", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [], - name: "name", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "ownerOf", - outputs: [ - { - internalType: "address", - name: "", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "safeTransferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - { - internalType: "bytes", - name: "data", - type: "bytes" - }, - ], - name: "safeTransferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "operator", - type: "address" - }, - { - internalType: "bool", - name: "approved", - type: "bool" - }, - ], - name: "setApprovalForAll", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "bytes4", - name: "interfaceId", - type: "bytes4" - }, - ], - name: "supportsInterface", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [], - name: "symbol", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "tokenURI", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "transferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - { - internalType: "bytes", - name: "cid", - type: "bytes" - }, - ], - name: "updateMetadata", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, -]; -var _bytecode = "0x608060405234801561001057600080fd5b506128f0806100206000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c80636352211e116100a2578063a22cb46511610071578063a22cb465146102dc578063af3ba9c1146102f8578063b88d4fde14610314578063c87b56dd14610330578063e985e9c5146103605761010b565b80636352211e1461024257806370a082311461027257806395d89b41146102a25780639a7fad40146102c05761010b565b806313859f46116100de57806313859f46146101aa57806323b872dd146101da57806342842e0e146101f65780634f558e79146102125761010b565b806301ffc9a71461011057806306fdde0314610140578063081812fc1461015e578063095ea7b31461018e575b600080fd5b61012a60048036038101906101259190611b95565b610390565b6040516101379190611fac565b60405180910390f35b610148610472565b6040516101559190611fe9565b60405180910390f35b61017860048036038101906101739190611c53565b610504565b6040516101859190611f45565b60405180910390f35b6101a860048036038101906101a39190611b59565b61054a565b005b6101c460048036038101906101bf9190611c53565b610662565b6040516101d19190611fc7565b60405180910390f35b6101f460048036038101906101ef9190611a53565b610702565b005b610210600480360381019061020b9190611a53565b610762565b005b61022c60048036038101906102279190611c53565b610782565b6040516102399190611fac565b60405180910390f35b61025c60048036038101906102579190611c53565b610794565b6040516102699190611f45565b60405180910390f35b61028c600480360381019061028791906119ee565b610846565b604051610299919061216b565b60405180910390f35b6102aa6108fe565b6040516102b79190611fe9565b60405180910390f35b6102da60048036038101906102d59190611c7c565b610990565b005b6102f660048036038101906102f19190611b1d565b610aae565b005b610312600480360381019061030d9190611be7565b610ac4565b005b61032e60048036038101906103299190611aa2565b610b21565b005b61034a60048036038101906103459190611c53565b610b83565b6040516103579190611fe9565b60405180910390f35b61037a60048036038101906103759190611a17565b610beb565b6040516103879190611fac565b60405180910390f35b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061045b57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061046b575061046a82610c7f565b5b9050919050565b606060658054610481906123c1565b80601f01602080910402602001604051908101604052809291908181526020018280546104ad906123c1565b80156104fa5780601f106104cf576101008083540402835291602001916104fa565b820191906000526020600020905b8154815290600101906020018083116104dd57829003601f168201915b5050505050905090565b600061050f82610ce9565b6069600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061055582610794565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156105c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105bd9061210b565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166105e5610d34565b73ffffffffffffffffffffffffffffffffffffffff16148061061457506106138161060e610d34565b610beb565b5b610653576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161064a906120ab565b60405180910390fd5b61065d8383610d3c565b505050565b60976020528060005260406000206000915090508054610681906123c1565b80601f01602080910402602001604051908101604052809291908181526020018280546106ad906123c1565b80156106fa5780601f106106cf576101008083540402835291602001916106fa565b820191906000526020600020905b8154815290600101906020018083116106dd57829003601f168201915b505050505081565b61071361070d610d34565b82610df5565b610752576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107499061214b565b60405180910390fd5b61075d838383610e8a565b505050565b61077d83838360405180602001604052806000815250610b21565b505050565b600061078d826110f1565b9050919050565b6000806067600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561083d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610834906120eb565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156108b7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ae9061208b565b60405180910390fd5b606860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60606066805461090d906123c1565b80601f0160208091040260200160405190810160405280929190818152602001828054610939906123c1565b80156109865780601f1061095b57610100808354040283529160200191610986565b820191906000526020600020905b81548152906001019060200180831161096957829003601f168201915b5050505050905090565b81600061099b610d34565b905060008173ffffffffffffffffffffffffffffffffffffffff166109bf84610794565b73ffffffffffffffffffffffffffffffffffffffff1614806109e757506109e68284610df5565b5b905080610a29576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a20906120cb565b60405180910390fd5b83609760008781526020019081526020016000209080519060200190610a5092919061178c565b5084610a5a610d34565b73ffffffffffffffffffffffffffffffffffffffff167fabddf73bfc8efbf8287a09ea355e43cf6c0c22880ce0470affeba5271c0a769486604051610a9f9190611fc7565b60405180910390a35050505050565b610ac0610ab9610d34565b838361115d565b5050565b600060019054906101000a900460ff16610b13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0a9061212b565b60405180910390fd5b610b1d82826112ca565b5050565b610b32610b2c610d34565b83610df5565b610b71576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b689061214b565b60405180910390fd5b610b7d84848484611327565b50505050565b6060610b8e82610ce9565b6000610b98611383565b90506000815111610bb85760405180602001604052806000815250610be3565b80610bc28461139a565b604051602001610bd3929190611f21565b6040516020818303038152906040525b915050919050565b6000606a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b610cf2816110f1565b610d31576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d28906120eb565b60405180910390fd5b50565b600033905090565b816069600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16610daf83610794565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610e0183610794565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480610e435750610e428185610beb565b5b80610e8157508373ffffffffffffffffffffffffffffffffffffffff16610e6984610504565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16610eaa82610794565b73ffffffffffffffffffffffffffffffffffffffff1614610f00576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ef79061202b565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610f70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f679061204b565b60405180910390fd5b610f7b838383611547565b610f86600082610d3c565b6001606860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610fd691906122d7565b925050819055506001606860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461102d9190612250565b92505081905550816067600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46110ec83838361154c565b505050565b60008073ffffffffffffffffffffffffffffffffffffffff166067600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156111cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111c39061206b565b60405180910390fd5b80606a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516112bd9190611fac565b60405180910390a3505050565b600060019054906101000a900460ff16611319576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113109061212b565b60405180910390fd5b6113238282611551565b5050565b611332848484610e8a565b61133e848484846115d2565b61137d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113749061200b565b60405180910390fd5b50505050565b606060405180602001604052806000815250905090565b606060008214156113e2576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050611542565b600082905060005b600082146114145780806113fd90612424565b915050600a8261140d91906122a6565b91506113ea565b60008167ffffffffffffffff811115611456577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156114885781602001600182028036833780820191505090505b5090505b6000851461153b576001826114a191906122d7565b9150600a856114b0919061246d565b60306114bc9190612250565b60f81b8183815181106114f8577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8561153491906122a6565b945061148c565b8093505050505b919050565b505050565b505050565b600060019054906101000a900460ff166115a0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115979061212b565b60405180910390fd5b81606590805190602001906115b6929190611812565b5080606690805190602001906115cd929190611812565b505050565b60006115f38473ffffffffffffffffffffffffffffffffffffffff16611769565b1561175c578373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261161c610d34565b8786866040518563ffffffff1660e01b815260040161163e9493929190611f60565b602060405180830381600087803b15801561165857600080fd5b505af192505050801561168957506040513d601f19601f820116820180604052508101906116869190611bbe565b60015b61170c573d80600081146116b9576040519150601f19603f3d011682016040523d82523d6000602084013e6116be565b606091505b50600081511415611704576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116fb9061200b565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050611761565b600190505b949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b828054611798906123c1565b90600052602060002090601f0160209004810192826117ba5760008555611801565b82601f106117d357805160ff1916838001178555611801565b82800160010185558215611801579182015b828111156118005782518255916020019190600101906117e5565b5b50905061180e9190611898565b5090565b82805461181e906123c1565b90600052602060002090601f0160209004810192826118405760008555611887565b82601f1061185957805160ff1916838001178555611887565b82800160010185558215611887579182015b8281111561188657825182559160200191906001019061186b565b5b5090506118949190611898565b5090565b5b808211156118b1576000816000905550600101611899565b5090565b60006118c86118c3846121ab565b612186565b9050828152602081018484840111156118e057600080fd5b6118eb84828561237f565b509392505050565b6000611906611901846121dc565b612186565b90508281526020810184848401111561191e57600080fd5b61192984828561237f565b509392505050565b6000813590506119408161285e565b92915050565b60008135905061195581612875565b92915050565b60008135905061196a8161288c565b92915050565b60008151905061197f8161288c565b92915050565b600082601f83011261199657600080fd5b81356119a68482602086016118b5565b91505092915050565b600082601f8301126119c057600080fd5b81356119d08482602086016118f3565b91505092915050565b6000813590506119e8816128a3565b92915050565b600060208284031215611a0057600080fd5b6000611a0e84828501611931565b91505092915050565b60008060408385031215611a2a57600080fd5b6000611a3885828601611931565b9250506020611a4985828601611931565b9150509250929050565b600080600060608486031215611a6857600080fd5b6000611a7686828701611931565b9350506020611a8786828701611931565b9250506040611a98868287016119d9565b9150509250925092565b60008060008060808587031215611ab857600080fd5b6000611ac687828801611931565b9450506020611ad787828801611931565b9350506040611ae8878288016119d9565b925050606085013567ffffffffffffffff811115611b0557600080fd5b611b1187828801611985565b91505092959194509250565b60008060408385031215611b3057600080fd5b6000611b3e85828601611931565b9250506020611b4f85828601611946565b9150509250929050565b60008060408385031215611b6c57600080fd5b6000611b7a85828601611931565b9250506020611b8b858286016119d9565b9150509250929050565b600060208284031215611ba757600080fd5b6000611bb58482850161195b565b91505092915050565b600060208284031215611bd057600080fd5b6000611bde84828501611970565b91505092915050565b60008060408385031215611bfa57600080fd5b600083013567ffffffffffffffff811115611c1457600080fd5b611c20858286016119af565b925050602083013567ffffffffffffffff811115611c3d57600080fd5b611c49858286016119af565b9150509250929050565b600060208284031215611c6557600080fd5b6000611c73848285016119d9565b91505092915050565b60008060408385031215611c8f57600080fd5b6000611c9d858286016119d9565b925050602083013567ffffffffffffffff811115611cba57600080fd5b611cc685828601611985565b9150509250929050565b611cd98161230b565b82525050565b611ce88161231d565b82525050565b6000611cf98261220d565b611d038185612223565b9350611d1381856020860161238e565b611d1c8161255a565b840191505092915050565b6000611d3282612218565b611d3c8185612234565b9350611d4c81856020860161238e565b611d558161255a565b840191505092915050565b6000611d6b82612218565b611d758185612245565b9350611d8581856020860161238e565b80840191505092915050565b6000611d9e603283612234565b9150611da98261256b565b604082019050919050565b6000611dc1602583612234565b9150611dcc826125ba565b604082019050919050565b6000611de4602483612234565b9150611def82612609565b604082019050919050565b6000611e07601983612234565b9150611e1282612658565b602082019050919050565b6000611e2a602983612234565b9150611e3582612681565b604082019050919050565b6000611e4d603e83612234565b9150611e58826126d0565b604082019050919050565b6000611e70600d83612234565b9150611e7b8261271f565b602082019050919050565b6000611e93601883612234565b9150611e9e82612748565b602082019050919050565b6000611eb6602183612234565b9150611ec182612771565b604082019050919050565b6000611ed9602b83612234565b9150611ee4826127c0565b604082019050919050565b6000611efc602e83612234565b9150611f078261280f565b604082019050919050565b611f1b81612375565b82525050565b6000611f2d8285611d60565b9150611f398284611d60565b91508190509392505050565b6000602082019050611f5a6000830184611cd0565b92915050565b6000608082019050611f756000830187611cd0565b611f826020830186611cd0565b611f8f6040830185611f12565b8181036060830152611fa18184611cee565b905095945050505050565b6000602082019050611fc16000830184611cdf565b92915050565b60006020820190508181036000830152611fe18184611cee565b905092915050565b600060208201905081810360008301526120038184611d27565b905092915050565b6000602082019050818103600083015261202481611d91565b9050919050565b6000602082019050818103600083015261204481611db4565b9050919050565b6000602082019050818103600083015261206481611dd7565b9050919050565b6000602082019050818103600083015261208481611dfa565b9050919050565b600060208201905081810360008301526120a481611e1d565b9050919050565b600060208201905081810360008301526120c481611e40565b9050919050565b600060208201905081810360008301526120e481611e63565b9050919050565b6000602082019050818103600083015261210481611e86565b9050919050565b6000602082019050818103600083015261212481611ea9565b9050919050565b6000602082019050818103600083015261214481611ecc565b9050919050565b6000602082019050818103600083015261216481611eef565b9050919050565b60006020820190506121806000830184611f12565b92915050565b60006121906121a1565b905061219c82826123f3565b919050565b6000604051905090565b600067ffffffffffffffff8211156121c6576121c561252b565b5b6121cf8261255a565b9050602081019050919050565b600067ffffffffffffffff8211156121f7576121f661252b565b5b6122008261255a565b9050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600061225b82612375565b915061226683612375565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561229b5761229a61249e565b5b828201905092915050565b60006122b182612375565b91506122bc83612375565b9250826122cc576122cb6124cd565b5b828204905092915050565b60006122e282612375565b91506122ed83612375565b925082821015612300576122ff61249e565b5b828203905092915050565b600061231682612355565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156123ac578082015181840152602081019050612391565b838111156123bb576000848401525b50505050565b600060028204905060018216806123d957607f821691505b602082108114156123ed576123ec6124fc565b5b50919050565b6123fc8261255a565b810181811067ffffffffffffffff8211171561241b5761241a61252b565b5b80604052505050565b600061242f82612375565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156124625761246161249e565b5b600182019050919050565b600061247882612375565b915061248383612375565b925082612493576124926124cd565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b7f4e6f207065726d697373696f6e00000000000000000000000000000000000000600082015250565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b6128678161230b565b811461287257600080fd5b50565b61287e8161231d565b811461288957600080fd5b50565b61289581612329565b81146128a057600080fd5b50565b6128ac81612375565b81146128b757600080fd5b5056fea2646970667358221220912681ee982aac98ba6e5a66c351c0104fd0af441115dab6d9ad9423598c793364736f6c63430008040033"; -var isSuperArgs = function (xs) { return xs.length > 1; }; -var VersionedERC721V2__factory = /** @class */ (function (_super) { - __extends(VersionedERC721V2__factory, _super); - function VersionedERC721V2__factory() { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - var _this = this; - if (isSuperArgs(args)) { - _this = _super.apply(this, args) || this; - } - else { - _this = _super.call(this, _abi, _bytecode, args[0]) || this; - } - _this.contractName = "VersionedERC721V2"; - return _this; - } - VersionedERC721V2__factory.prototype.deploy = function (overrides) { - return _super.prototype.deploy.call(this, overrides || {}); - }; - VersionedERC721V2__factory.prototype.getDeployTransaction = function (overrides) { - return _super.prototype.getDeployTransaction.call(this, overrides || {}); - }; - VersionedERC721V2__factory.prototype.attach = function (address) { - return _super.prototype.attach.call(this, address); - }; - VersionedERC721V2__factory.prototype.connect = function (signer) { - return _super.prototype.connect.call(this, signer); - }; - VersionedERC721V2__factory.createInterface = function () { - return new ethers_1.utils.Interface(_abi); - }; - VersionedERC721V2__factory.connect = function (address, signerOrProvider) { - return new ethers_1.Contract(address, _abi, signerOrProvider); - }; - VersionedERC721V2__factory.bytecode = _bytecode; - VersionedERC721V2__factory.abi = _abi; - return VersionedERC721V2__factory; -}(ethers_1.ContractFactory)); -exports.VersionedERC721V2__factory = VersionedERC721V2__factory; diff --git a/desci-contracts/typechain-types/factories/VersionedERC721__factory.js b/desci-contracts/typechain-types/factories/VersionedERC721__factory.js deleted file mode 100644 index 25f3262d..00000000 --- a/desci-contracts/typechain-types/factories/VersionedERC721__factory.js +++ /dev/null @@ -1,508 +0,0 @@ -"use strict"; -var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - if (typeof b !== "function" && b !== null) - throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -exports.__esModule = true; -exports.VersionedERC721__factory = void 0; -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -var ethers_1 = require("ethers"); -var _abi = [ - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "owner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "approved", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "Approval", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "owner", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "operator", - type: "address" - }, - { - indexed: false, - internalType: "bool", - name: "approved", - type: "bool" - }, - ], - name: "ApprovalForAll", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "uint8", - name: "version", - type: "uint8" - }, - ], - name: "Initialized", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "from", - type: "address" - }, - { - indexed: true, - internalType: "address", - name: "to", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "Transfer", - type: "event" - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: "address", - name: "_from", - type: "address" - }, - { - indexed: true, - internalType: "uint256", - name: "_uuid", - type: "uint256" - }, - { - indexed: false, - internalType: "bytes", - name: "_cid", - type: "bytes" - }, - ], - name: "VersionPush", - type: "event" - }, - { - inputs: [ - { - internalType: "string", - name: "name", - type: "string" - }, - { - internalType: "string", - name: "symbol", - type: "string" - }, - ], - name: "__VersionedERC721_init", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "", - type: "uint256" - }, - ], - name: "_metadata", - outputs: [ - { - internalType: "bytes", - name: "", - type: "bytes" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "approve", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - ], - name: "balanceOf", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "exists", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "getApproved", - outputs: [ - { - internalType: "address", - name: "", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "owner", - type: "address" - }, - { - internalType: "address", - name: "operator", - type: "address" - }, - ], - name: "isApprovedForAll", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [], - name: "name", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "ownerOf", - outputs: [ - { - internalType: "address", - name: "", - type: "address" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "safeTransferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - { - internalType: "bytes", - name: "data", - type: "bytes" - }, - ], - name: "safeTransferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "operator", - type: "address" - }, - { - internalType: "bool", - name: "approved", - type: "bool" - }, - ], - name: "setApprovalForAll", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "bytes4", - name: "interfaceId", - type: "bytes4" - }, - ], - name: "supportsInterface", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [], - name: "symbol", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "tokenURI", - outputs: [ - { - internalType: "string", - name: "", - type: "string" - }, - ], - stateMutability: "view", - type: "function" - }, - { - inputs: [ - { - internalType: "address", - name: "from", - type: "address" - }, - { - internalType: "address", - name: "to", - type: "address" - }, - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - ], - name: "transferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, - { - inputs: [ - { - internalType: "uint256", - name: "tokenId", - type: "uint256" - }, - { - internalType: "bytes", - name: "cid", - type: "bytes" - }, - ], - name: "updateMetadata", - outputs: [], - stateMutability: "nonpayable", - type: "function" - }, -]; -var _bytecode = "0x608060405234801561001057600080fd5b506128df806100206000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c8063599ad936116100a25780639a7fad40116100715780639a7fad40146102dc578063a22cb465146102f8578063b88d4fde14610314578063c87b56dd14610330578063e985e9c5146103605761010b565b8063599ad936146102425780636352211e1461025e57806370a082311461028e57806395d89b41146102be5761010b565b806313859f46116100de57806313859f46146101aa57806323b872dd146101da57806342842e0e146101f65780634f558e79146102125761010b565b806301ffc9a71461011057806306fdde0314610140578063081812fc1461015e578063095ea7b31461018e575b600080fd5b61012a60048036038101906101259190611b84565b610390565b6040516101379190611f9b565b60405180910390f35b610148610472565b6040516101559190611fd8565b60405180910390f35b61017860048036038101906101739190611c42565b610504565b6040516101859190611f34565b60405180910390f35b6101a860048036038101906101a39190611b48565b61054a565b005b6101c460048036038101906101bf9190611c42565b610662565b6040516101d19190611fb6565b60405180910390f35b6101f460048036038101906101ef9190611a42565b610702565b005b610210600480360381019061020b9190611a42565b610762565b005b61022c60048036038101906102279190611c42565b610782565b6040516102399190611f9b565b60405180910390f35b61025c60048036038101906102579190611bd6565b610794565b005b61027860048036038101906102739190611c42565b6107f1565b6040516102859190611f34565b60405180910390f35b6102a860048036038101906102a391906119dd565b6108a3565b6040516102b5919061215a565b60405180910390f35b6102c661095b565b6040516102d39190611fd8565b60405180910390f35b6102f660048036038101906102f19190611c6b565b6109ed565b005b610312600480360381019061030d9190611b0c565b610afa565b005b61032e60048036038101906103299190611a91565b610b10565b005b61034a60048036038101906103459190611c42565b610b72565b6040516103579190611fd8565b60405180910390f35b61037a60048036038101906103759190611a06565b610bda565b6040516103879190611f9b565b60405180910390f35b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061045b57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061046b575061046a82610c6e565b5b9050919050565b606060658054610481906123b0565b80601f01602080910402602001604051908101604052809291908181526020018280546104ad906123b0565b80156104fa5780601f106104cf576101008083540402835291602001916104fa565b820191906000526020600020905b8154815290600101906020018083116104dd57829003601f168201915b5050505050905090565b600061050f82610cd8565b6069600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610555826107f1565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156105c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105bd906120fa565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166105e5610d23565b73ffffffffffffffffffffffffffffffffffffffff16148061061457506106138161060e610d23565b610bda565b5b610653576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161064a9061209a565b60405180910390fd5b61065d8383610d2b565b505050565b60976020528060005260406000206000915090508054610681906123b0565b80601f01602080910402602001604051908101604052809291908181526020018280546106ad906123b0565b80156106fa5780601f106106cf576101008083540402835291602001916106fa565b820191906000526020600020905b8154815290600101906020018083116106dd57829003601f168201915b505050505081565b61071361070d610d23565b82610de4565b610752576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107499061213a565b60405180910390fd5b61075d838383610e79565b505050565b61077d83838360405180602001604052806000815250610b10565b505050565b600061078d826110e0565b9050919050565b600060019054906101000a900460ff166107e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107da9061211a565b60405180910390fd5b6107ed828261114c565b5050565b6000806067600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561089a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610891906120da565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610914576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090b9061207a565b60405180910390fd5b606860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60606066805461096a906123b0565b80601f0160208091040260200160405190810160405280929190818152602001828054610996906123b0565b80156109e35780601f106109b8576101008083540402835291602001916109e3565b820191906000526020600020905b8154815290600101906020018083116109c657829003601f168201915b5050505050905090565b8160006109f8610d23565b905060008173ffffffffffffffffffffffffffffffffffffffff16610a1c846107f1565b73ffffffffffffffffffffffffffffffffffffffff1614905080610a75576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6c906120ba565b60405180910390fd5b83609760008781526020019081526020016000209080519060200190610a9c92919061177b565b5084610aa6610d23565b73ffffffffffffffffffffffffffffffffffffffff167fabddf73bfc8efbf8287a09ea355e43cf6c0c22880ce0470affeba5271c0a769486604051610aeb9190611fb6565b60405180910390a35050505050565b610b0c610b05610d23565b83836111a9565b5050565b610b21610b1b610d23565b83610de4565b610b60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b579061213a565b60405180910390fd5b610b6c84848484611316565b50505050565b6060610b7d82610cd8565b6000610b87611372565b90506000815111610ba75760405180602001604052806000815250610bd2565b80610bb184611389565b604051602001610bc2929190611f10565b6040516020818303038152906040525b915050919050565b6000606a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b610ce1816110e0565b610d20576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d17906120da565b60405180910390fd5b50565b600033905090565b816069600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16610d9e836107f1565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610df0836107f1565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480610e325750610e318185610bda565b5b80610e7057508373ffffffffffffffffffffffffffffffffffffffff16610e5884610504565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16610e99826107f1565b73ffffffffffffffffffffffffffffffffffffffff1614610eef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ee69061201a565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610f5f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f569061203a565b60405180910390fd5b610f6a838383611536565b610f75600082610d2b565b6001606860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610fc591906122c6565b925050819055506001606860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461101c919061223f565b92505081905550816067600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46110db83838361153b565b505050565b60008073ffffffffffffffffffffffffffffffffffffffff166067600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600060019054906101000a900460ff1661119b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111929061211a565b60405180910390fd5b6111a58282611540565b5050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611218576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120f9061205a565b60405180910390fd5b80606a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516113099190611f9b565b60405180910390a3505050565b611321848484610e79565b61132d848484846115c1565b61136c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161136390611ffa565b60405180910390fd5b50505050565b606060405180602001604052806000815250905090565b606060008214156113d1576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050611531565b600082905060005b600082146114035780806113ec90612413565b915050600a826113fc9190612295565b91506113d9565b60008167ffffffffffffffff811115611445577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156114775781602001600182028036833780820191505090505b5090505b6000851461152a5760018261149091906122c6565b9150600a8561149f919061245c565b60306114ab919061223f565b60f81b8183815181106114e7577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856115239190612295565b945061147b565b8093505050505b919050565b505050565b505050565b600060019054906101000a900460ff1661158f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115869061211a565b60405180910390fd5b81606590805190602001906115a5929190611801565b5080606690805190602001906115bc929190611801565b505050565b60006115e28473ffffffffffffffffffffffffffffffffffffffff16611758565b1561174b578373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261160b610d23565b8786866040518563ffffffff1660e01b815260040161162d9493929190611f4f565b602060405180830381600087803b15801561164757600080fd5b505af192505050801561167857506040513d601f19601f820116820180604052508101906116759190611bad565b60015b6116fb573d80600081146116a8576040519150601f19603f3d011682016040523d82523d6000602084013e6116ad565b606091505b506000815114156116f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ea90611ffa565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050611750565b600190505b949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b828054611787906123b0565b90600052602060002090601f0160209004810192826117a957600085556117f0565b82601f106117c257805160ff19168380011785556117f0565b828001600101855582156117f0579182015b828111156117ef5782518255916020019190600101906117d4565b5b5090506117fd9190611887565b5090565b82805461180d906123b0565b90600052602060002090601f01602090048101928261182f5760008555611876565b82601f1061184857805160ff1916838001178555611876565b82800160010185558215611876579182015b8281111561187557825182559160200191906001019061185a565b5b5090506118839190611887565b5090565b5b808211156118a0576000816000905550600101611888565b5090565b60006118b76118b28461219a565b612175565b9050828152602081018484840111156118cf57600080fd5b6118da84828561236e565b509392505050565b60006118f56118f0846121cb565b612175565b90508281526020810184848401111561190d57600080fd5b61191884828561236e565b509392505050565b60008135905061192f8161284d565b92915050565b60008135905061194481612864565b92915050565b6000813590506119598161287b565b92915050565b60008151905061196e8161287b565b92915050565b600082601f83011261198557600080fd5b81356119958482602086016118a4565b91505092915050565b600082601f8301126119af57600080fd5b81356119bf8482602086016118e2565b91505092915050565b6000813590506119d781612892565b92915050565b6000602082840312156119ef57600080fd5b60006119fd84828501611920565b91505092915050565b60008060408385031215611a1957600080fd5b6000611a2785828601611920565b9250506020611a3885828601611920565b9150509250929050565b600080600060608486031215611a5757600080fd5b6000611a6586828701611920565b9350506020611a7686828701611920565b9250506040611a87868287016119c8565b9150509250925092565b60008060008060808587031215611aa757600080fd5b6000611ab587828801611920565b9450506020611ac687828801611920565b9350506040611ad7878288016119c8565b925050606085013567ffffffffffffffff811115611af457600080fd5b611b0087828801611974565b91505092959194509250565b60008060408385031215611b1f57600080fd5b6000611b2d85828601611920565b9250506020611b3e85828601611935565b9150509250929050565b60008060408385031215611b5b57600080fd5b6000611b6985828601611920565b9250506020611b7a858286016119c8565b9150509250929050565b600060208284031215611b9657600080fd5b6000611ba48482850161194a565b91505092915050565b600060208284031215611bbf57600080fd5b6000611bcd8482850161195f565b91505092915050565b60008060408385031215611be957600080fd5b600083013567ffffffffffffffff811115611c0357600080fd5b611c0f8582860161199e565b925050602083013567ffffffffffffffff811115611c2c57600080fd5b611c388582860161199e565b9150509250929050565b600060208284031215611c5457600080fd5b6000611c62848285016119c8565b91505092915050565b60008060408385031215611c7e57600080fd5b6000611c8c858286016119c8565b925050602083013567ffffffffffffffff811115611ca957600080fd5b611cb585828601611974565b9150509250929050565b611cc8816122fa565b82525050565b611cd78161230c565b82525050565b6000611ce8826121fc565b611cf28185612212565b9350611d0281856020860161237d565b611d0b81612549565b840191505092915050565b6000611d2182612207565b611d2b8185612223565b9350611d3b81856020860161237d565b611d4481612549565b840191505092915050565b6000611d5a82612207565b611d648185612234565b9350611d7481856020860161237d565b80840191505092915050565b6000611d8d603283612223565b9150611d988261255a565b604082019050919050565b6000611db0602583612223565b9150611dbb826125a9565b604082019050919050565b6000611dd3602483612223565b9150611dde826125f8565b604082019050919050565b6000611df6601983612223565b9150611e0182612647565b602082019050919050565b6000611e19602983612223565b9150611e2482612670565b604082019050919050565b6000611e3c603e83612223565b9150611e47826126bf565b604082019050919050565b6000611e5f600d83612223565b9150611e6a8261270e565b602082019050919050565b6000611e82601883612223565b9150611e8d82612737565b602082019050919050565b6000611ea5602183612223565b9150611eb082612760565b604082019050919050565b6000611ec8602b83612223565b9150611ed3826127af565b604082019050919050565b6000611eeb602e83612223565b9150611ef6826127fe565b604082019050919050565b611f0a81612364565b82525050565b6000611f1c8285611d4f565b9150611f288284611d4f565b91508190509392505050565b6000602082019050611f496000830184611cbf565b92915050565b6000608082019050611f646000830187611cbf565b611f716020830186611cbf565b611f7e6040830185611f01565b8181036060830152611f908184611cdd565b905095945050505050565b6000602082019050611fb06000830184611cce565b92915050565b60006020820190508181036000830152611fd08184611cdd565b905092915050565b60006020820190508181036000830152611ff28184611d16565b905092915050565b6000602082019050818103600083015261201381611d80565b9050919050565b6000602082019050818103600083015261203381611da3565b9050919050565b6000602082019050818103600083015261205381611dc6565b9050919050565b6000602082019050818103600083015261207381611de9565b9050919050565b6000602082019050818103600083015261209381611e0c565b9050919050565b600060208201905081810360008301526120b381611e2f565b9050919050565b600060208201905081810360008301526120d381611e52565b9050919050565b600060208201905081810360008301526120f381611e75565b9050919050565b6000602082019050818103600083015261211381611e98565b9050919050565b6000602082019050818103600083015261213381611ebb565b9050919050565b6000602082019050818103600083015261215381611ede565b9050919050565b600060208201905061216f6000830184611f01565b92915050565b600061217f612190565b905061218b82826123e2565b919050565b6000604051905090565b600067ffffffffffffffff8211156121b5576121b461251a565b5b6121be82612549565b9050602081019050919050565b600067ffffffffffffffff8211156121e6576121e561251a565b5b6121ef82612549565b9050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600061224a82612364565b915061225583612364565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561228a5761228961248d565b5b828201905092915050565b60006122a082612364565b91506122ab83612364565b9250826122bb576122ba6124bc565b5b828204905092915050565b60006122d182612364565b91506122dc83612364565b9250828210156122ef576122ee61248d565b5b828203905092915050565b600061230582612344565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b8381101561239b578082015181840152602081019050612380565b838111156123aa576000848401525b50505050565b600060028204905060018216806123c857607f821691505b602082108114156123dc576123db6124eb565b5b50919050565b6123eb82612549565b810181811067ffffffffffffffff8211171561240a5761240961251a565b5b80604052505050565b600061241e82612364565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156124515761245061248d565b5b600182019050919050565b600061246782612364565b915061247283612364565b925082612482576124816124bc565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c0000602082015250565b7f4e6f207065726d697373696f6e00000000000000000000000000000000000000600082015250565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b612856816122fa565b811461286157600080fd5b50565b61286d8161230c565b811461287857600080fd5b50565b61288481612318565b811461288f57600080fd5b50565b61289b81612364565b81146128a657600080fd5b5056fea26469706673582212208816f35c3f39abe99ae49479034773b9cac55a86f0dc13f69dab11aa58a03d2f64736f6c63430008040033"; -var isSuperArgs = function (xs) { return xs.length > 1; }; -var VersionedERC721__factory = /** @class */ (function (_super) { - __extends(VersionedERC721__factory, _super); - function VersionedERC721__factory() { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - var _this = this; - if (isSuperArgs(args)) { - _this = _super.apply(this, args) || this; - } - else { - _this = _super.call(this, _abi, _bytecode, args[0]) || this; - } - _this.contractName = "VersionedERC721"; - return _this; - } - VersionedERC721__factory.prototype.deploy = function (overrides) { - return _super.prototype.deploy.call(this, overrides || {}); - }; - VersionedERC721__factory.prototype.getDeployTransaction = function (overrides) { - return _super.prototype.getDeployTransaction.call(this, overrides || {}); - }; - VersionedERC721__factory.prototype.attach = function (address) { - return _super.prototype.attach.call(this, address); - }; - VersionedERC721__factory.prototype.connect = function (signer) { - return _super.prototype.connect.call(this, signer); - }; - VersionedERC721__factory.createInterface = function () { - return new ethers_1.utils.Interface(_abi); - }; - VersionedERC721__factory.connect = function (address, signerOrProvider) { - return new ethers_1.Contract(address, _abi, signerOrProvider); - }; - VersionedERC721__factory.bytecode = _bytecode; - VersionedERC721__factory.abi = _abi; - return VersionedERC721__factory; -}(ethers_1.ContractFactory)); -exports.VersionedERC721__factory = VersionedERC721__factory; diff --git a/desci-contracts/typechain-types/hardhat.d.ts b/desci-contracts/typechain-types/hardhat.d.ts index 49fd57e3..116bf02c 100644 --- a/desci-contracts/typechain-types/hardhat.d.ts +++ b/desci-contracts/typechain-types/hardhat.d.ts @@ -72,6 +72,10 @@ declare module "hardhat/types/runtime" { name: "IERC165", signerOrOptions?: ethers.Signer | FactoryOptions ): Promise; + getContractFactory( + name: "DpidAliasRegistry", + signerOrOptions?: ethers.Signer | FactoryOptions + ): Promise; getContractFactory( name: "DpidRegistry", signerOrOptions?: ethers.Signer | FactoryOptions @@ -180,6 +184,11 @@ declare module "hardhat/types/runtime" { address: string, signer?: ethers.Signer ): Promise; + getContractAt( + name: "DpidAliasRegistry", + address: string, + signer?: ethers.Signer + ): Promise; getContractAt( name: "DpidRegistry", address: string, diff --git a/desci-contracts/typechain-types/index.js b/desci-contracts/typechain-types/index.js deleted file mode 100644 index 62939d50..00000000 --- a/desci-contracts/typechain-types/index.js +++ /dev/null @@ -1,60 +0,0 @@ -"use strict"; -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -exports.__esModule = true; -exports.VersionedERC721V2__factory = exports.VersionedERC721__factory = exports.TestERC721__factory = exports.ResearchObjectV2__factory = exports.ResearchObject__factory = exports.ResearchObjectMigrated__factory = exports.IDpidRegistry__factory = exports.DpidRegistry__factory = exports.IERC165__factory = exports.ERC165__factory = exports.IERC721Receiver__factory = exports.IERC721__factory = exports.IERC721Metadata__factory = exports.ERC721__factory = exports.IERC165Upgradeable__factory = exports.ERC165Upgradeable__factory = exports.ContextUpgradeable__factory = exports.IERC721Upgradeable__factory = exports.IERC721ReceiverUpgradeable__factory = exports.IERC721MetadataUpgradeable__factory = exports.ERC721Upgradeable__factory = exports.Initializable__factory = exports.OwnableUpgradeable__factory = void 0; -var OwnableUpgradeable__factory_1 = require("./factories/OwnableUpgradeable__factory"); -__createBinding(exports, OwnableUpgradeable__factory_1, "OwnableUpgradeable__factory"); -var Initializable__factory_1 = require("./factories/Initializable__factory"); -__createBinding(exports, Initializable__factory_1, "Initializable__factory"); -var ERC721Upgradeable__factory_1 = require("./factories/ERC721Upgradeable__factory"); -__createBinding(exports, ERC721Upgradeable__factory_1, "ERC721Upgradeable__factory"); -var IERC721MetadataUpgradeable__factory_1 = require("./factories/IERC721MetadataUpgradeable__factory"); -__createBinding(exports, IERC721MetadataUpgradeable__factory_1, "IERC721MetadataUpgradeable__factory"); -var IERC721ReceiverUpgradeable__factory_1 = require("./factories/IERC721ReceiverUpgradeable__factory"); -__createBinding(exports, IERC721ReceiverUpgradeable__factory_1, "IERC721ReceiverUpgradeable__factory"); -var IERC721Upgradeable__factory_1 = require("./factories/IERC721Upgradeable__factory"); -__createBinding(exports, IERC721Upgradeable__factory_1, "IERC721Upgradeable__factory"); -var ContextUpgradeable__factory_1 = require("./factories/ContextUpgradeable__factory"); -__createBinding(exports, ContextUpgradeable__factory_1, "ContextUpgradeable__factory"); -var ERC165Upgradeable__factory_1 = require("./factories/ERC165Upgradeable__factory"); -__createBinding(exports, ERC165Upgradeable__factory_1, "ERC165Upgradeable__factory"); -var IERC165Upgradeable__factory_1 = require("./factories/IERC165Upgradeable__factory"); -__createBinding(exports, IERC165Upgradeable__factory_1, "IERC165Upgradeable__factory"); -var ERC721__factory_1 = require("./factories/ERC721__factory"); -__createBinding(exports, ERC721__factory_1, "ERC721__factory"); -var IERC721Metadata__factory_1 = require("./factories/IERC721Metadata__factory"); -__createBinding(exports, IERC721Metadata__factory_1, "IERC721Metadata__factory"); -var IERC721__factory_1 = require("./factories/IERC721__factory"); -__createBinding(exports, IERC721__factory_1, "IERC721__factory"); -var IERC721Receiver__factory_1 = require("./factories/IERC721Receiver__factory"); -__createBinding(exports, IERC721Receiver__factory_1, "IERC721Receiver__factory"); -var ERC165__factory_1 = require("./factories/ERC165__factory"); -__createBinding(exports, ERC165__factory_1, "ERC165__factory"); -var IERC165__factory_1 = require("./factories/IERC165__factory"); -__createBinding(exports, IERC165__factory_1, "IERC165__factory"); -var DpidRegistry__factory_1 = require("./factories/DpidRegistry__factory"); -__createBinding(exports, DpidRegistry__factory_1, "DpidRegistry__factory"); -var IDpidRegistry__factory_1 = require("./factories/IDpidRegistry__factory"); -__createBinding(exports, IDpidRegistry__factory_1, "IDpidRegistry__factory"); -var ResearchObjectMigrated__factory_1 = require("./factories/ResearchObjectMigrated__factory"); -__createBinding(exports, ResearchObjectMigrated__factory_1, "ResearchObjectMigrated__factory"); -var ResearchObject__factory_1 = require("./factories/ResearchObject__factory"); -__createBinding(exports, ResearchObject__factory_1, "ResearchObject__factory"); -var ResearchObjectV2__factory_1 = require("./factories/ResearchObjectV2__factory"); -__createBinding(exports, ResearchObjectV2__factory_1, "ResearchObjectV2__factory"); -var TestERC721__factory_1 = require("./factories/TestERC721__factory"); -__createBinding(exports, TestERC721__factory_1, "TestERC721__factory"); -var VersionedERC721__factory_1 = require("./factories/VersionedERC721__factory"); -__createBinding(exports, VersionedERC721__factory_1, "VersionedERC721__factory"); -var VersionedERC721V2__factory_1 = require("./factories/VersionedERC721V2__factory"); -__createBinding(exports, VersionedERC721V2__factory_1, "VersionedERC721V2__factory"); diff --git a/desci-contracts/typechain-types/index.ts b/desci-contracts/typechain-types/index.ts index 82c5030b..5b992f0f 100644 --- a/desci-contracts/typechain-types/index.ts +++ b/desci-contracts/typechain-types/index.ts @@ -16,6 +16,7 @@ export type { IERC721 } from "./IERC721"; export type { IERC721Receiver } from "./IERC721Receiver"; export type { ERC165 } from "./ERC165"; export type { IERC165 } from "./IERC165"; +export type { DpidAliasRegistry } from "./DpidAliasRegistry"; export type { DpidRegistry } from "./DpidRegistry"; export type { IDpidRegistry } from "./IDpidRegistry"; export type { ResearchObjectMigrated } from "./ResearchObjectMigrated"; @@ -40,6 +41,7 @@ export { IERC721__factory } from "./factories/IERC721__factory"; export { IERC721Receiver__factory } from "./factories/IERC721Receiver__factory"; export { ERC165__factory } from "./factories/ERC165__factory"; export { IERC165__factory } from "./factories/IERC165__factory"; +export { DpidAliasRegistry__factory } from "./factories/DpidAliasRegistry__factory"; export { DpidRegistry__factory } from "./factories/DpidRegistry__factory"; export { IDpidRegistry__factory } from "./factories/IDpidRegistry__factory"; export { ResearchObjectMigrated__factory } from "./factories/ResearchObjectMigrated__factory"; diff --git a/desci-contracts/yarn.lock b/desci-contracts/yarn.lock index 978088aa..5ba7f6ae 100644 --- a/desci-contracts/yarn.lock +++ b/desci-contracts/yarn.lock @@ -1784,6 +1784,13 @@ "@types/node" "*" "@types/responselike" "^1.0.0" +"@types/chai-as-promised@^7.1.8": + version "7.1.8" + resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz#f2b3d82d53c59626b5d6bbc087667ccb4b677fe9" + integrity sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw== + dependencies: + "@types/chai" "*" + "@types/chai@*", "@types/chai@^4.2.21": version "4.3.14" resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.14.tgz#ae3055ea2be43c91c9fd700a36d67820026d96e6" @@ -3613,6 +3620,13 @@ cborg@^1.5.4, cborg@^1.6.0: resolved "https://registry.yarnpkg.com/cborg/-/cborg-1.10.2.tgz#83cd581b55b3574c816f82696307c7512db759a1" integrity sha512-b3tFPA9pUr2zCUiCfRd2+wok2/LBSNUMKOuRRok+WlvvAgEt/PlbgPTsZUcwCOs53IJvLgTp0eotwtosE6njug== +chai-as-promised@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.2.tgz#70cd73b74afd519754161386421fb71832c6d041" + integrity sha512-aBDHZxRzYnUYuIAIPBH2s511DjlKPzXNlXSGFC8CwmroWQLfrW0LtE1nK3MAwwNhJPa9raEjNCmRoFpG0Hurdw== + dependencies: + check-error "^1.0.2" + chai@^4.3.4: version "4.4.1" resolved "https://registry.yarnpkg.com/chai/-/chai-4.4.1.tgz#3603fa6eba35425b0f2ac91a009fe924106e50d1" @@ -3667,7 +3681,7 @@ chalk@^4, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" integrity sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA== -check-error@^1.0.3: +check-error@^1.0.2, check-error@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.3.tgz#a6502e4312a7ee969f646e83bb3ddd56281bd694" integrity sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg== From e21aac51ae0ff0c57a24b58d706177394159fe87 Mon Sep 17 00:00:00 2001 From: m0ar Date: Mon, 20 May 2024 16:03:40 +0200 Subject: [PATCH 115/278] Move chai-as-promises to devdep --- desci-contracts/package.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/desci-contracts/package.json b/desci-contracts/package.json index e26bfb55..011c277b 100644 --- a/desci-contracts/package.json +++ b/desci-contracts/package.json @@ -45,6 +45,7 @@ "@types/node": "^16.4.10", "as-base64": "^0.2.0", "chai": "^4.3.4", + "chai-as-promised": "^7.1.2", "cids": "^1.1.9", "dotenv": "^10.0.0", "ethereum-waffle": "^3.4.0", @@ -62,7 +63,5 @@ "typechain": "^7.0.0", "typescript": "^4.3.5" }, - "dependencies": { - "chai-as-promised": "^7.1.2" - } + "dependencies": {} } From bc5a3dc3b2a2939075fe3806c227461cd1897aea Mon Sep 17 00:00:00 2001 From: m0ar Date: Thu, 23 May 2024 09:56:47 +0200 Subject: [PATCH 116/278] contracts: deploy alias registry in chain seeding --- desci-contracts/package.json | 5 +-- .../scripts/deployDpidAliasRegistry.js | 31 +++++++++++++++++++ desci-contracts/scripts/startTestChain.sh | 5 +++ 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 desci-contracts/scripts/deployDpidAliasRegistry.js diff --git a/desci-contracts/package.json b/desci-contracts/package.json index 011c277b..ac3089b4 100644 --- a/desci-contracts/package.json +++ b/desci-contracts/package.json @@ -1,16 +1,17 @@ { "name": "@desci-labs/desci-contracts", "description": "Smart contracts implementing DeSci Nodes on-chain state and logic", - "version": "0.2.3-rc3", + "version": "0.2.4", "license": "MIT", "scripts": { - "test": "hardhat clean && hardhat test test/DpidAliasRegistry.ts", + "test": "hardhat clean && hardhat test", "build": "hardhat compile --network ganache", "makePackage": "rm -rf dist && tsc && cp -r .openzeppelin dist", "docker:build": "docker build -t desci-hardhat-node .", "docker:push": "docker tag desci-hardhat-node:latest 523044037273.dkr.ecr.us-east-2.amazonaws.com/desci-hardhat-node:latest && docker push 523044037273.dkr.ecr.us-east-2.amazonaws.com/desci-hardhat-node:latest", "deploy:ganache": "yarn stubHardhatAnalytics && hardhat run scripts/deployResearchObject.js --network ganache", "deploy:dpid:ganache": "yarn stubHardhatAnalytics && hardhat run scripts/deployDpidRegistry.js --network ganache", + "deploy:alias:ganache": "yarn stubHardhatAnalytics && hardhat run scripts/deployDpidAliasRegistry.js --network ganache", "migrate": "hardhat run scripts/migrateToNewContract.js --network ganache && touch ./.openzeppelin/migration-complete.json", "graph:codegen": "graph codegen subgraph/subgraph.yaml -o subgraph/generated", "graph:build": "graph build subgraph/subgraph.yaml", diff --git a/desci-contracts/scripts/deployDpidAliasRegistry.js b/desci-contracts/scripts/deployDpidAliasRegistry.js new file mode 100644 index 00000000..c6d8efef --- /dev/null +++ b/desci-contracts/scripts/deployDpidAliasRegistry.js @@ -0,0 +1,31 @@ +const { ethers, upgrades } = require("hardhat"); +const fs = require('fs'); + +const FIRST_DPID = 500; + +console.log(process.cwd()) +async function main() { + fs.rmSync(".openzeppelin/unknown-dpid-alias-registry.json", { force: true }); + fs.rmSync(".openzeppelin/unknown-1337.json", { force: true }); + + const DpidAliasRegistry = await ethers.getContractFactory("DpidAliasRegistry"); + console.log("[deployDpidAliasRegistry] Deploying DpidAliasRegistry..."); + const proxy = await upgrades.deployProxy( + DpidAliasRegistry, + [ + FIRST_DPID // firstDpid + ], + { + initializer: "__DpidAliasRegistry_init" + } + ); + await proxy.deployed(); + console.log("[deployDpidRegistry] DpidAliasRegistry deployed to:", proxy.address); + + fs.renameSync( + ".openzeppelin/unknown-1337.json", + ".openzeppelin/unknown-dpid-alias-registry.json", + ); +}; + +main(); diff --git a/desci-contracts/scripts/startTestChain.sh b/desci-contracts/scripts/startTestChain.sh index a72377a4..5b30987d 100755 --- a/desci-contracts/scripts/startTestChain.sh +++ b/desci-contracts/scripts/startTestChain.sh @@ -32,6 +32,11 @@ checkTestDeployments() { echo "[startTestChain] deploying RO contract..." yarn deploy:ganache fi + + if ! scripts/checkTestDeployments.sh ".openzeppelin/unknown-dpid-alias-registry.json"; then + echo "[startTestChain] deploying dpid alias registry..." + yarn deploy:alias:ganache + fi } waitForPostgres() { From 0ce077214afc1c1f6de41e933e441d89a2f0712b Mon Sep 17 00:00:00 2001 From: m0ar Date: Fri, 24 May 2024 12:12:32 +0200 Subject: [PATCH 117/278] contracts: tweak alias registry, add migration script, update typechain artefacts --- .../DpidAliasRegistry.json | 14 ++--- .../contracts/DpidAliasRegistry.sol | 15 +++-- desci-contracts/hardhat.config.ts | 2 - desci-contracts/index.ts | 2 + desci-contracts/package.json | 2 +- .../scripts/migrateToAliasRegistry.mjs | 61 +++++++++++++++++++ desci-contracts/test/DpidAliasRegistry.ts | 4 +- .../typechain-types/DpidAliasRegistry.ts | 33 +++++----- .../factories/DpidAliasRegistry__factory.ts | 12 ++-- 9 files changed, 103 insertions(+), 42 deletions(-) create mode 100644 desci-contracts/scripts/migrateToAliasRegistry.mjs diff --git a/desci-contracts/artifacts/contracts/DpidAliasRegistry.sol/DpidAliasRegistry.json b/desci-contracts/artifacts/contracts/DpidAliasRegistry.sol/DpidAliasRegistry.json index 24c64307..51effc33 100644 --- a/desci-contracts/artifacts/contracts/DpidAliasRegistry.sol/DpidAliasRegistry.json +++ b/desci-contracts/artifacts/contracts/DpidAliasRegistry.sol/DpidAliasRegistry.json @@ -52,7 +52,7 @@ }, { "internalType": "uint256", - "name": "timestamp", + "name": "time", "type": "uint256" } ], @@ -125,7 +125,7 @@ "inputs": [ { "internalType": "uint256", - "name": "firstDpid", + "name": "_firstDpid", "type": "uint256" } ], @@ -136,7 +136,7 @@ }, { "inputs": [], - "name": "_firstDpid", + "name": "firstDpid", "outputs": [ { "internalType": "uint256", @@ -170,7 +170,7 @@ }, { "internalType": "uint256", - "name": "timestamp", + "name": "time", "type": "uint256" } ], @@ -234,7 +234,7 @@ }, { "internalType": "uint256", - "name": "timestamp", + "name": "time", "type": "uint256" } ], @@ -373,8 +373,8 @@ "type": "function" } ], - "bytecode": "0x60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d3565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000127565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff161015620000ed5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e4919062000149565b60405180910390a15b565b6000620000fe60278362000166565b91506200010b8262000184565b604082019050919050565b620001218162000177565b82525050565b600060208201905081810360008301526200014281620000ef565b9050919050565b600060208201905062000160600083018462000116565b92915050565b600082825260208201905092915050565b600060ff82169050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b6122cb80620001e36000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c8063810a9afa1161008c578063b724de3a11610066578063b724de3a14610212578063dc5d7a2e14610242578063ded8896b14610260578063f2fde38b1461027c576100cf565b8063810a9afa146101a65780638da5cb5b146101d6578063afc26911146101f4576100cf565b80630a874df6146100d4578063144ae85514610104578063362b3e63146101205780635893253c1461013c578063715018a61461016c578063788243d514610176575b600080fd5b6100ee60048036038101906100e99190610dff565b610298565b6040516100fb919061131c565b60405180910390f35b61011e60048036038101906101199190610e80565b61033d565b005b61013a60048036038101906101359190610dff565b6103a5565b005b61015660048036038101906101519190610dff565b6104eb565b604051610163919061131c565b60405180910390f35b61017461058b565b005b610190600480360381019061018b9190610dff565b61059f565b60405161019d91906112e6565b60405180910390f35b6101c060048036038101906101bb9190610dff565b6105dd565b6040516101cd91906113fe565b60405180910390f35b6101de61075b565b6040516101eb91906112e6565b60405180910390f35b6101fc610785565b6040516102099190611420565b60405180910390f35b61022c60048036038101906102279190610dba565b61078b565b6040516102399190611420565b60405180910390f35b61024a610813565b6040516102579190611420565b60405180910390f35b61027a60048036038101906102759190610e28565b610819565b005b61029660048036038101906102919190610d91565b610982565b005b60606067600083815260200190815260200160002080546102b890611c27565b80601f01602080910402602001604051908101604052809291908181526020018280546102e490611c27565b80156103315780601f1061030657610100808354040283529160200191610331565b820191906000526020600020905b81548152906001019060200180831161031457829003601f168201915b50505050509050919050565b610345610a06565b8060686000848152602001908152602001600020818161036591906121ee565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada828260405161039992919061146d565b60405180910390a15050565b60008060019054906101000a900460ff161590508080156103d65750600160008054906101000a900460ff1660ff16105b8061040357506103e530610a84565b1580156104025750600160008054906101000a900460ff1660ff16145b5b610442576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104399061137e565b60405180910390fd5b60016000806101000a81548160ff021916908360ff160217905550801561047f576001600060016101000a81548160ff0219169083151502179055505b610487610aa7565b8160668190555080156104e75760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516104de9190611301565b60405180910390a15b5050565b6067602052806000526040600020600091509050805461050a90611c27565b80601f016020809104026020016040519081016040528092919081815260200182805461053690611c27565b80156105835780601f1061055857610100808354040283529160200191610583565b820191906000526020600020905b81548152906001019060200180831161056657829003601f168201915b505050505081565b610593610a06565b61059d6000610b00565b565b60686020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b6105e5610c2f565b606860008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b8282101561074c57838290600052602060002090600202016040518060400160405290816000820180546106b190611c27565b80601f01602080910402602001604051908101604052809291908181526020018280546106dd90611c27565b801561072a5780601f106106ff5761010080835404028352916020019161072a565b820191906000526020600020905b81548152906001019060200180831161070d57829003601f168201915b505050505081526020016001820154815250508152602001906001019061067e565b50505050815250509050919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60665481565b600080606654905083836067600084815260200190815260200160002091906107b5929190610c5f565b507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d8185856040516107e99392919061143b565b60405180910390a16066600081548092919061080490611c75565b91905055508091505092915050565b60655481565b600060676000858152602001908152602001600020805461083990611c27565b90501461087b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108729061133e565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff166068600085815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461091f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610916906113de565b60405180910390fd5b8181606760008681526020019081526020016000209190610941929190610c5f565b507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c8383836040516109759392919061143b565b60405180910390a1505050565b61098a610a06565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156109fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109f19061135e565b60405180910390fd5b610a0381610b00565b50565b610a0e610bc6565b73ffffffffffffffffffffffffffffffffffffffff16610a2c61075b565b73ffffffffffffffffffffffffffffffffffffffff1614610a82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a799061139e565b60405180910390fd5b565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610af6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aed906113be565b60405180910390fd5b610afe610bce565b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600060019054906101000a900460ff16610c1d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c14906113be565b60405180910390fd5b610c2d610c28610bc6565b610b00565b565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b828054610c6b90611c27565b90600052602060002090601f016020900481019282610c8d5760008555610cd4565b82601f10610ca657803560ff1916838001178555610cd4565b82800160010185558215610cd4579182015b82811115610cd3578235825591602001919060010190610cb8565b5b509050610ce19190610ce5565b5090565b5b80821115610cfe576000816000905550600101610ce6565b5090565b600081359050610d1181612262565b92915050565b60008083601f840112610d2957600080fd5b8235905067ffffffffffffffff811115610d4257600080fd5b602083019150836001820283011115610d5a57600080fd5b9250929050565b600060408284031215610d7357600080fd5b81905092915050565b600081359050610d8b81612279565b92915050565b600060208284031215610da357600080fd5b6000610db184828501610d02565b91505092915050565b60008060208385031215610dcd57600080fd5b600083013567ffffffffffffffff811115610de757600080fd5b610df385828601610d17565b92509250509250929050565b600060208284031215610e1157600080fd5b6000610e1f84828501610d7c565b91505092915050565b600080600060408486031215610e3d57600080fd5b6000610e4b86828701610d7c565b935050602084013567ffffffffffffffff811115610e6857600080fd5b610e7486828701610d17565b92509250509250925092565b60008060408385031215610e9357600080fd5b6000610ea185828601610d7c565b925050602083013567ffffffffffffffff811115610ebe57600080fd5b610eca85828601610d61565b9150509250929050565b6000610ee0838361123c565b905092915050565b6000610ef4838361128b565b905092915050565b610f05816118ad565b82525050565b610f14816118ad565b82525050565b6000610f26838561161b565b935083602084028501610f3884611586565b8060005b87811015610f7c578484038952610f538284611818565b610f5d8582610ed4565b9450610f6883611601565b925060208a01995050600181019050610f3c565b50829750879450505050509392505050565b6000610f99826115d5565b610fa3818561161b565b935083602082028501610fb585611590565b8060005b85811015610ff15784840389528151610fd28582610ee8565b9450610fdd8361160e565b925060208a01995050600181019050610fb9565b50829750879550505050505092915050565b61100c8161199c565b82525050565b600061101e838561162c565b935061102b838584611b59565b61103483611ecc565b840190509392505050565b600061104b838561163d565b9350611058838584611b59565b61106183611ecc565b840190509392505050565b6000611077826115f6565b611081818561162c565b9350611091818560208601611b68565b61109a81611ecc565b840191505092915050565b60006110b0826115f6565b6110ba818561163d565b93506110ca818560208601611b68565b6110d381611ecc565b840191505092915050565b60006110eb60158361163d565b91506110f682611f58565b602082019050919050565b600061110e60268361163d565b915061111982611f81565b604082019050919050565b6000611131602e8361163d565b915061113c82611fd0565b604082019050919050565b600061115460208361163d565b915061115f8261201f565b602082019050919050565b6000611177602b8361163d565b915061118282612048565b604082019050919050565b600061119a60198361163d565b91506111a582612097565b602082019050919050565b6000604083016111c36000840184611753565b6111d06000860182610efc565b506111de602084018461176a565b85830360208701526111f1838284610f1a565b925050508091505092915050565b60006040830160008301516112176000860182610efc565b506020830151848203602086015261122f8282610f8e565b9150508091505092915050565b60006040830161124f60008401846117c1565b8583036000870152611262838284611012565b92505050611273602084018461183c565b61128060208601826112c8565b508091505092915050565b600060408301600083015184820360008601526112a8828261106c565b91505060208301516112bd60208601826112c8565b508091505092915050565b6112d1816118df565b82525050565b6112e0816118df565b82525050565b60006020820190506112fb6000830184610f0b565b92915050565b60006020820190506113166000830184611003565b92915050565b6000602082019050818103600083015261133681846110a5565b905092915050565b60006020820190508181036000830152611357816110de565b9050919050565b6000602082019050818103600083015261137781611101565b9050919050565b6000602082019050818103600083015261139781611124565b9050919050565b600060208201905081810360008301526113b781611147565b9050919050565b600060208201905081810360008301526113d78161116a565b9050919050565b600060208201905081810360008301526113f78161118d565b9050919050565b6000602082019050818103600083015261141881846111ff565b905092915050565b600060208201905061143560008301846112d7565b92915050565b600060408201905061145060008301866112d7565b818103602083015261146381848661103f565b9050949350505050565b600060408201905061148260008301856112d7565b818103602083015261149481846111b0565b90509392505050565b600080833560016020038436030381126114b657600080fd5b80840192508235915067ffffffffffffffff8211156114d457600080fd5b6020830192506020820236038313156114ec57600080fd5b509250929050565b6000808335600160200384360303811261150d57600080fd5b80840192508235915067ffffffffffffffff82111561152b57600080fd5b60208301925060018202360383131561154357600080fd5b509250929050565b60008235600160400383360303811261156357600080fd5b80830191505092915050565b600081905061157f826002611853565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b60208410600081146116a757601f841160018114611677576116708685611c59565b83556116a1565b611680836115b5565b6116956020601f880104820160018301611904565b61169f87856120c0565b505b506116f0565b6116b0826115b5565b6020601f8701048101601f871680156116d1576116d08160018403611d98565b5b6116e36020601f890104840183611904565b6001886002021785555050505b5050505050565b6020831060008114611742576020851060008114611720576117198685611c59565b835561173c565b8360ff1916935083611731846115b5565b556001866002020183555b5061174c565b6001856002020182555b5050505050565b60006117626020840184610d02565b905092915050565b6000808335600160200384360303811261178357600080fd5b83810192508235915060208301925067ffffffffffffffff8211156117a757600080fd5b6020820236038413156117b957600080fd5b509250929050565b600080833560016020038436030381126117da57600080fd5b83810192508235915060208301925067ffffffffffffffff8211156117fe57600080fd5b60018202360384131561181057600080fd5b509250929050565b60008235600160400383360303811261183057600080fd5b82810191505092915050565b600061184b6020840184610d7c565b905092915050565b600061185e826118df565b9150611869836118df565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156118a2576118a1611d0b565b5b828202905092915050565b60006118b8826118bf565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b611901600082611e77565b50565b5b8181101561192357611918600082611f40565b600181019050611905565b5050565b5b818110156119465761193b600082611f22565b600281019050611928565b5050565b818110156119685761195d600082611f40565b60018101905061194a565b5050565b6119796000808301611f04565b611987600060018301611f40565b50565b6000611995826119ae565b9050919050565b60006119a7826118e9565b9050919050565b60006119b9826119c0565b9050919050565b60006119cb826118bf565b9050919050565b60006119dd826118df565b9050919050565b6119ee83836115ca565b6119f88183611e13565b611a0183611586565b611a0a836115a0565b6000805b84811015611a4357611a20848861154b565b611a2b81848661221f565b60208501945060028401935050600181019050611a0e565b5050505050505050565b611a5783836115eb565b67ffffffffffffffff811115611a7057611a6f611d69565b5b611a7a8254611c27565b600080601f8411601f84111715611a9757611a94856115b5565b90505b601f831115611aca576020601f85010481016020851015611ab6578190505b611ac86020601f860104830182611904565b505b601f841160018114611af75760008515611ae5578388013590505b611aef8682611c59565b875550611b4f565b601f1985168260005b82811015611b2557858a01358255600182019150602086019550602081019050611b00565b87831015611b4257858a0135611b3e601f8a1682611cbe565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b83811015611b86578082015181840152602081019050611b6b565b83811115611b95576000848401525b50505050565b600081016000830180611bad81611de7565b9050611bb981846121ab565b5050506001810160208301611bce818561149d565b611bd98183866121ce565b505050505050565b6000810160008301611bf381856114f4565b611bfe8183866121de565b50505050600181016020830180611c1481611dfd565b9050611c2081846121fc565b5050505050565b60006002820490506001821680611c3f57607f821691505b60208210811415611c5357611c52611d3a565b5b50919050565b6000611c658383611cbe565b9150826002028217905092915050565b6000611c80826118df565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415611cb357611cb2611d0b565b5b600182019050919050565b6000611ccf60001984600802611ef7565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611dc87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83602003600802611ef7565b815481168255505050565b6000819050919050565b6000819050919050565b60008135611df481612262565b80915050919050565b60008135611e0a81612279565b80915050919050565b68010000000000000000821115611e2d57611e2c611d69565b5b611e36816115e0565b82825580831015611e7257611e4a8161156f565b611e538461156f565b611e5c846115a0565b818101838201611e6c8183611927565b50505050505b505050565b68010000000000000000821115611e9157611e90611d69565b5b8054611e9c81611c27565b80841115611eb157611eb0848284866116f7565b5b80841015611ec657611ec58482848661164e565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b60008214611f1557611f14611cdc565b5b611f1e816118f6565b5050565b60008214611f3357611f32611cdc565b5b611f3c8161196c565b5050565b611f48612290565b611f5381848461223d565b505050565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b6120c9816115b5565b6120d4838254611c59565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff61210184611edd565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61214384611edd565b9350801983169250808416831791505092915050565b6000600883026121897fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82611eea565b6121938683611eea565b95508019841693508086168417925050509392505050565b6121b48261198a565b6121c76121c082611dd3565b83546120e1565b8255505050565b6121d98383836119e4565b505050565b6121e9838383611a4d565b505050565b6121f88282611b9b565b5050565b612205826119d2565b61221861221182611ddd565b8354612117565b8255505050565b811561222e5761222d611cdc565b5b6122388382611be1565b505050565b612246836119d2565b61225a61225282611ddd565b848454612159565b825550505050565b61226b816118ad565b811461227657600080fd5b50565b612282816118df565b811461228d57600080fd5b50565b60009056fea26469706673582212209d15c5501273e10408c38b0c27c1d9008c55404af21e411dc9d13c190f83a2b364736f6c63430008040033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100cf5760003560e01c8063810a9afa1161008c578063b724de3a11610066578063b724de3a14610212578063dc5d7a2e14610242578063ded8896b14610260578063f2fde38b1461027c576100cf565b8063810a9afa146101a65780638da5cb5b146101d6578063afc26911146101f4576100cf565b80630a874df6146100d4578063144ae85514610104578063362b3e63146101205780635893253c1461013c578063715018a61461016c578063788243d514610176575b600080fd5b6100ee60048036038101906100e99190610dff565b610298565b6040516100fb919061131c565b60405180910390f35b61011e60048036038101906101199190610e80565b61033d565b005b61013a60048036038101906101359190610dff565b6103a5565b005b61015660048036038101906101519190610dff565b6104eb565b604051610163919061131c565b60405180910390f35b61017461058b565b005b610190600480360381019061018b9190610dff565b61059f565b60405161019d91906112e6565b60405180910390f35b6101c060048036038101906101bb9190610dff565b6105dd565b6040516101cd91906113fe565b60405180910390f35b6101de61075b565b6040516101eb91906112e6565b60405180910390f35b6101fc610785565b6040516102099190611420565b60405180910390f35b61022c60048036038101906102279190610dba565b61078b565b6040516102399190611420565b60405180910390f35b61024a610813565b6040516102579190611420565b60405180910390f35b61027a60048036038101906102759190610e28565b610819565b005b61029660048036038101906102919190610d91565b610982565b005b60606067600083815260200190815260200160002080546102b890611c27565b80601f01602080910402602001604051908101604052809291908181526020018280546102e490611c27565b80156103315780601f1061030657610100808354040283529160200191610331565b820191906000526020600020905b81548152906001019060200180831161031457829003601f168201915b50505050509050919050565b610345610a06565b8060686000848152602001908152602001600020818161036591906121ee565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada828260405161039992919061146d565b60405180910390a15050565b60008060019054906101000a900460ff161590508080156103d65750600160008054906101000a900460ff1660ff16105b8061040357506103e530610a84565b1580156104025750600160008054906101000a900460ff1660ff16145b5b610442576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104399061137e565b60405180910390fd5b60016000806101000a81548160ff021916908360ff160217905550801561047f576001600060016101000a81548160ff0219169083151502179055505b610487610aa7565b8160668190555080156104e75760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516104de9190611301565b60405180910390a15b5050565b6067602052806000526040600020600091509050805461050a90611c27565b80601f016020809104026020016040519081016040528092919081815260200182805461053690611c27565b80156105835780601f1061055857610100808354040283529160200191610583565b820191906000526020600020905b81548152906001019060200180831161056657829003601f168201915b505050505081565b610593610a06565b61059d6000610b00565b565b60686020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b6105e5610c2f565b606860008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b8282101561074c57838290600052602060002090600202016040518060400160405290816000820180546106b190611c27565b80601f01602080910402602001604051908101604052809291908181526020018280546106dd90611c27565b801561072a5780601f106106ff5761010080835404028352916020019161072a565b820191906000526020600020905b81548152906001019060200180831161070d57829003601f168201915b505050505081526020016001820154815250508152602001906001019061067e565b50505050815250509050919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60665481565b600080606654905083836067600084815260200190815260200160002091906107b5929190610c5f565b507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d8185856040516107e99392919061143b565b60405180910390a16066600081548092919061080490611c75565b91905055508091505092915050565b60655481565b600060676000858152602001908152602001600020805461083990611c27565b90501461087b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108729061133e565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff166068600085815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461091f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610916906113de565b60405180910390fd5b8181606760008681526020019081526020016000209190610941929190610c5f565b507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c8383836040516109759392919061143b565b60405180910390a1505050565b61098a610a06565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156109fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109f19061135e565b60405180910390fd5b610a0381610b00565b50565b610a0e610bc6565b73ffffffffffffffffffffffffffffffffffffffff16610a2c61075b565b73ffffffffffffffffffffffffffffffffffffffff1614610a82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a799061139e565b60405180910390fd5b565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610af6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aed906113be565b60405180910390fd5b610afe610bce565b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600060019054906101000a900460ff16610c1d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c14906113be565b60405180910390fd5b610c2d610c28610bc6565b610b00565b565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b828054610c6b90611c27565b90600052602060002090601f016020900481019282610c8d5760008555610cd4565b82601f10610ca657803560ff1916838001178555610cd4565b82800160010185558215610cd4579182015b82811115610cd3578235825591602001919060010190610cb8565b5b509050610ce19190610ce5565b5090565b5b80821115610cfe576000816000905550600101610ce6565b5090565b600081359050610d1181612262565b92915050565b60008083601f840112610d2957600080fd5b8235905067ffffffffffffffff811115610d4257600080fd5b602083019150836001820283011115610d5a57600080fd5b9250929050565b600060408284031215610d7357600080fd5b81905092915050565b600081359050610d8b81612279565b92915050565b600060208284031215610da357600080fd5b6000610db184828501610d02565b91505092915050565b60008060208385031215610dcd57600080fd5b600083013567ffffffffffffffff811115610de757600080fd5b610df385828601610d17565b92509250509250929050565b600060208284031215610e1157600080fd5b6000610e1f84828501610d7c565b91505092915050565b600080600060408486031215610e3d57600080fd5b6000610e4b86828701610d7c565b935050602084013567ffffffffffffffff811115610e6857600080fd5b610e7486828701610d17565b92509250509250925092565b60008060408385031215610e9357600080fd5b6000610ea185828601610d7c565b925050602083013567ffffffffffffffff811115610ebe57600080fd5b610eca85828601610d61565b9150509250929050565b6000610ee0838361123c565b905092915050565b6000610ef4838361128b565b905092915050565b610f05816118ad565b82525050565b610f14816118ad565b82525050565b6000610f26838561161b565b935083602084028501610f3884611586565b8060005b87811015610f7c578484038952610f538284611818565b610f5d8582610ed4565b9450610f6883611601565b925060208a01995050600181019050610f3c565b50829750879450505050509392505050565b6000610f99826115d5565b610fa3818561161b565b935083602082028501610fb585611590565b8060005b85811015610ff15784840389528151610fd28582610ee8565b9450610fdd8361160e565b925060208a01995050600181019050610fb9565b50829750879550505050505092915050565b61100c8161199c565b82525050565b600061101e838561162c565b935061102b838584611b59565b61103483611ecc565b840190509392505050565b600061104b838561163d565b9350611058838584611b59565b61106183611ecc565b840190509392505050565b6000611077826115f6565b611081818561162c565b9350611091818560208601611b68565b61109a81611ecc565b840191505092915050565b60006110b0826115f6565b6110ba818561163d565b93506110ca818560208601611b68565b6110d381611ecc565b840191505092915050565b60006110eb60158361163d565b91506110f682611f58565b602082019050919050565b600061110e60268361163d565b915061111982611f81565b604082019050919050565b6000611131602e8361163d565b915061113c82611fd0565b604082019050919050565b600061115460208361163d565b915061115f8261201f565b602082019050919050565b6000611177602b8361163d565b915061118282612048565b604082019050919050565b600061119a60198361163d565b91506111a582612097565b602082019050919050565b6000604083016111c36000840184611753565b6111d06000860182610efc565b506111de602084018461176a565b85830360208701526111f1838284610f1a565b925050508091505092915050565b60006040830160008301516112176000860182610efc565b506020830151848203602086015261122f8282610f8e565b9150508091505092915050565b60006040830161124f60008401846117c1565b8583036000870152611262838284611012565b92505050611273602084018461183c565b61128060208601826112c8565b508091505092915050565b600060408301600083015184820360008601526112a8828261106c565b91505060208301516112bd60208601826112c8565b508091505092915050565b6112d1816118df565b82525050565b6112e0816118df565b82525050565b60006020820190506112fb6000830184610f0b565b92915050565b60006020820190506113166000830184611003565b92915050565b6000602082019050818103600083015261133681846110a5565b905092915050565b60006020820190508181036000830152611357816110de565b9050919050565b6000602082019050818103600083015261137781611101565b9050919050565b6000602082019050818103600083015261139781611124565b9050919050565b600060208201905081810360008301526113b781611147565b9050919050565b600060208201905081810360008301526113d78161116a565b9050919050565b600060208201905081810360008301526113f78161118d565b9050919050565b6000602082019050818103600083015261141881846111ff565b905092915050565b600060208201905061143560008301846112d7565b92915050565b600060408201905061145060008301866112d7565b818103602083015261146381848661103f565b9050949350505050565b600060408201905061148260008301856112d7565b818103602083015261149481846111b0565b90509392505050565b600080833560016020038436030381126114b657600080fd5b80840192508235915067ffffffffffffffff8211156114d457600080fd5b6020830192506020820236038313156114ec57600080fd5b509250929050565b6000808335600160200384360303811261150d57600080fd5b80840192508235915067ffffffffffffffff82111561152b57600080fd5b60208301925060018202360383131561154357600080fd5b509250929050565b60008235600160400383360303811261156357600080fd5b80830191505092915050565b600081905061157f826002611853565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b60208410600081146116a757601f841160018114611677576116708685611c59565b83556116a1565b611680836115b5565b6116956020601f880104820160018301611904565b61169f87856120c0565b505b506116f0565b6116b0826115b5565b6020601f8701048101601f871680156116d1576116d08160018403611d98565b5b6116e36020601f890104840183611904565b6001886002021785555050505b5050505050565b6020831060008114611742576020851060008114611720576117198685611c59565b835561173c565b8360ff1916935083611731846115b5565b556001866002020183555b5061174c565b6001856002020182555b5050505050565b60006117626020840184610d02565b905092915050565b6000808335600160200384360303811261178357600080fd5b83810192508235915060208301925067ffffffffffffffff8211156117a757600080fd5b6020820236038413156117b957600080fd5b509250929050565b600080833560016020038436030381126117da57600080fd5b83810192508235915060208301925067ffffffffffffffff8211156117fe57600080fd5b60018202360384131561181057600080fd5b509250929050565b60008235600160400383360303811261183057600080fd5b82810191505092915050565b600061184b6020840184610d7c565b905092915050565b600061185e826118df565b9150611869836118df565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156118a2576118a1611d0b565b5b828202905092915050565b60006118b8826118bf565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b611901600082611e77565b50565b5b8181101561192357611918600082611f40565b600181019050611905565b5050565b5b818110156119465761193b600082611f22565b600281019050611928565b5050565b818110156119685761195d600082611f40565b60018101905061194a565b5050565b6119796000808301611f04565b611987600060018301611f40565b50565b6000611995826119ae565b9050919050565b60006119a7826118e9565b9050919050565b60006119b9826119c0565b9050919050565b60006119cb826118bf565b9050919050565b60006119dd826118df565b9050919050565b6119ee83836115ca565b6119f88183611e13565b611a0183611586565b611a0a836115a0565b6000805b84811015611a4357611a20848861154b565b611a2b81848661221f565b60208501945060028401935050600181019050611a0e565b5050505050505050565b611a5783836115eb565b67ffffffffffffffff811115611a7057611a6f611d69565b5b611a7a8254611c27565b600080601f8411601f84111715611a9757611a94856115b5565b90505b601f831115611aca576020601f85010481016020851015611ab6578190505b611ac86020601f860104830182611904565b505b601f841160018114611af75760008515611ae5578388013590505b611aef8682611c59565b875550611b4f565b601f1985168260005b82811015611b2557858a01358255600182019150602086019550602081019050611b00565b87831015611b4257858a0135611b3e601f8a1682611cbe565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b83811015611b86578082015181840152602081019050611b6b565b83811115611b95576000848401525b50505050565b600081016000830180611bad81611de7565b9050611bb981846121ab565b5050506001810160208301611bce818561149d565b611bd98183866121ce565b505050505050565b6000810160008301611bf381856114f4565b611bfe8183866121de565b50505050600181016020830180611c1481611dfd565b9050611c2081846121fc565b5050505050565b60006002820490506001821680611c3f57607f821691505b60208210811415611c5357611c52611d3a565b5b50919050565b6000611c658383611cbe565b9150826002028217905092915050565b6000611c80826118df565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415611cb357611cb2611d0b565b5b600182019050919050565b6000611ccf60001984600802611ef7565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611dc87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83602003600802611ef7565b815481168255505050565b6000819050919050565b6000819050919050565b60008135611df481612262565b80915050919050565b60008135611e0a81612279565b80915050919050565b68010000000000000000821115611e2d57611e2c611d69565b5b611e36816115e0565b82825580831015611e7257611e4a8161156f565b611e538461156f565b611e5c846115a0565b818101838201611e6c8183611927565b50505050505b505050565b68010000000000000000821115611e9157611e90611d69565b5b8054611e9c81611c27565b80841115611eb157611eb0848284866116f7565b5b80841015611ec657611ec58482848661164e565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b60008214611f1557611f14611cdc565b5b611f1e816118f6565b5050565b60008214611f3357611f32611cdc565b5b611f3c8161196c565b5050565b611f48612290565b611f5381848461223d565b505050565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b6120c9816115b5565b6120d4838254611c59565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff61210184611edd565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61214384611edd565b9350801983169250808416831791505092915050565b6000600883026121897fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82611eea565b6121938683611eea565b95508019841693508086168417925050509392505050565b6121b48261198a565b6121c76121c082611dd3565b83546120e1565b8255505050565b6121d98383836119e4565b505050565b6121e9838383611a4d565b505050565b6121f88282611b9b565b5050565b612205826119d2565b61221861221182611ddd565b8354612117565b8255505050565b811561222e5761222d611cdc565b5b6122388382611be1565b505050565b612246836119d2565b61225a61225282611ddd565b848454612159565b825550505050565b61226b816118ad565b811461227657600080fd5b50565b612282816118df565b811461228d57600080fd5b50565b60009056fea26469706673582212209d15c5501273e10408c38b0c27c1d9008c55404af21e411dc9d13c190f83a2b364736f6c63430008040033", + "bytecode": "0x60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d3565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000127565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff161015620000ed5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e4919062000149565b60405180910390a15b565b6000620000fe60278362000166565b91506200010b8262000184565b604082019050919050565b620001218162000177565b82525050565b600060208201905081810360008301526200014281620000ef565b9050919050565b600060208201905062000160600083018462000116565b92915050565b600082825260208201905092915050565b600060ff82169050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b6122d280620001e36000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c8063810a9afa1161008c578063b724de3a11610066578063b724de3a14610212578063cfb452b514610242578063ded8896b14610260578063f2fde38b1461027c576100cf565b8063810a9afa146101a65780638da5cb5b146101d6578063afc26911146101f4576100cf565b80630a874df6146100d4578063144ae85514610104578063362b3e63146101205780635893253c1461013c578063715018a61461016c578063788243d514610176575b600080fd5b6100ee60048036038101906100e99190610e06565b610298565b6040516100fb9190611323565b60405180910390f35b61011e60048036038101906101199190610e87565b61033d565b005b61013a60048036038101906101359190610e06565b6103a5565b005b61015660048036038101906101519190610e06565b6104f2565b6040516101639190611323565b60405180910390f35b610174610592565b005b610190600480360381019061018b9190610e06565b6105a6565b60405161019d91906112ed565b60405180910390f35b6101c060048036038101906101bb9190610e06565b6105e4565b6040516101cd9190611405565b60405180910390f35b6101de610762565b6040516101eb91906112ed565b60405180910390f35b6101fc61078c565b6040516102099190611427565b60405180910390f35b61022c60048036038101906102279190610dc1565b610792565b6040516102399190611427565b60405180910390f35b61024a61081a565b6040516102579190611427565b60405180910390f35b61027a60048036038101906102759190610e2f565b610820565b005b61029660048036038101906102919190610d98565b610989565b005b60606067600083815260200190815260200160002080546102b890611c2e565b80601f01602080910402602001604051908101604052809291908181526020018280546102e490611c2e565b80156103315780601f1061030657610100808354040283529160200191610331565b820191906000526020600020905b81548152906001019060200180831161031457829003601f168201915b50505050509050919050565b610345610a0d565b8060686000848152602001908152602001600020818161036591906121f5565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada8282604051610399929190611474565b60405180910390a15050565b60008060019054906101000a900460ff161590508080156103d65750600160008054906101000a900460ff1660ff16105b8061040357506103e530610a8b565b1580156104025750600160008054906101000a900460ff1660ff16145b5b610442576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161043990611385565b60405180910390fd5b60016000806101000a81548160ff021916908360ff160217905550801561047f576001600060016101000a81548160ff0219169083151502179055505b610487610aae565b816065819055508160668190555080156104ee5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516104e59190611308565b60405180910390a15b5050565b6067602052806000526040600020600091509050805461051190611c2e565b80601f016020809104026020016040519081016040528092919081815260200182805461053d90611c2e565b801561058a5780601f1061055f5761010080835404028352916020019161058a565b820191906000526020600020905b81548152906001019060200180831161056d57829003601f168201915b505050505081565b61059a610a0d565b6105a46000610b07565b565b60686020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b6105ec610c36565b606860008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b8282101561075357838290600052602060002090600202016040518060400160405290816000820180546106b890611c2e565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490611c2e565b80156107315780601f1061070657610100808354040283529160200191610731565b820191906000526020600020905b81548152906001019060200180831161071457829003601f168201915b5050505050815260200160018201548152505081526020019060010190610685565b50505050815250509050919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60665481565b600080606654905083836067600084815260200190815260200160002091906107bc929190610c66565b507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d8185856040516107f093929190611442565b60405180910390a16066600081548092919061080b90611c7c565b91905055508091505092915050565b60655481565b600060676000858152602001908152602001600020805461084090611c2e565b905014610882576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161087990611345565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166068600085815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610926576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091d906113e5565b60405180910390fd5b8181606760008681526020019081526020016000209190610948929190610c66565b507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c83838360405161097c93929190611442565b60405180910390a1505050565b610991610a0d565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610a01576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109f890611365565b60405180910390fd5b610a0a81610b07565b50565b610a15610bcd565b73ffffffffffffffffffffffffffffffffffffffff16610a33610762565b73ffffffffffffffffffffffffffffffffffffffff1614610a89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a80906113a5565b60405180910390fd5b565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610afd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af4906113c5565b60405180910390fd5b610b05610bd5565b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600060019054906101000a900460ff16610c24576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1b906113c5565b60405180910390fd5b610c34610c2f610bcd565b610b07565b565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b828054610c7290611c2e565b90600052602060002090601f016020900481019282610c945760008555610cdb565b82601f10610cad57803560ff1916838001178555610cdb565b82800160010185558215610cdb579182015b82811115610cda578235825591602001919060010190610cbf565b5b509050610ce89190610cec565b5090565b5b80821115610d05576000816000905550600101610ced565b5090565b600081359050610d1881612269565b92915050565b60008083601f840112610d3057600080fd5b8235905067ffffffffffffffff811115610d4957600080fd5b602083019150836001820283011115610d6157600080fd5b9250929050565b600060408284031215610d7a57600080fd5b81905092915050565b600081359050610d9281612280565b92915050565b600060208284031215610daa57600080fd5b6000610db884828501610d09565b91505092915050565b60008060208385031215610dd457600080fd5b600083013567ffffffffffffffff811115610dee57600080fd5b610dfa85828601610d1e565b92509250509250929050565b600060208284031215610e1857600080fd5b6000610e2684828501610d83565b91505092915050565b600080600060408486031215610e4457600080fd5b6000610e5286828701610d83565b935050602084013567ffffffffffffffff811115610e6f57600080fd5b610e7b86828701610d1e565b92509250509250925092565b60008060408385031215610e9a57600080fd5b6000610ea885828601610d83565b925050602083013567ffffffffffffffff811115610ec557600080fd5b610ed185828601610d68565b9150509250929050565b6000610ee78383611243565b905092915050565b6000610efb8383611292565b905092915050565b610f0c816118b4565b82525050565b610f1b816118b4565b82525050565b6000610f2d8385611622565b935083602084028501610f3f8461158d565b8060005b87811015610f83578484038952610f5a828461181f565b610f648582610edb565b9450610f6f83611608565b925060208a01995050600181019050610f43565b50829750879450505050509392505050565b6000610fa0826115dc565b610faa8185611622565b935083602082028501610fbc85611597565b8060005b85811015610ff85784840389528151610fd98582610eef565b9450610fe483611615565b925060208a01995050600181019050610fc0565b50829750879550505050505092915050565b611013816119a3565b82525050565b60006110258385611633565b9350611032838584611b60565b61103b83611ed3565b840190509392505050565b60006110528385611644565b935061105f838584611b60565b61106883611ed3565b840190509392505050565b600061107e826115fd565b6110888185611633565b9350611098818560208601611b6f565b6110a181611ed3565b840191505092915050565b60006110b7826115fd565b6110c18185611644565b93506110d1818560208601611b6f565b6110da81611ed3565b840191505092915050565b60006110f2601583611644565b91506110fd82611f5f565b602082019050919050565b6000611115602683611644565b915061112082611f88565b604082019050919050565b6000611138602e83611644565b915061114382611fd7565b604082019050919050565b600061115b602083611644565b915061116682612026565b602082019050919050565b600061117e602b83611644565b91506111898261204f565b604082019050919050565b60006111a1601983611644565b91506111ac8261209e565b602082019050919050565b6000604083016111ca600084018461175a565b6111d76000860182610f03565b506111e56020840184611771565b85830360208701526111f8838284610f21565b925050508091505092915050565b600060408301600083015161121e6000860182610f03565b50602083015184820360208601526112368282610f95565b9150508091505092915050565b60006040830161125660008401846117c8565b8583036000870152611269838284611019565b9250505061127a6020840184611843565b61128760208601826112cf565b508091505092915050565b600060408301600083015184820360008601526112af8282611073565b91505060208301516112c460208601826112cf565b508091505092915050565b6112d8816118e6565b82525050565b6112e7816118e6565b82525050565b60006020820190506113026000830184610f12565b92915050565b600060208201905061131d600083018461100a565b92915050565b6000602082019050818103600083015261133d81846110ac565b905092915050565b6000602082019050818103600083015261135e816110e5565b9050919050565b6000602082019050818103600083015261137e81611108565b9050919050565b6000602082019050818103600083015261139e8161112b565b9050919050565b600060208201905081810360008301526113be8161114e565b9050919050565b600060208201905081810360008301526113de81611171565b9050919050565b600060208201905081810360008301526113fe81611194565b9050919050565b6000602082019050818103600083015261141f8184611206565b905092915050565b600060208201905061143c60008301846112de565b92915050565b600060408201905061145760008301866112de565b818103602083015261146a818486611046565b9050949350505050565b600060408201905061148960008301856112de565b818103602083015261149b81846111b7565b90509392505050565b600080833560016020038436030381126114bd57600080fd5b80840192508235915067ffffffffffffffff8211156114db57600080fd5b6020830192506020820236038313156114f357600080fd5b509250929050565b6000808335600160200384360303811261151457600080fd5b80840192508235915067ffffffffffffffff82111561153257600080fd5b60208301925060018202360383131561154a57600080fd5b509250929050565b60008235600160400383360303811261156a57600080fd5b80830191505092915050565b600081905061158682600261185a565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b60208410600081146116ae57601f84116001811461167e576116778685611c60565b83556116a8565b611687836115bc565b61169c6020601f88010482016001830161190b565b6116a687856120c7565b505b506116f7565b6116b7826115bc565b6020601f8701048101601f871680156116d8576116d78160018403611d9f565b5b6116ea6020601f89010484018361190b565b6001886002021785555050505b5050505050565b6020831060008114611749576020851060008114611727576117208685611c60565b8355611743565b8360ff1916935083611738846115bc565b556001866002020183555b50611753565b6001856002020182555b5050505050565b60006117696020840184610d09565b905092915050565b6000808335600160200384360303811261178a57600080fd5b83810192508235915060208301925067ffffffffffffffff8211156117ae57600080fd5b6020820236038413156117c057600080fd5b509250929050565b600080833560016020038436030381126117e157600080fd5b83810192508235915060208301925067ffffffffffffffff82111561180557600080fd5b60018202360384131561181757600080fd5b509250929050565b60008235600160400383360303811261183757600080fd5b82810191505092915050565b60006118526020840184610d83565b905092915050565b6000611865826118e6565b9150611870836118e6565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156118a9576118a8611d12565b5b828202905092915050565b60006118bf826118c6565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b611908600082611e7e565b50565b5b8181101561192a5761191f600082611f47565b60018101905061190c565b5050565b5b8181101561194d57611942600082611f29565b60028101905061192f565b5050565b8181101561196f57611964600082611f47565b600181019050611951565b5050565b6119806000808301611f0b565b61198e600060018301611f47565b50565b600061199c826119b5565b9050919050565b60006119ae826118f0565b9050919050565b60006119c0826119c7565b9050919050565b60006119d2826118c6565b9050919050565b60006119e4826118e6565b9050919050565b6119f583836115d1565b6119ff8183611e1a565b611a088361158d565b611a11836115a7565b6000805b84811015611a4a57611a278488611552565b611a32818486612226565b60208501945060028401935050600181019050611a15565b5050505050505050565b611a5e83836115f2565b67ffffffffffffffff811115611a7757611a76611d70565b5b611a818254611c2e565b600080601f8411601f84111715611a9e57611a9b856115bc565b90505b601f831115611ad1576020601f85010481016020851015611abd578190505b611acf6020601f86010483018261190b565b505b601f841160018114611afe5760008515611aec578388013590505b611af68682611c60565b875550611b56565b601f1985168260005b82811015611b2c57858a01358255600182019150602086019550602081019050611b07565b87831015611b4957858a0135611b45601f8a1682611cc5565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b83811015611b8d578082015181840152602081019050611b72565b83811115611b9c576000848401525b50505050565b600081016000830180611bb481611dee565b9050611bc081846121b2565b5050506001810160208301611bd581856114a4565b611be08183866121d5565b505050505050565b6000810160008301611bfa81856114fb565b611c058183866121e5565b50505050600181016020830180611c1b81611e04565b9050611c278184612203565b5050505050565b60006002820490506001821680611c4657607f821691505b60208210811415611c5a57611c59611d41565b5b50919050565b6000611c6c8383611cc5565b9150826002028217905092915050565b6000611c87826118e6565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415611cba57611cb9611d12565b5b600182019050919050565b6000611cd660001984600802611efe565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611dcf7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83602003600802611efe565b815481168255505050565b6000819050919050565b6000819050919050565b60008135611dfb81612269565b80915050919050565b60008135611e1181612280565b80915050919050565b68010000000000000000821115611e3457611e33611d70565b5b611e3d816115e7565b82825580831015611e7957611e5181611576565b611e5a84611576565b611e63846115a7565b818101838201611e73818361192e565b50505050505b505050565b68010000000000000000821115611e9857611e97611d70565b5b8054611ea381611c2e565b80841115611eb857611eb7848284866116fe565b5b80841015611ecd57611ecc84828486611655565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b60008214611f1c57611f1b611ce3565b5b611f25816118fd565b5050565b60008214611f3a57611f39611ce3565b5b611f4381611973565b5050565b611f4f612297565b611f5a818484612244565b505050565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b6120d0816115bc565b6120db838254611c60565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff61210884611ee4565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61214a84611ee4565b9350801983169250808416831791505092915050565b6000600883026121907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82611ef1565b61219a8683611ef1565b95508019841693508086168417925050509392505050565b6121bb82611991565b6121ce6121c782611dda565b83546120e8565b8255505050565b6121e08383836119eb565b505050565b6121f0838383611a54565b505050565b6121ff8282611ba2565b5050565b61220c826119d9565b61221f61221882611de4565b835461211e565b8255505050565b811561223557612234611ce3565b5b61223f8382611be8565b505050565b61224d836119d9565b61226161225982611de4565b848454612160565b825550505050565b612272816118b4565b811461227d57600080fd5b50565b612289816118e6565b811461229457600080fd5b50565b60009056fea264697066735822122084f5f1681ed8582b0b01a3c050af63e3bc886fc8eb1d7bfbad5710635ba9f00f64736f6c63430008040033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100cf5760003560e01c8063810a9afa1161008c578063b724de3a11610066578063b724de3a14610212578063cfb452b514610242578063ded8896b14610260578063f2fde38b1461027c576100cf565b8063810a9afa146101a65780638da5cb5b146101d6578063afc26911146101f4576100cf565b80630a874df6146100d4578063144ae85514610104578063362b3e63146101205780635893253c1461013c578063715018a61461016c578063788243d514610176575b600080fd5b6100ee60048036038101906100e99190610e06565b610298565b6040516100fb9190611323565b60405180910390f35b61011e60048036038101906101199190610e87565b61033d565b005b61013a60048036038101906101359190610e06565b6103a5565b005b61015660048036038101906101519190610e06565b6104f2565b6040516101639190611323565b60405180910390f35b610174610592565b005b610190600480360381019061018b9190610e06565b6105a6565b60405161019d91906112ed565b60405180910390f35b6101c060048036038101906101bb9190610e06565b6105e4565b6040516101cd9190611405565b60405180910390f35b6101de610762565b6040516101eb91906112ed565b60405180910390f35b6101fc61078c565b6040516102099190611427565b60405180910390f35b61022c60048036038101906102279190610dc1565b610792565b6040516102399190611427565b60405180910390f35b61024a61081a565b6040516102579190611427565b60405180910390f35b61027a60048036038101906102759190610e2f565b610820565b005b61029660048036038101906102919190610d98565b610989565b005b60606067600083815260200190815260200160002080546102b890611c2e565b80601f01602080910402602001604051908101604052809291908181526020018280546102e490611c2e565b80156103315780601f1061030657610100808354040283529160200191610331565b820191906000526020600020905b81548152906001019060200180831161031457829003601f168201915b50505050509050919050565b610345610a0d565b8060686000848152602001908152602001600020818161036591906121f5565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada8282604051610399929190611474565b60405180910390a15050565b60008060019054906101000a900460ff161590508080156103d65750600160008054906101000a900460ff1660ff16105b8061040357506103e530610a8b565b1580156104025750600160008054906101000a900460ff1660ff16145b5b610442576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161043990611385565b60405180910390fd5b60016000806101000a81548160ff021916908360ff160217905550801561047f576001600060016101000a81548160ff0219169083151502179055505b610487610aae565b816065819055508160668190555080156104ee5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516104e59190611308565b60405180910390a15b5050565b6067602052806000526040600020600091509050805461051190611c2e565b80601f016020809104026020016040519081016040528092919081815260200182805461053d90611c2e565b801561058a5780601f1061055f5761010080835404028352916020019161058a565b820191906000526020600020905b81548152906001019060200180831161056d57829003601f168201915b505050505081565b61059a610a0d565b6105a46000610b07565b565b60686020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b6105ec610c36565b606860008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b8282101561075357838290600052602060002090600202016040518060400160405290816000820180546106b890611c2e565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490611c2e565b80156107315780601f1061070657610100808354040283529160200191610731565b820191906000526020600020905b81548152906001019060200180831161071457829003601f168201915b5050505050815260200160018201548152505081526020019060010190610685565b50505050815250509050919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60665481565b600080606654905083836067600084815260200190815260200160002091906107bc929190610c66565b507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d8185856040516107f093929190611442565b60405180910390a16066600081548092919061080b90611c7c565b91905055508091505092915050565b60655481565b600060676000858152602001908152602001600020805461084090611c2e565b905014610882576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161087990611345565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166068600085815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610926576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091d906113e5565b60405180910390fd5b8181606760008681526020019081526020016000209190610948929190610c66565b507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c83838360405161097c93929190611442565b60405180910390a1505050565b610991610a0d565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610a01576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109f890611365565b60405180910390fd5b610a0a81610b07565b50565b610a15610bcd565b73ffffffffffffffffffffffffffffffffffffffff16610a33610762565b73ffffffffffffffffffffffffffffffffffffffff1614610a89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a80906113a5565b60405180910390fd5b565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610afd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af4906113c5565b60405180910390fd5b610b05610bd5565b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600060019054906101000a900460ff16610c24576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1b906113c5565b60405180910390fd5b610c34610c2f610bcd565b610b07565b565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b828054610c7290611c2e565b90600052602060002090601f016020900481019282610c945760008555610cdb565b82601f10610cad57803560ff1916838001178555610cdb565b82800160010185558215610cdb579182015b82811115610cda578235825591602001919060010190610cbf565b5b509050610ce89190610cec565b5090565b5b80821115610d05576000816000905550600101610ced565b5090565b600081359050610d1881612269565b92915050565b60008083601f840112610d3057600080fd5b8235905067ffffffffffffffff811115610d4957600080fd5b602083019150836001820283011115610d6157600080fd5b9250929050565b600060408284031215610d7a57600080fd5b81905092915050565b600081359050610d9281612280565b92915050565b600060208284031215610daa57600080fd5b6000610db884828501610d09565b91505092915050565b60008060208385031215610dd457600080fd5b600083013567ffffffffffffffff811115610dee57600080fd5b610dfa85828601610d1e565b92509250509250929050565b600060208284031215610e1857600080fd5b6000610e2684828501610d83565b91505092915050565b600080600060408486031215610e4457600080fd5b6000610e5286828701610d83565b935050602084013567ffffffffffffffff811115610e6f57600080fd5b610e7b86828701610d1e565b92509250509250925092565b60008060408385031215610e9a57600080fd5b6000610ea885828601610d83565b925050602083013567ffffffffffffffff811115610ec557600080fd5b610ed185828601610d68565b9150509250929050565b6000610ee78383611243565b905092915050565b6000610efb8383611292565b905092915050565b610f0c816118b4565b82525050565b610f1b816118b4565b82525050565b6000610f2d8385611622565b935083602084028501610f3f8461158d565b8060005b87811015610f83578484038952610f5a828461181f565b610f648582610edb565b9450610f6f83611608565b925060208a01995050600181019050610f43565b50829750879450505050509392505050565b6000610fa0826115dc565b610faa8185611622565b935083602082028501610fbc85611597565b8060005b85811015610ff85784840389528151610fd98582610eef565b9450610fe483611615565b925060208a01995050600181019050610fc0565b50829750879550505050505092915050565b611013816119a3565b82525050565b60006110258385611633565b9350611032838584611b60565b61103b83611ed3565b840190509392505050565b60006110528385611644565b935061105f838584611b60565b61106883611ed3565b840190509392505050565b600061107e826115fd565b6110888185611633565b9350611098818560208601611b6f565b6110a181611ed3565b840191505092915050565b60006110b7826115fd565b6110c18185611644565b93506110d1818560208601611b6f565b6110da81611ed3565b840191505092915050565b60006110f2601583611644565b91506110fd82611f5f565b602082019050919050565b6000611115602683611644565b915061112082611f88565b604082019050919050565b6000611138602e83611644565b915061114382611fd7565b604082019050919050565b600061115b602083611644565b915061116682612026565b602082019050919050565b600061117e602b83611644565b91506111898261204f565b604082019050919050565b60006111a1601983611644565b91506111ac8261209e565b602082019050919050565b6000604083016111ca600084018461175a565b6111d76000860182610f03565b506111e56020840184611771565b85830360208701526111f8838284610f21565b925050508091505092915050565b600060408301600083015161121e6000860182610f03565b50602083015184820360208601526112368282610f95565b9150508091505092915050565b60006040830161125660008401846117c8565b8583036000870152611269838284611019565b9250505061127a6020840184611843565b61128760208601826112cf565b508091505092915050565b600060408301600083015184820360008601526112af8282611073565b91505060208301516112c460208601826112cf565b508091505092915050565b6112d8816118e6565b82525050565b6112e7816118e6565b82525050565b60006020820190506113026000830184610f12565b92915050565b600060208201905061131d600083018461100a565b92915050565b6000602082019050818103600083015261133d81846110ac565b905092915050565b6000602082019050818103600083015261135e816110e5565b9050919050565b6000602082019050818103600083015261137e81611108565b9050919050565b6000602082019050818103600083015261139e8161112b565b9050919050565b600060208201905081810360008301526113be8161114e565b9050919050565b600060208201905081810360008301526113de81611171565b9050919050565b600060208201905081810360008301526113fe81611194565b9050919050565b6000602082019050818103600083015261141f8184611206565b905092915050565b600060208201905061143c60008301846112de565b92915050565b600060408201905061145760008301866112de565b818103602083015261146a818486611046565b9050949350505050565b600060408201905061148960008301856112de565b818103602083015261149b81846111b7565b90509392505050565b600080833560016020038436030381126114bd57600080fd5b80840192508235915067ffffffffffffffff8211156114db57600080fd5b6020830192506020820236038313156114f357600080fd5b509250929050565b6000808335600160200384360303811261151457600080fd5b80840192508235915067ffffffffffffffff82111561153257600080fd5b60208301925060018202360383131561154a57600080fd5b509250929050565b60008235600160400383360303811261156a57600080fd5b80830191505092915050565b600081905061158682600261185a565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b60208410600081146116ae57601f84116001811461167e576116778685611c60565b83556116a8565b611687836115bc565b61169c6020601f88010482016001830161190b565b6116a687856120c7565b505b506116f7565b6116b7826115bc565b6020601f8701048101601f871680156116d8576116d78160018403611d9f565b5b6116ea6020601f89010484018361190b565b6001886002021785555050505b5050505050565b6020831060008114611749576020851060008114611727576117208685611c60565b8355611743565b8360ff1916935083611738846115bc565b556001866002020183555b50611753565b6001856002020182555b5050505050565b60006117696020840184610d09565b905092915050565b6000808335600160200384360303811261178a57600080fd5b83810192508235915060208301925067ffffffffffffffff8211156117ae57600080fd5b6020820236038413156117c057600080fd5b509250929050565b600080833560016020038436030381126117e157600080fd5b83810192508235915060208301925067ffffffffffffffff82111561180557600080fd5b60018202360384131561181757600080fd5b509250929050565b60008235600160400383360303811261183757600080fd5b82810191505092915050565b60006118526020840184610d83565b905092915050565b6000611865826118e6565b9150611870836118e6565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156118a9576118a8611d12565b5b828202905092915050565b60006118bf826118c6565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b611908600082611e7e565b50565b5b8181101561192a5761191f600082611f47565b60018101905061190c565b5050565b5b8181101561194d57611942600082611f29565b60028101905061192f565b5050565b8181101561196f57611964600082611f47565b600181019050611951565b5050565b6119806000808301611f0b565b61198e600060018301611f47565b50565b600061199c826119b5565b9050919050565b60006119ae826118f0565b9050919050565b60006119c0826119c7565b9050919050565b60006119d2826118c6565b9050919050565b60006119e4826118e6565b9050919050565b6119f583836115d1565b6119ff8183611e1a565b611a088361158d565b611a11836115a7565b6000805b84811015611a4a57611a278488611552565b611a32818486612226565b60208501945060028401935050600181019050611a15565b5050505050505050565b611a5e83836115f2565b67ffffffffffffffff811115611a7757611a76611d70565b5b611a818254611c2e565b600080601f8411601f84111715611a9e57611a9b856115bc565b90505b601f831115611ad1576020601f85010481016020851015611abd578190505b611acf6020601f86010483018261190b565b505b601f841160018114611afe5760008515611aec578388013590505b611af68682611c60565b875550611b56565b601f1985168260005b82811015611b2c57858a01358255600182019150602086019550602081019050611b07565b87831015611b4957858a0135611b45601f8a1682611cc5565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b83811015611b8d578082015181840152602081019050611b72565b83811115611b9c576000848401525b50505050565b600081016000830180611bb481611dee565b9050611bc081846121b2565b5050506001810160208301611bd581856114a4565b611be08183866121d5565b505050505050565b6000810160008301611bfa81856114fb565b611c058183866121e5565b50505050600181016020830180611c1b81611e04565b9050611c278184612203565b5050505050565b60006002820490506001821680611c4657607f821691505b60208210811415611c5a57611c59611d41565b5b50919050565b6000611c6c8383611cc5565b9150826002028217905092915050565b6000611c87826118e6565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415611cba57611cb9611d12565b5b600182019050919050565b6000611cd660001984600802611efe565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611dcf7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83602003600802611efe565b815481168255505050565b6000819050919050565b6000819050919050565b60008135611dfb81612269565b80915050919050565b60008135611e1181612280565b80915050919050565b68010000000000000000821115611e3457611e33611d70565b5b611e3d816115e7565b82825580831015611e7957611e5181611576565b611e5a84611576565b611e63846115a7565b818101838201611e73818361192e565b50505050505b505050565b68010000000000000000821115611e9857611e97611d70565b5b8054611ea381611c2e565b80841115611eb857611eb7848284866116fe565b5b80841015611ecd57611ecc84828486611655565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b60008214611f1c57611f1b611ce3565b5b611f25816118fd565b5050565b60008214611f3a57611f39611ce3565b5b611f4381611973565b5050565b611f4f612297565b611f5a818484612244565b505050565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b6120d0816115bc565b6120db838254611c60565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff61210884611ee4565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61214a84611ee4565b9350801983169250808416831791505092915050565b6000600883026121907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82611ef1565b61219a8683611ef1565b95508019841693508086168417925050509392505050565b6121bb82611991565b6121ce6121c782611dda565b83546120e8565b8255505050565b6121e08383836119eb565b505050565b6121f0838383611a54565b505050565b6121ff8282611ba2565b5050565b61220c826119d9565b61221f61221882611de4565b835461211e565b8255505050565b811561223557612234611ce3565b5b61223f8382611be8565b505050565b61224d836119d9565b61226161225982611de4565b848454612160565b825550505050565b612272816118b4565b811461227d57600080fd5b50565b612289816118e6565b811461229457600080fd5b50565b60009056fea264697066735822122084f5f1681ed8582b0b01a3c050af63e3bc886fc8eb1d7bfbad5710635ba9f00f64736f6c63430008040033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/desci-contracts/contracts/DpidAliasRegistry.sol b/desci-contracts/contracts/DpidAliasRegistry.sol index c68f6b50..f7b2010d 100644 --- a/desci-contracts/contracts/DpidAliasRegistry.sol +++ b/desci-contracts/contracts/DpidAliasRegistry.sol @@ -4,7 +4,10 @@ pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; contract DpidAliasRegistry is OwnableUpgradeable { - uint256 public _firstDpid; + // Only written at time of initialization + uint256 public firstDpid; + + // Incremented on each dPID mint uint256 public nextDpid; // dpid => codex streamID @@ -16,10 +19,10 @@ contract DpidAliasRegistry is OwnableUpgradeable { _disableInitializers(); } - function __DpidAliasRegistry_init(uint256 firstDpid) public initializer { + function __DpidAliasRegistry_init(uint256 _firstDpid) public initializer { OwnableUpgradeable.__Ownable_init(); - firstDpid = firstDpid; - nextDpid = firstDpid; + firstDpid = _firstDpid; + nextDpid = _firstDpid; } /** @@ -56,7 +59,7 @@ contract DpidAliasRegistry is OwnableUpgradeable { struct LegacyVersion { string cid; - uint256 timestamp; + uint256 time; } struct LegacyDpidEntry { @@ -104,7 +107,7 @@ contract DpidAliasRegistry is OwnableUpgradeable { // Assert that this dPID has not been set in the main registry require(bytes(registry[dpid]).length == 0, "dpid already upgraded"); // Assert that the tx was made by the owner of the imported entry - require(legacy[dpid].owner == tx.origin, "unauthorized dpid upgrade"); + require(legacy[dpid].owner == msg.sender, "unauthorized dpid upgrade"); // Reclaim old dpid registry[dpid] = streamId; diff --git a/desci-contracts/hardhat.config.ts b/desci-contracts/hardhat.config.ts index 70862b6b..0bbe69f0 100644 --- a/desci-contracts/hardhat.config.ts +++ b/desci-contracts/hardhat.config.ts @@ -35,8 +35,6 @@ module.exports = { coinmarketcap: process.env.COINMARKETCAP_API_KEY, }, networks: { - // NOTE: hardhat node has a bug with websockets: https://github.com/nomiclabs/hardhat/issues/588 - // alternative is to use ganache for more than running contract tests hardhat: { chainId: 1337, accounts: { diff --git a/desci-contracts/index.ts b/desci-contracts/index.ts index 3a0f4b78..7ded7bf6 100644 --- a/desci-contracts/index.ts +++ b/desci-contracts/index.ts @@ -5,6 +5,7 @@ import devRoInfo from "./.openzeppelin/sepoliaDev-research-object.json"; import devDpidInfo from "./.openzeppelin/sepoliaDev-dpid.json"; import prodRoInfo from "./.openzeppelin/sepoliaProd-research-object.json"; import prodDpidInfo from "./.openzeppelin/sepoliaProd-dpid.json"; +import localDpidAliasInfo from "./.openzeppelin/unknown-dpid-alias-registry.json"; export const contracts = { localRoInfo, @@ -13,4 +14,5 @@ export const contracts = { devDpidInfo, prodRoInfo, prodDpidInfo, + localDpidAliasInfo, }; diff --git a/desci-contracts/package.json b/desci-contracts/package.json index ac3089b4..ba1f4829 100644 --- a/desci-contracts/package.json +++ b/desci-contracts/package.json @@ -1,7 +1,7 @@ { "name": "@desci-labs/desci-contracts", "description": "Smart contracts implementing DeSci Nodes on-chain state and logic", - "version": "0.2.4", + "version": "0.2.5-rc2", "license": "MIT", "scripts": { "test": "hardhat clean && hardhat test", diff --git a/desci-contracts/scripts/migrateToAliasRegistry.mjs b/desci-contracts/scripts/migrateToAliasRegistry.mjs new file mode 100644 index 00000000..916ad9f2 --- /dev/null +++ b/desci-contracts/scripts/migrateToAliasRegistry.mjs @@ -0,0 +1,61 @@ +import hardhat from "hardhat"; +const { ethers } = hardhat; +import axios from "axios"; + +const getDpidPage = async (page) => { + const { data } = await axios.get( + `https://dev-beta.dpid.org/api/v1/dpid?size=100&page=${page}` + ); + return data; +}; + +const allDpids = (await Promise.all( + [1,2,3].map(getDpidPage) +)).flat(); + +const toImportEntry = (dpid) => [ + dpid.dpid, + { + owner: dpid.researchObject.owner, + versions: dpid.researchObject.versions.map(v => ({cid: v.cid, time: v.time})) + } +]; + +const importEntries = allDpids.map(toImportEntry); + +const DpidAliasRegistryFactory = await ethers.getContractFactory("DpidAliasRegistry"); + +const registry = await upgrades.deployProxy( + DpidAliasRegistryFactory, + [ + 500 // firstDpid + ], + { + initializer: "__DpidAliasRegistry_init" + } +); + +await registry.deployed(); + +const sliceToImport = importEntries.slice(0,5); +console.log("Importing dPIDs:", sliceToImport.map(s => s[0]).join(", ")) + +const results = []; + +for (const [ dpid, entry ] of importEntries.slice(0, 5)) { + console.log(`✨ Importing dPID ${dpid}...`) + await registry.importLegacyDpid(dpid, entry); + + console.log(`🔎 Resolving dPID ${dpid} from new contract...`) + const fromContract = await registry.legacyLookup(dpid); + + const result = { + dpid, + owner: fromContract[0], + versions: fromContract[1].map(([cid, time]) => ({cid, time: ethers.BigNumber.from(time).toNumber() })) + }; + + console.log(`🎊 Found migrated history of dPID ${dpid} in new contract: \n${JSON.stringify(result, undefined, 2)}`) + console.log("-----------------------------------------------------------------") +}; + diff --git a/desci-contracts/test/DpidAliasRegistry.ts b/desci-contracts/test/DpidAliasRegistry.ts index 006398a6..fb4825a1 100644 --- a/desci-contracts/test/DpidAliasRegistry.ts +++ b/desci-contracts/test/DpidAliasRegistry.ts @@ -136,7 +136,7 @@ describe("dPID", () => { versions: [ { cid: "bafybeihdwdcefgh4dqkjv67uzcmw7ojee6xedzdetojuzjevtenxquvyku", - timestamp: 1716369952, + time: 1716369952, }, ], }; @@ -158,7 +158,7 @@ describe("dPID", () => { expect(legacyEntry.owner).to.equal(migrationEntry.owner); expect(legacyEntry.versions.length).to.equal(1); expect(legacyEntry.versions[0].cid).to.equal("bafybeihdwdcefgh4dqkjv67uzcmw7ojee6xedzdetojuzjevtenxquvyku"); - expect(legacyEntry.versions[0].timestamp).to.equal(1716369952); + expect(legacyEntry.versions[0].time).to.equal(1716369952); }); it("emits an event on success", () => { diff --git a/desci-contracts/typechain-types/DpidAliasRegistry.ts b/desci-contracts/typechain-types/DpidAliasRegistry.ts index 7fe4135e..9e818892 100644 --- a/desci-contracts/typechain-types/DpidAliasRegistry.ts +++ b/desci-contracts/typechain-types/DpidAliasRegistry.ts @@ -18,11 +18,11 @@ import { Listener, Provider } from "@ethersproject/providers"; import { TypedEventFilter, TypedEvent, TypedListener, OnEvent } from "./common"; export declare namespace DpidAliasRegistry { - export type LegacyVersionStruct = { cid: string; timestamp: BigNumberish }; + export type LegacyVersionStruct = { cid: string; time: BigNumberish }; export type LegacyVersionStructOutput = [string, BigNumber] & { cid: string; - timestamp: BigNumber; + time: BigNumber; }; export type LegacyDpidEntryStruct = { @@ -43,7 +43,7 @@ export interface DpidAliasRegistryInterface extends utils.Interface { contractName: "DpidAliasRegistry"; functions: { "__DpidAliasRegistry_init(uint256)": FunctionFragment; - "_firstDpid()": FunctionFragment; + "firstDpid()": FunctionFragment; "importLegacyDpid(uint256,(address,(string,uint256)[]))": FunctionFragment; "legacy(uint256)": FunctionFragment; "legacyLookup(uint256)": FunctionFragment; @@ -61,10 +61,7 @@ export interface DpidAliasRegistryInterface extends utils.Interface { functionFragment: "__DpidAliasRegistry_init", values: [BigNumberish] ): string; - encodeFunctionData( - functionFragment: "_firstDpid", - values?: undefined - ): string; + encodeFunctionData(functionFragment: "firstDpid", values?: undefined): string; encodeFunctionData( functionFragment: "importLegacyDpid", values: [BigNumberish, DpidAliasRegistry.LegacyDpidEntryStruct] @@ -105,7 +102,7 @@ export interface DpidAliasRegistryInterface extends utils.Interface { functionFragment: "__DpidAliasRegistry_init", data: BytesLike ): Result; - decodeFunctionResult(functionFragment: "_firstDpid", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "firstDpid", data: BytesLike): Result; decodeFunctionResult( functionFragment: "importLegacyDpid", data: BytesLike @@ -210,11 +207,11 @@ export interface DpidAliasRegistry extends BaseContract { functions: { __DpidAliasRegistry_init( - firstDpid: BigNumberish, + _firstDpid: BigNumberish, overrides?: Overrides & { from?: string | Promise } ): Promise; - _firstDpid(overrides?: CallOverrides): Promise<[BigNumber]>; + firstDpid(overrides?: CallOverrides): Promise<[BigNumber]>; importLegacyDpid( dpid: BigNumberish, @@ -262,11 +259,11 @@ export interface DpidAliasRegistry extends BaseContract { }; __DpidAliasRegistry_init( - firstDpid: BigNumberish, + _firstDpid: BigNumberish, overrides?: Overrides & { from?: string | Promise } ): Promise; - _firstDpid(overrides?: CallOverrides): Promise; + firstDpid(overrides?: CallOverrides): Promise; importLegacyDpid( dpid: BigNumberish, @@ -311,11 +308,11 @@ export interface DpidAliasRegistry extends BaseContract { callStatic: { __DpidAliasRegistry_init( - firstDpid: BigNumberish, + _firstDpid: BigNumberish, overrides?: CallOverrides ): Promise; - _firstDpid(overrides?: CallOverrides): Promise; + firstDpid(overrides?: CallOverrides): Promise; importLegacyDpid( dpid: BigNumberish, @@ -388,11 +385,11 @@ export interface DpidAliasRegistry extends BaseContract { estimateGas: { __DpidAliasRegistry_init( - firstDpid: BigNumberish, + _firstDpid: BigNumberish, overrides?: Overrides & { from?: string | Promise } ): Promise; - _firstDpid(overrides?: CallOverrides): Promise; + firstDpid(overrides?: CallOverrides): Promise; importLegacyDpid( dpid: BigNumberish, @@ -438,11 +435,11 @@ export interface DpidAliasRegistry extends BaseContract { populateTransaction: { __DpidAliasRegistry_init( - firstDpid: BigNumberish, + _firstDpid: BigNumberish, overrides?: Overrides & { from?: string | Promise } ): Promise; - _firstDpid(overrides?: CallOverrides): Promise; + firstDpid(overrides?: CallOverrides): Promise; importLegacyDpid( dpid: BigNumberish, diff --git a/desci-contracts/typechain-types/factories/DpidAliasRegistry__factory.ts b/desci-contracts/typechain-types/factories/DpidAliasRegistry__factory.ts index 122c5f10..e333bfee 100644 --- a/desci-contracts/typechain-types/factories/DpidAliasRegistry__factory.ts +++ b/desci-contracts/typechain-types/factories/DpidAliasRegistry__factory.ts @@ -58,7 +58,7 @@ const _abi = [ }, { internalType: "uint256", - name: "timestamp", + name: "time", type: "uint256", }, ], @@ -131,7 +131,7 @@ const _abi = [ inputs: [ { internalType: "uint256", - name: "firstDpid", + name: "_firstDpid", type: "uint256", }, ], @@ -142,7 +142,7 @@ const _abi = [ }, { inputs: [], - name: "_firstDpid", + name: "firstDpid", outputs: [ { internalType: "uint256", @@ -176,7 +176,7 @@ const _abi = [ }, { internalType: "uint256", - name: "timestamp", + name: "time", type: "uint256", }, ], @@ -240,7 +240,7 @@ const _abi = [ }, { internalType: "uint256", - name: "timestamp", + name: "time", type: "uint256", }, ], @@ -381,7 +381,7 @@ const _abi = [ ]; const _bytecode = - "0x60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d3565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000127565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff161015620000ed5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e4919062000149565b60405180910390a15b565b6000620000fe60278362000166565b91506200010b8262000184565b604082019050919050565b620001218162000177565b82525050565b600060208201905081810360008301526200014281620000ef565b9050919050565b600060208201905062000160600083018462000116565b92915050565b600082825260208201905092915050565b600060ff82169050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b6122cb80620001e36000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c8063810a9afa1161008c578063b724de3a11610066578063b724de3a14610212578063dc5d7a2e14610242578063ded8896b14610260578063f2fde38b1461027c576100cf565b8063810a9afa146101a65780638da5cb5b146101d6578063afc26911146101f4576100cf565b80630a874df6146100d4578063144ae85514610104578063362b3e63146101205780635893253c1461013c578063715018a61461016c578063788243d514610176575b600080fd5b6100ee60048036038101906100e99190610dff565b610298565b6040516100fb919061131c565b60405180910390f35b61011e60048036038101906101199190610e80565b61033d565b005b61013a60048036038101906101359190610dff565b6103a5565b005b61015660048036038101906101519190610dff565b6104eb565b604051610163919061131c565b60405180910390f35b61017461058b565b005b610190600480360381019061018b9190610dff565b61059f565b60405161019d91906112e6565b60405180910390f35b6101c060048036038101906101bb9190610dff565b6105dd565b6040516101cd91906113fe565b60405180910390f35b6101de61075b565b6040516101eb91906112e6565b60405180910390f35b6101fc610785565b6040516102099190611420565b60405180910390f35b61022c60048036038101906102279190610dba565b61078b565b6040516102399190611420565b60405180910390f35b61024a610813565b6040516102579190611420565b60405180910390f35b61027a60048036038101906102759190610e28565b610819565b005b61029660048036038101906102919190610d91565b610982565b005b60606067600083815260200190815260200160002080546102b890611c27565b80601f01602080910402602001604051908101604052809291908181526020018280546102e490611c27565b80156103315780601f1061030657610100808354040283529160200191610331565b820191906000526020600020905b81548152906001019060200180831161031457829003601f168201915b50505050509050919050565b610345610a06565b8060686000848152602001908152602001600020818161036591906121ee565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada828260405161039992919061146d565b60405180910390a15050565b60008060019054906101000a900460ff161590508080156103d65750600160008054906101000a900460ff1660ff16105b8061040357506103e530610a84565b1580156104025750600160008054906101000a900460ff1660ff16145b5b610442576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104399061137e565b60405180910390fd5b60016000806101000a81548160ff021916908360ff160217905550801561047f576001600060016101000a81548160ff0219169083151502179055505b610487610aa7565b8160668190555080156104e75760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516104de9190611301565b60405180910390a15b5050565b6067602052806000526040600020600091509050805461050a90611c27565b80601f016020809104026020016040519081016040528092919081815260200182805461053690611c27565b80156105835780601f1061055857610100808354040283529160200191610583565b820191906000526020600020905b81548152906001019060200180831161056657829003601f168201915b505050505081565b610593610a06565b61059d6000610b00565b565b60686020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b6105e5610c2f565b606860008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b8282101561074c57838290600052602060002090600202016040518060400160405290816000820180546106b190611c27565b80601f01602080910402602001604051908101604052809291908181526020018280546106dd90611c27565b801561072a5780601f106106ff5761010080835404028352916020019161072a565b820191906000526020600020905b81548152906001019060200180831161070d57829003601f168201915b505050505081526020016001820154815250508152602001906001019061067e565b50505050815250509050919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60665481565b600080606654905083836067600084815260200190815260200160002091906107b5929190610c5f565b507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d8185856040516107e99392919061143b565b60405180910390a16066600081548092919061080490611c75565b91905055508091505092915050565b60655481565b600060676000858152602001908152602001600020805461083990611c27565b90501461087b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108729061133e565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff166068600085815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461091f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610916906113de565b60405180910390fd5b8181606760008681526020019081526020016000209190610941929190610c5f565b507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c8383836040516109759392919061143b565b60405180910390a1505050565b61098a610a06565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156109fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109f19061135e565b60405180910390fd5b610a0381610b00565b50565b610a0e610bc6565b73ffffffffffffffffffffffffffffffffffffffff16610a2c61075b565b73ffffffffffffffffffffffffffffffffffffffff1614610a82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a799061139e565b60405180910390fd5b565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610af6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aed906113be565b60405180910390fd5b610afe610bce565b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600060019054906101000a900460ff16610c1d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c14906113be565b60405180910390fd5b610c2d610c28610bc6565b610b00565b565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b828054610c6b90611c27565b90600052602060002090601f016020900481019282610c8d5760008555610cd4565b82601f10610ca657803560ff1916838001178555610cd4565b82800160010185558215610cd4579182015b82811115610cd3578235825591602001919060010190610cb8565b5b509050610ce19190610ce5565b5090565b5b80821115610cfe576000816000905550600101610ce6565b5090565b600081359050610d1181612262565b92915050565b60008083601f840112610d2957600080fd5b8235905067ffffffffffffffff811115610d4257600080fd5b602083019150836001820283011115610d5a57600080fd5b9250929050565b600060408284031215610d7357600080fd5b81905092915050565b600081359050610d8b81612279565b92915050565b600060208284031215610da357600080fd5b6000610db184828501610d02565b91505092915050565b60008060208385031215610dcd57600080fd5b600083013567ffffffffffffffff811115610de757600080fd5b610df385828601610d17565b92509250509250929050565b600060208284031215610e1157600080fd5b6000610e1f84828501610d7c565b91505092915050565b600080600060408486031215610e3d57600080fd5b6000610e4b86828701610d7c565b935050602084013567ffffffffffffffff811115610e6857600080fd5b610e7486828701610d17565b92509250509250925092565b60008060408385031215610e9357600080fd5b6000610ea185828601610d7c565b925050602083013567ffffffffffffffff811115610ebe57600080fd5b610eca85828601610d61565b9150509250929050565b6000610ee0838361123c565b905092915050565b6000610ef4838361128b565b905092915050565b610f05816118ad565b82525050565b610f14816118ad565b82525050565b6000610f26838561161b565b935083602084028501610f3884611586565b8060005b87811015610f7c578484038952610f538284611818565b610f5d8582610ed4565b9450610f6883611601565b925060208a01995050600181019050610f3c565b50829750879450505050509392505050565b6000610f99826115d5565b610fa3818561161b565b935083602082028501610fb585611590565b8060005b85811015610ff15784840389528151610fd28582610ee8565b9450610fdd8361160e565b925060208a01995050600181019050610fb9565b50829750879550505050505092915050565b61100c8161199c565b82525050565b600061101e838561162c565b935061102b838584611b59565b61103483611ecc565b840190509392505050565b600061104b838561163d565b9350611058838584611b59565b61106183611ecc565b840190509392505050565b6000611077826115f6565b611081818561162c565b9350611091818560208601611b68565b61109a81611ecc565b840191505092915050565b60006110b0826115f6565b6110ba818561163d565b93506110ca818560208601611b68565b6110d381611ecc565b840191505092915050565b60006110eb60158361163d565b91506110f682611f58565b602082019050919050565b600061110e60268361163d565b915061111982611f81565b604082019050919050565b6000611131602e8361163d565b915061113c82611fd0565b604082019050919050565b600061115460208361163d565b915061115f8261201f565b602082019050919050565b6000611177602b8361163d565b915061118282612048565b604082019050919050565b600061119a60198361163d565b91506111a582612097565b602082019050919050565b6000604083016111c36000840184611753565b6111d06000860182610efc565b506111de602084018461176a565b85830360208701526111f1838284610f1a565b925050508091505092915050565b60006040830160008301516112176000860182610efc565b506020830151848203602086015261122f8282610f8e565b9150508091505092915050565b60006040830161124f60008401846117c1565b8583036000870152611262838284611012565b92505050611273602084018461183c565b61128060208601826112c8565b508091505092915050565b600060408301600083015184820360008601526112a8828261106c565b91505060208301516112bd60208601826112c8565b508091505092915050565b6112d1816118df565b82525050565b6112e0816118df565b82525050565b60006020820190506112fb6000830184610f0b565b92915050565b60006020820190506113166000830184611003565b92915050565b6000602082019050818103600083015261133681846110a5565b905092915050565b60006020820190508181036000830152611357816110de565b9050919050565b6000602082019050818103600083015261137781611101565b9050919050565b6000602082019050818103600083015261139781611124565b9050919050565b600060208201905081810360008301526113b781611147565b9050919050565b600060208201905081810360008301526113d78161116a565b9050919050565b600060208201905081810360008301526113f78161118d565b9050919050565b6000602082019050818103600083015261141881846111ff565b905092915050565b600060208201905061143560008301846112d7565b92915050565b600060408201905061145060008301866112d7565b818103602083015261146381848661103f565b9050949350505050565b600060408201905061148260008301856112d7565b818103602083015261149481846111b0565b90509392505050565b600080833560016020038436030381126114b657600080fd5b80840192508235915067ffffffffffffffff8211156114d457600080fd5b6020830192506020820236038313156114ec57600080fd5b509250929050565b6000808335600160200384360303811261150d57600080fd5b80840192508235915067ffffffffffffffff82111561152b57600080fd5b60208301925060018202360383131561154357600080fd5b509250929050565b60008235600160400383360303811261156357600080fd5b80830191505092915050565b600081905061157f826002611853565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b60208410600081146116a757601f841160018114611677576116708685611c59565b83556116a1565b611680836115b5565b6116956020601f880104820160018301611904565b61169f87856120c0565b505b506116f0565b6116b0826115b5565b6020601f8701048101601f871680156116d1576116d08160018403611d98565b5b6116e36020601f890104840183611904565b6001886002021785555050505b5050505050565b6020831060008114611742576020851060008114611720576117198685611c59565b835561173c565b8360ff1916935083611731846115b5565b556001866002020183555b5061174c565b6001856002020182555b5050505050565b60006117626020840184610d02565b905092915050565b6000808335600160200384360303811261178357600080fd5b83810192508235915060208301925067ffffffffffffffff8211156117a757600080fd5b6020820236038413156117b957600080fd5b509250929050565b600080833560016020038436030381126117da57600080fd5b83810192508235915060208301925067ffffffffffffffff8211156117fe57600080fd5b60018202360384131561181057600080fd5b509250929050565b60008235600160400383360303811261183057600080fd5b82810191505092915050565b600061184b6020840184610d7c565b905092915050565b600061185e826118df565b9150611869836118df565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156118a2576118a1611d0b565b5b828202905092915050565b60006118b8826118bf565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b611901600082611e77565b50565b5b8181101561192357611918600082611f40565b600181019050611905565b5050565b5b818110156119465761193b600082611f22565b600281019050611928565b5050565b818110156119685761195d600082611f40565b60018101905061194a565b5050565b6119796000808301611f04565b611987600060018301611f40565b50565b6000611995826119ae565b9050919050565b60006119a7826118e9565b9050919050565b60006119b9826119c0565b9050919050565b60006119cb826118bf565b9050919050565b60006119dd826118df565b9050919050565b6119ee83836115ca565b6119f88183611e13565b611a0183611586565b611a0a836115a0565b6000805b84811015611a4357611a20848861154b565b611a2b81848661221f565b60208501945060028401935050600181019050611a0e565b5050505050505050565b611a5783836115eb565b67ffffffffffffffff811115611a7057611a6f611d69565b5b611a7a8254611c27565b600080601f8411601f84111715611a9757611a94856115b5565b90505b601f831115611aca576020601f85010481016020851015611ab6578190505b611ac86020601f860104830182611904565b505b601f841160018114611af75760008515611ae5578388013590505b611aef8682611c59565b875550611b4f565b601f1985168260005b82811015611b2557858a01358255600182019150602086019550602081019050611b00565b87831015611b4257858a0135611b3e601f8a1682611cbe565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b83811015611b86578082015181840152602081019050611b6b565b83811115611b95576000848401525b50505050565b600081016000830180611bad81611de7565b9050611bb981846121ab565b5050506001810160208301611bce818561149d565b611bd98183866121ce565b505050505050565b6000810160008301611bf381856114f4565b611bfe8183866121de565b50505050600181016020830180611c1481611dfd565b9050611c2081846121fc565b5050505050565b60006002820490506001821680611c3f57607f821691505b60208210811415611c5357611c52611d3a565b5b50919050565b6000611c658383611cbe565b9150826002028217905092915050565b6000611c80826118df565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415611cb357611cb2611d0b565b5b600182019050919050565b6000611ccf60001984600802611ef7565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611dc87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83602003600802611ef7565b815481168255505050565b6000819050919050565b6000819050919050565b60008135611df481612262565b80915050919050565b60008135611e0a81612279565b80915050919050565b68010000000000000000821115611e2d57611e2c611d69565b5b611e36816115e0565b82825580831015611e7257611e4a8161156f565b611e538461156f565b611e5c846115a0565b818101838201611e6c8183611927565b50505050505b505050565b68010000000000000000821115611e9157611e90611d69565b5b8054611e9c81611c27565b80841115611eb157611eb0848284866116f7565b5b80841015611ec657611ec58482848661164e565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b60008214611f1557611f14611cdc565b5b611f1e816118f6565b5050565b60008214611f3357611f32611cdc565b5b611f3c8161196c565b5050565b611f48612290565b611f5381848461223d565b505050565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b6120c9816115b5565b6120d4838254611c59565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff61210184611edd565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61214384611edd565b9350801983169250808416831791505092915050565b6000600883026121897fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82611eea565b6121938683611eea565b95508019841693508086168417925050509392505050565b6121b48261198a565b6121c76121c082611dd3565b83546120e1565b8255505050565b6121d98383836119e4565b505050565b6121e9838383611a4d565b505050565b6121f88282611b9b565b5050565b612205826119d2565b61221861221182611ddd565b8354612117565b8255505050565b811561222e5761222d611cdc565b5b6122388382611be1565b505050565b612246836119d2565b61225a61225282611ddd565b848454612159565b825550505050565b61226b816118ad565b811461227657600080fd5b50565b612282816118df565b811461228d57600080fd5b50565b60009056fea26469706673582212209d15c5501273e10408c38b0c27c1d9008c55404af21e411dc9d13c190f83a2b364736f6c63430008040033"; + "0x60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d3565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000127565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff161015620000ed5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e4919062000149565b60405180910390a15b565b6000620000fe60278362000166565b91506200010b8262000184565b604082019050919050565b620001218162000177565b82525050565b600060208201905081810360008301526200014281620000ef565b9050919050565b600060208201905062000160600083018462000116565b92915050565b600082825260208201905092915050565b600060ff82169050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b6122d280620001e36000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c8063810a9afa1161008c578063b724de3a11610066578063b724de3a14610212578063cfb452b514610242578063ded8896b14610260578063f2fde38b1461027c576100cf565b8063810a9afa146101a65780638da5cb5b146101d6578063afc26911146101f4576100cf565b80630a874df6146100d4578063144ae85514610104578063362b3e63146101205780635893253c1461013c578063715018a61461016c578063788243d514610176575b600080fd5b6100ee60048036038101906100e99190610e06565b610298565b6040516100fb9190611323565b60405180910390f35b61011e60048036038101906101199190610e87565b61033d565b005b61013a60048036038101906101359190610e06565b6103a5565b005b61015660048036038101906101519190610e06565b6104f2565b6040516101639190611323565b60405180910390f35b610174610592565b005b610190600480360381019061018b9190610e06565b6105a6565b60405161019d91906112ed565b60405180910390f35b6101c060048036038101906101bb9190610e06565b6105e4565b6040516101cd9190611405565b60405180910390f35b6101de610762565b6040516101eb91906112ed565b60405180910390f35b6101fc61078c565b6040516102099190611427565b60405180910390f35b61022c60048036038101906102279190610dc1565b610792565b6040516102399190611427565b60405180910390f35b61024a61081a565b6040516102579190611427565b60405180910390f35b61027a60048036038101906102759190610e2f565b610820565b005b61029660048036038101906102919190610d98565b610989565b005b60606067600083815260200190815260200160002080546102b890611c2e565b80601f01602080910402602001604051908101604052809291908181526020018280546102e490611c2e565b80156103315780601f1061030657610100808354040283529160200191610331565b820191906000526020600020905b81548152906001019060200180831161031457829003601f168201915b50505050509050919050565b610345610a0d565b8060686000848152602001908152602001600020818161036591906121f5565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada8282604051610399929190611474565b60405180910390a15050565b60008060019054906101000a900460ff161590508080156103d65750600160008054906101000a900460ff1660ff16105b8061040357506103e530610a8b565b1580156104025750600160008054906101000a900460ff1660ff16145b5b610442576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161043990611385565b60405180910390fd5b60016000806101000a81548160ff021916908360ff160217905550801561047f576001600060016101000a81548160ff0219169083151502179055505b610487610aae565b816065819055508160668190555080156104ee5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516104e59190611308565b60405180910390a15b5050565b6067602052806000526040600020600091509050805461051190611c2e565b80601f016020809104026020016040519081016040528092919081815260200182805461053d90611c2e565b801561058a5780601f1061055f5761010080835404028352916020019161058a565b820191906000526020600020905b81548152906001019060200180831161056d57829003601f168201915b505050505081565b61059a610a0d565b6105a46000610b07565b565b60686020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b6105ec610c36565b606860008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b8282101561075357838290600052602060002090600202016040518060400160405290816000820180546106b890611c2e565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490611c2e565b80156107315780601f1061070657610100808354040283529160200191610731565b820191906000526020600020905b81548152906001019060200180831161071457829003601f168201915b5050505050815260200160018201548152505081526020019060010190610685565b50505050815250509050919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60665481565b600080606654905083836067600084815260200190815260200160002091906107bc929190610c66565b507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d8185856040516107f093929190611442565b60405180910390a16066600081548092919061080b90611c7c565b91905055508091505092915050565b60655481565b600060676000858152602001908152602001600020805461084090611c2e565b905014610882576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161087990611345565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166068600085815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610926576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091d906113e5565b60405180910390fd5b8181606760008681526020019081526020016000209190610948929190610c66565b507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c83838360405161097c93929190611442565b60405180910390a1505050565b610991610a0d565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610a01576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109f890611365565b60405180910390fd5b610a0a81610b07565b50565b610a15610bcd565b73ffffffffffffffffffffffffffffffffffffffff16610a33610762565b73ffffffffffffffffffffffffffffffffffffffff1614610a89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a80906113a5565b60405180910390fd5b565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610afd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af4906113c5565b60405180910390fd5b610b05610bd5565b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600060019054906101000a900460ff16610c24576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1b906113c5565b60405180910390fd5b610c34610c2f610bcd565b610b07565b565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b828054610c7290611c2e565b90600052602060002090601f016020900481019282610c945760008555610cdb565b82601f10610cad57803560ff1916838001178555610cdb565b82800160010185558215610cdb579182015b82811115610cda578235825591602001919060010190610cbf565b5b509050610ce89190610cec565b5090565b5b80821115610d05576000816000905550600101610ced565b5090565b600081359050610d1881612269565b92915050565b60008083601f840112610d3057600080fd5b8235905067ffffffffffffffff811115610d4957600080fd5b602083019150836001820283011115610d6157600080fd5b9250929050565b600060408284031215610d7a57600080fd5b81905092915050565b600081359050610d9281612280565b92915050565b600060208284031215610daa57600080fd5b6000610db884828501610d09565b91505092915050565b60008060208385031215610dd457600080fd5b600083013567ffffffffffffffff811115610dee57600080fd5b610dfa85828601610d1e565b92509250509250929050565b600060208284031215610e1857600080fd5b6000610e2684828501610d83565b91505092915050565b600080600060408486031215610e4457600080fd5b6000610e5286828701610d83565b935050602084013567ffffffffffffffff811115610e6f57600080fd5b610e7b86828701610d1e565b92509250509250925092565b60008060408385031215610e9a57600080fd5b6000610ea885828601610d83565b925050602083013567ffffffffffffffff811115610ec557600080fd5b610ed185828601610d68565b9150509250929050565b6000610ee78383611243565b905092915050565b6000610efb8383611292565b905092915050565b610f0c816118b4565b82525050565b610f1b816118b4565b82525050565b6000610f2d8385611622565b935083602084028501610f3f8461158d565b8060005b87811015610f83578484038952610f5a828461181f565b610f648582610edb565b9450610f6f83611608565b925060208a01995050600181019050610f43565b50829750879450505050509392505050565b6000610fa0826115dc565b610faa8185611622565b935083602082028501610fbc85611597565b8060005b85811015610ff85784840389528151610fd98582610eef565b9450610fe483611615565b925060208a01995050600181019050610fc0565b50829750879550505050505092915050565b611013816119a3565b82525050565b60006110258385611633565b9350611032838584611b60565b61103b83611ed3565b840190509392505050565b60006110528385611644565b935061105f838584611b60565b61106883611ed3565b840190509392505050565b600061107e826115fd565b6110888185611633565b9350611098818560208601611b6f565b6110a181611ed3565b840191505092915050565b60006110b7826115fd565b6110c18185611644565b93506110d1818560208601611b6f565b6110da81611ed3565b840191505092915050565b60006110f2601583611644565b91506110fd82611f5f565b602082019050919050565b6000611115602683611644565b915061112082611f88565b604082019050919050565b6000611138602e83611644565b915061114382611fd7565b604082019050919050565b600061115b602083611644565b915061116682612026565b602082019050919050565b600061117e602b83611644565b91506111898261204f565b604082019050919050565b60006111a1601983611644565b91506111ac8261209e565b602082019050919050565b6000604083016111ca600084018461175a565b6111d76000860182610f03565b506111e56020840184611771565b85830360208701526111f8838284610f21565b925050508091505092915050565b600060408301600083015161121e6000860182610f03565b50602083015184820360208601526112368282610f95565b9150508091505092915050565b60006040830161125660008401846117c8565b8583036000870152611269838284611019565b9250505061127a6020840184611843565b61128760208601826112cf565b508091505092915050565b600060408301600083015184820360008601526112af8282611073565b91505060208301516112c460208601826112cf565b508091505092915050565b6112d8816118e6565b82525050565b6112e7816118e6565b82525050565b60006020820190506113026000830184610f12565b92915050565b600060208201905061131d600083018461100a565b92915050565b6000602082019050818103600083015261133d81846110ac565b905092915050565b6000602082019050818103600083015261135e816110e5565b9050919050565b6000602082019050818103600083015261137e81611108565b9050919050565b6000602082019050818103600083015261139e8161112b565b9050919050565b600060208201905081810360008301526113be8161114e565b9050919050565b600060208201905081810360008301526113de81611171565b9050919050565b600060208201905081810360008301526113fe81611194565b9050919050565b6000602082019050818103600083015261141f8184611206565b905092915050565b600060208201905061143c60008301846112de565b92915050565b600060408201905061145760008301866112de565b818103602083015261146a818486611046565b9050949350505050565b600060408201905061148960008301856112de565b818103602083015261149b81846111b7565b90509392505050565b600080833560016020038436030381126114bd57600080fd5b80840192508235915067ffffffffffffffff8211156114db57600080fd5b6020830192506020820236038313156114f357600080fd5b509250929050565b6000808335600160200384360303811261151457600080fd5b80840192508235915067ffffffffffffffff82111561153257600080fd5b60208301925060018202360383131561154a57600080fd5b509250929050565b60008235600160400383360303811261156a57600080fd5b80830191505092915050565b600081905061158682600261185a565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b60208410600081146116ae57601f84116001811461167e576116778685611c60565b83556116a8565b611687836115bc565b61169c6020601f88010482016001830161190b565b6116a687856120c7565b505b506116f7565b6116b7826115bc565b6020601f8701048101601f871680156116d8576116d78160018403611d9f565b5b6116ea6020601f89010484018361190b565b6001886002021785555050505b5050505050565b6020831060008114611749576020851060008114611727576117208685611c60565b8355611743565b8360ff1916935083611738846115bc565b556001866002020183555b50611753565b6001856002020182555b5050505050565b60006117696020840184610d09565b905092915050565b6000808335600160200384360303811261178a57600080fd5b83810192508235915060208301925067ffffffffffffffff8211156117ae57600080fd5b6020820236038413156117c057600080fd5b509250929050565b600080833560016020038436030381126117e157600080fd5b83810192508235915060208301925067ffffffffffffffff82111561180557600080fd5b60018202360384131561181757600080fd5b509250929050565b60008235600160400383360303811261183757600080fd5b82810191505092915050565b60006118526020840184610d83565b905092915050565b6000611865826118e6565b9150611870836118e6565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156118a9576118a8611d12565b5b828202905092915050565b60006118bf826118c6565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b611908600082611e7e565b50565b5b8181101561192a5761191f600082611f47565b60018101905061190c565b5050565b5b8181101561194d57611942600082611f29565b60028101905061192f565b5050565b8181101561196f57611964600082611f47565b600181019050611951565b5050565b6119806000808301611f0b565b61198e600060018301611f47565b50565b600061199c826119b5565b9050919050565b60006119ae826118f0565b9050919050565b60006119c0826119c7565b9050919050565b60006119d2826118c6565b9050919050565b60006119e4826118e6565b9050919050565b6119f583836115d1565b6119ff8183611e1a565b611a088361158d565b611a11836115a7565b6000805b84811015611a4a57611a278488611552565b611a32818486612226565b60208501945060028401935050600181019050611a15565b5050505050505050565b611a5e83836115f2565b67ffffffffffffffff811115611a7757611a76611d70565b5b611a818254611c2e565b600080601f8411601f84111715611a9e57611a9b856115bc565b90505b601f831115611ad1576020601f85010481016020851015611abd578190505b611acf6020601f86010483018261190b565b505b601f841160018114611afe5760008515611aec578388013590505b611af68682611c60565b875550611b56565b601f1985168260005b82811015611b2c57858a01358255600182019150602086019550602081019050611b07565b87831015611b4957858a0135611b45601f8a1682611cc5565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b83811015611b8d578082015181840152602081019050611b72565b83811115611b9c576000848401525b50505050565b600081016000830180611bb481611dee565b9050611bc081846121b2565b5050506001810160208301611bd581856114a4565b611be08183866121d5565b505050505050565b6000810160008301611bfa81856114fb565b611c058183866121e5565b50505050600181016020830180611c1b81611e04565b9050611c278184612203565b5050505050565b60006002820490506001821680611c4657607f821691505b60208210811415611c5a57611c59611d41565b5b50919050565b6000611c6c8383611cc5565b9150826002028217905092915050565b6000611c87826118e6565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415611cba57611cb9611d12565b5b600182019050919050565b6000611cd660001984600802611efe565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611dcf7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83602003600802611efe565b815481168255505050565b6000819050919050565b6000819050919050565b60008135611dfb81612269565b80915050919050565b60008135611e1181612280565b80915050919050565b68010000000000000000821115611e3457611e33611d70565b5b611e3d816115e7565b82825580831015611e7957611e5181611576565b611e5a84611576565b611e63846115a7565b818101838201611e73818361192e565b50505050505b505050565b68010000000000000000821115611e9857611e97611d70565b5b8054611ea381611c2e565b80841115611eb857611eb7848284866116fe565b5b80841015611ecd57611ecc84828486611655565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b60008214611f1c57611f1b611ce3565b5b611f25816118fd565b5050565b60008214611f3a57611f39611ce3565b5b611f4381611973565b5050565b611f4f612297565b611f5a818484612244565b505050565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b6120d0816115bc565b6120db838254611c60565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff61210884611ee4565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61214a84611ee4565b9350801983169250808416831791505092915050565b6000600883026121907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82611ef1565b61219a8683611ef1565b95508019841693508086168417925050509392505050565b6121bb82611991565b6121ce6121c782611dda565b83546120e8565b8255505050565b6121e08383836119eb565b505050565b6121f0838383611a54565b505050565b6121ff8282611ba2565b5050565b61220c826119d9565b61221f61221882611de4565b835461211e565b8255505050565b811561223557612234611ce3565b5b61223f8382611be8565b505050565b61224d836119d9565b61226161225982611de4565b848454612160565b825550505050565b612272816118b4565b811461227d57600080fd5b50565b612289816118e6565b811461229457600080fd5b50565b60009056fea264697066735822122084f5f1681ed8582b0b01a3c050af63e3bc886fc8eb1d7bfbad5710635ba9f00f64736f6c63430008040033"; type DpidAliasRegistryConstructorParams = | [signer?: Signer] From e4a5f6e885887c843baf3012df0616cfd18b596f Mon Sep 17 00:00:00 2001 From: m0ar Date: Mon, 27 May 2024 12:14:14 +0200 Subject: [PATCH 118/278] proxy: add optimism RPC endpoints --- reverse-proxy/kubernetes/deployment_dev.yaml | 3 ++- reverse-proxy/kubernetes/deployment_prod.yaml | 3 ++- reverse-proxy/kubernetes/deployment_staging.yaml | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/reverse-proxy/kubernetes/deployment_dev.yaml b/reverse-proxy/kubernetes/deployment_dev.yaml index 89099605..d47d069d 100755 --- a/reverse-proxy/kubernetes/deployment_dev.yaml +++ b/reverse-proxy/kubernetes/deployment_dev.yaml @@ -62,7 +62,8 @@ spec: echo "sourcing"; export PROXY_MAPPING_RPC_SEPOLIA={{ .Data.PROXY_MAPPING_RPC_SEPOLIA }} export PROXY_MAPPING_RPC_MAINNET={{ .Data.PROXY_MAPPING_RPC_MAINNET }} - + export PROXY_MAPPING_RPC_OPT_SEPOLIA={{ .Data.PROXY_MAPPING_RPC_OPT_SEPOLIA }} + export PROXY_MAPPING_RPC_OPT_MAINNET={{ .Data.PROXY_MAPPING_RPC_OPT_MAINNET }} {{- end -}} labels: App: ReverseProxyDev diff --git a/reverse-proxy/kubernetes/deployment_prod.yaml b/reverse-proxy/kubernetes/deployment_prod.yaml index 92ae649e..c095aa98 100755 --- a/reverse-proxy/kubernetes/deployment_prod.yaml +++ b/reverse-proxy/kubernetes/deployment_prod.yaml @@ -62,7 +62,8 @@ spec: echo "sourcing"; export PROXY_MAPPING_RPC_SEPOLIA={{ .Data.PROXY_MAPPING_RPC_SEPOLIA }} export PROXY_MAPPING_RPC_MAINNET={{ .Data.PROXY_MAPPING_RPC_MAINNET }} - + export PROXY_MAPPING_RPC_OPT_SEPOLIA={{ .Data.PROXY_MAPPING_RPC_OPT_SEPOLIA }} + export PROXY_MAPPING_RPC_OPT_MAINNET={{ .Data.PROXY_MAPPING_RPC_OPT_MAINNET }} {{- end -}} labels: App: ReverseProxyProd diff --git a/reverse-proxy/kubernetes/deployment_staging.yaml b/reverse-proxy/kubernetes/deployment_staging.yaml index b0f5cc79..df9cb15a 100755 --- a/reverse-proxy/kubernetes/deployment_staging.yaml +++ b/reverse-proxy/kubernetes/deployment_staging.yaml @@ -62,7 +62,8 @@ spec: echo "sourcing"; export PROXY_MAPPING_RPC_SEPOLIA={{ .Data.PROXY_MAPPING_RPC_SEPOLIA }} export PROXY_MAPPING_RPC_MAINNET={{ .Data.PROXY_MAPPING_RPC_MAINNET }} - + export PROXY_MAPPING_RPC_OPT_SEPOLIA={{ .Data.PROXY_MAPPING_RPC_OPT_SEPOLIA }} + export PROXY_MAPPING_RPC_OPT_MAINNET={{ .Data.PROXY_MAPPING_RPC_OPT_MAINNET }} {{- end -}} labels: App: ReverseProxyStaging From 41489c39050d9b38964d7a7f94c77f584ec230ff Mon Sep 17 00:00:00 2001 From: m0ar Date: Wed, 29 May 2024 13:47:23 +0200 Subject: [PATCH 119/278] contracts: add reverseRegistry and single alias limitation to alias registry --- .../DpidAliasRegistry.json | 80 ++++++++++++----- .../contracts/DpidAliasRegistry.sol | 53 +++++++++--- desci-contracts/index.ts | 3 + desci-contracts/package.json | 2 +- desci-contracts/test/DpidAliasRegistry.ts | 22 ++--- .../typechain-types/DpidAliasRegistry.ts | 85 ++++++++++++++----- .../factories/DpidAliasRegistry__factory.ts | 78 ++++++++++++----- 7 files changed, 237 insertions(+), 86 deletions(-) diff --git a/desci-contracts/artifacts/contracts/DpidAliasRegistry.sol/DpidAliasRegistry.json b/desci-contracts/artifacts/contracts/DpidAliasRegistry.sol/DpidAliasRegistry.json index 51effc33..da4e58c7 100644 --- a/desci-contracts/artifacts/contracts/DpidAliasRegistry.sol/DpidAliasRegistry.json +++ b/desci-contracts/artifacts/contracts/DpidAliasRegistry.sol/DpidAliasRegistry.json @@ -134,6 +134,25 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "string", + "name": "streamId", + "type": "string" + } + ], + "name": "find", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "firstDpid", @@ -251,25 +270,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "dpid", - "type": "uint256" - } - ], - "name": "lookup", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -341,6 +341,44 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "dpid", + "type": "uint256" + } + ], + "name": "resolve", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "name": "reverseRegistry", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -373,8 +411,8 @@ "type": "function" } ], - "bytecode": "0x60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d3565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000127565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff161015620000ed5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e4919062000149565b60405180910390a15b565b6000620000fe60278362000166565b91506200010b8262000184565b604082019050919050565b620001218162000177565b82525050565b600060208201905081810360008301526200014281620000ef565b9050919050565b600060208201905062000160600083018462000116565b92915050565b600082825260208201905092915050565b600060ff82169050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b6122d280620001e36000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c8063810a9afa1161008c578063b724de3a11610066578063b724de3a14610212578063cfb452b514610242578063ded8896b14610260578063f2fde38b1461027c576100cf565b8063810a9afa146101a65780638da5cb5b146101d6578063afc26911146101f4576100cf565b80630a874df6146100d4578063144ae85514610104578063362b3e63146101205780635893253c1461013c578063715018a61461016c578063788243d514610176575b600080fd5b6100ee60048036038101906100e99190610e06565b610298565b6040516100fb9190611323565b60405180910390f35b61011e60048036038101906101199190610e87565b61033d565b005b61013a60048036038101906101359190610e06565b6103a5565b005b61015660048036038101906101519190610e06565b6104f2565b6040516101639190611323565b60405180910390f35b610174610592565b005b610190600480360381019061018b9190610e06565b6105a6565b60405161019d91906112ed565b60405180910390f35b6101c060048036038101906101bb9190610e06565b6105e4565b6040516101cd9190611405565b60405180910390f35b6101de610762565b6040516101eb91906112ed565b60405180910390f35b6101fc61078c565b6040516102099190611427565b60405180910390f35b61022c60048036038101906102279190610dc1565b610792565b6040516102399190611427565b60405180910390f35b61024a61081a565b6040516102579190611427565b60405180910390f35b61027a60048036038101906102759190610e2f565b610820565b005b61029660048036038101906102919190610d98565b610989565b005b60606067600083815260200190815260200160002080546102b890611c2e565b80601f01602080910402602001604051908101604052809291908181526020018280546102e490611c2e565b80156103315780601f1061030657610100808354040283529160200191610331565b820191906000526020600020905b81548152906001019060200180831161031457829003601f168201915b50505050509050919050565b610345610a0d565b8060686000848152602001908152602001600020818161036591906121f5565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada8282604051610399929190611474565b60405180910390a15050565b60008060019054906101000a900460ff161590508080156103d65750600160008054906101000a900460ff1660ff16105b8061040357506103e530610a8b565b1580156104025750600160008054906101000a900460ff1660ff16145b5b610442576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161043990611385565b60405180910390fd5b60016000806101000a81548160ff021916908360ff160217905550801561047f576001600060016101000a81548160ff0219169083151502179055505b610487610aae565b816065819055508160668190555080156104ee5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516104e59190611308565b60405180910390a15b5050565b6067602052806000526040600020600091509050805461051190611c2e565b80601f016020809104026020016040519081016040528092919081815260200182805461053d90611c2e565b801561058a5780601f1061055f5761010080835404028352916020019161058a565b820191906000526020600020905b81548152906001019060200180831161056d57829003601f168201915b505050505081565b61059a610a0d565b6105a46000610b07565b565b60686020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b6105ec610c36565b606860008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b8282101561075357838290600052602060002090600202016040518060400160405290816000820180546106b890611c2e565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490611c2e565b80156107315780601f1061070657610100808354040283529160200191610731565b820191906000526020600020905b81548152906001019060200180831161071457829003601f168201915b5050505050815260200160018201548152505081526020019060010190610685565b50505050815250509050919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60665481565b600080606654905083836067600084815260200190815260200160002091906107bc929190610c66565b507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d8185856040516107f093929190611442565b60405180910390a16066600081548092919061080b90611c7c565b91905055508091505092915050565b60655481565b600060676000858152602001908152602001600020805461084090611c2e565b905014610882576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161087990611345565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166068600085815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610926576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091d906113e5565b60405180910390fd5b8181606760008681526020019081526020016000209190610948929190610c66565b507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c83838360405161097c93929190611442565b60405180910390a1505050565b610991610a0d565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610a01576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109f890611365565b60405180910390fd5b610a0a81610b07565b50565b610a15610bcd565b73ffffffffffffffffffffffffffffffffffffffff16610a33610762565b73ffffffffffffffffffffffffffffffffffffffff1614610a89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a80906113a5565b60405180910390fd5b565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610afd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af4906113c5565b60405180910390fd5b610b05610bd5565b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600060019054906101000a900460ff16610c24576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1b906113c5565b60405180910390fd5b610c34610c2f610bcd565b610b07565b565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b828054610c7290611c2e565b90600052602060002090601f016020900481019282610c945760008555610cdb565b82601f10610cad57803560ff1916838001178555610cdb565b82800160010185558215610cdb579182015b82811115610cda578235825591602001919060010190610cbf565b5b509050610ce89190610cec565b5090565b5b80821115610d05576000816000905550600101610ced565b5090565b600081359050610d1881612269565b92915050565b60008083601f840112610d3057600080fd5b8235905067ffffffffffffffff811115610d4957600080fd5b602083019150836001820283011115610d6157600080fd5b9250929050565b600060408284031215610d7a57600080fd5b81905092915050565b600081359050610d9281612280565b92915050565b600060208284031215610daa57600080fd5b6000610db884828501610d09565b91505092915050565b60008060208385031215610dd457600080fd5b600083013567ffffffffffffffff811115610dee57600080fd5b610dfa85828601610d1e565b92509250509250929050565b600060208284031215610e1857600080fd5b6000610e2684828501610d83565b91505092915050565b600080600060408486031215610e4457600080fd5b6000610e5286828701610d83565b935050602084013567ffffffffffffffff811115610e6f57600080fd5b610e7b86828701610d1e565b92509250509250925092565b60008060408385031215610e9a57600080fd5b6000610ea885828601610d83565b925050602083013567ffffffffffffffff811115610ec557600080fd5b610ed185828601610d68565b9150509250929050565b6000610ee78383611243565b905092915050565b6000610efb8383611292565b905092915050565b610f0c816118b4565b82525050565b610f1b816118b4565b82525050565b6000610f2d8385611622565b935083602084028501610f3f8461158d565b8060005b87811015610f83578484038952610f5a828461181f565b610f648582610edb565b9450610f6f83611608565b925060208a01995050600181019050610f43565b50829750879450505050509392505050565b6000610fa0826115dc565b610faa8185611622565b935083602082028501610fbc85611597565b8060005b85811015610ff85784840389528151610fd98582610eef565b9450610fe483611615565b925060208a01995050600181019050610fc0565b50829750879550505050505092915050565b611013816119a3565b82525050565b60006110258385611633565b9350611032838584611b60565b61103b83611ed3565b840190509392505050565b60006110528385611644565b935061105f838584611b60565b61106883611ed3565b840190509392505050565b600061107e826115fd565b6110888185611633565b9350611098818560208601611b6f565b6110a181611ed3565b840191505092915050565b60006110b7826115fd565b6110c18185611644565b93506110d1818560208601611b6f565b6110da81611ed3565b840191505092915050565b60006110f2601583611644565b91506110fd82611f5f565b602082019050919050565b6000611115602683611644565b915061112082611f88565b604082019050919050565b6000611138602e83611644565b915061114382611fd7565b604082019050919050565b600061115b602083611644565b915061116682612026565b602082019050919050565b600061117e602b83611644565b91506111898261204f565b604082019050919050565b60006111a1601983611644565b91506111ac8261209e565b602082019050919050565b6000604083016111ca600084018461175a565b6111d76000860182610f03565b506111e56020840184611771565b85830360208701526111f8838284610f21565b925050508091505092915050565b600060408301600083015161121e6000860182610f03565b50602083015184820360208601526112368282610f95565b9150508091505092915050565b60006040830161125660008401846117c8565b8583036000870152611269838284611019565b9250505061127a6020840184611843565b61128760208601826112cf565b508091505092915050565b600060408301600083015184820360008601526112af8282611073565b91505060208301516112c460208601826112cf565b508091505092915050565b6112d8816118e6565b82525050565b6112e7816118e6565b82525050565b60006020820190506113026000830184610f12565b92915050565b600060208201905061131d600083018461100a565b92915050565b6000602082019050818103600083015261133d81846110ac565b905092915050565b6000602082019050818103600083015261135e816110e5565b9050919050565b6000602082019050818103600083015261137e81611108565b9050919050565b6000602082019050818103600083015261139e8161112b565b9050919050565b600060208201905081810360008301526113be8161114e565b9050919050565b600060208201905081810360008301526113de81611171565b9050919050565b600060208201905081810360008301526113fe81611194565b9050919050565b6000602082019050818103600083015261141f8184611206565b905092915050565b600060208201905061143c60008301846112de565b92915050565b600060408201905061145760008301866112de565b818103602083015261146a818486611046565b9050949350505050565b600060408201905061148960008301856112de565b818103602083015261149b81846111b7565b90509392505050565b600080833560016020038436030381126114bd57600080fd5b80840192508235915067ffffffffffffffff8211156114db57600080fd5b6020830192506020820236038313156114f357600080fd5b509250929050565b6000808335600160200384360303811261151457600080fd5b80840192508235915067ffffffffffffffff82111561153257600080fd5b60208301925060018202360383131561154a57600080fd5b509250929050565b60008235600160400383360303811261156a57600080fd5b80830191505092915050565b600081905061158682600261185a565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b60208410600081146116ae57601f84116001811461167e576116778685611c60565b83556116a8565b611687836115bc565b61169c6020601f88010482016001830161190b565b6116a687856120c7565b505b506116f7565b6116b7826115bc565b6020601f8701048101601f871680156116d8576116d78160018403611d9f565b5b6116ea6020601f89010484018361190b565b6001886002021785555050505b5050505050565b6020831060008114611749576020851060008114611727576117208685611c60565b8355611743565b8360ff1916935083611738846115bc565b556001866002020183555b50611753565b6001856002020182555b5050505050565b60006117696020840184610d09565b905092915050565b6000808335600160200384360303811261178a57600080fd5b83810192508235915060208301925067ffffffffffffffff8211156117ae57600080fd5b6020820236038413156117c057600080fd5b509250929050565b600080833560016020038436030381126117e157600080fd5b83810192508235915060208301925067ffffffffffffffff82111561180557600080fd5b60018202360384131561181757600080fd5b509250929050565b60008235600160400383360303811261183757600080fd5b82810191505092915050565b60006118526020840184610d83565b905092915050565b6000611865826118e6565b9150611870836118e6565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156118a9576118a8611d12565b5b828202905092915050565b60006118bf826118c6565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b611908600082611e7e565b50565b5b8181101561192a5761191f600082611f47565b60018101905061190c565b5050565b5b8181101561194d57611942600082611f29565b60028101905061192f565b5050565b8181101561196f57611964600082611f47565b600181019050611951565b5050565b6119806000808301611f0b565b61198e600060018301611f47565b50565b600061199c826119b5565b9050919050565b60006119ae826118f0565b9050919050565b60006119c0826119c7565b9050919050565b60006119d2826118c6565b9050919050565b60006119e4826118e6565b9050919050565b6119f583836115d1565b6119ff8183611e1a565b611a088361158d565b611a11836115a7565b6000805b84811015611a4a57611a278488611552565b611a32818486612226565b60208501945060028401935050600181019050611a15565b5050505050505050565b611a5e83836115f2565b67ffffffffffffffff811115611a7757611a76611d70565b5b611a818254611c2e565b600080601f8411601f84111715611a9e57611a9b856115bc565b90505b601f831115611ad1576020601f85010481016020851015611abd578190505b611acf6020601f86010483018261190b565b505b601f841160018114611afe5760008515611aec578388013590505b611af68682611c60565b875550611b56565b601f1985168260005b82811015611b2c57858a01358255600182019150602086019550602081019050611b07565b87831015611b4957858a0135611b45601f8a1682611cc5565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b83811015611b8d578082015181840152602081019050611b72565b83811115611b9c576000848401525b50505050565b600081016000830180611bb481611dee565b9050611bc081846121b2565b5050506001810160208301611bd581856114a4565b611be08183866121d5565b505050505050565b6000810160008301611bfa81856114fb565b611c058183866121e5565b50505050600181016020830180611c1b81611e04565b9050611c278184612203565b5050505050565b60006002820490506001821680611c4657607f821691505b60208210811415611c5a57611c59611d41565b5b50919050565b6000611c6c8383611cc5565b9150826002028217905092915050565b6000611c87826118e6565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415611cba57611cb9611d12565b5b600182019050919050565b6000611cd660001984600802611efe565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611dcf7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83602003600802611efe565b815481168255505050565b6000819050919050565b6000819050919050565b60008135611dfb81612269565b80915050919050565b60008135611e1181612280565b80915050919050565b68010000000000000000821115611e3457611e33611d70565b5b611e3d816115e7565b82825580831015611e7957611e5181611576565b611e5a84611576565b611e63846115a7565b818101838201611e73818361192e565b50505050505b505050565b68010000000000000000821115611e9857611e97611d70565b5b8054611ea381611c2e565b80841115611eb857611eb7848284866116fe565b5b80841015611ecd57611ecc84828486611655565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b60008214611f1c57611f1b611ce3565b5b611f25816118fd565b5050565b60008214611f3a57611f39611ce3565b5b611f4381611973565b5050565b611f4f612297565b611f5a818484612244565b505050565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b6120d0816115bc565b6120db838254611c60565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff61210884611ee4565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61214a84611ee4565b9350801983169250808416831791505092915050565b6000600883026121907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82611ef1565b61219a8683611ef1565b95508019841693508086168417925050509392505050565b6121bb82611991565b6121ce6121c782611dda565b83546120e8565b8255505050565b6121e08383836119eb565b505050565b6121f0838383611a54565b505050565b6121ff8282611ba2565b5050565b61220c826119d9565b61221f61221882611de4565b835461211e565b8255505050565b811561223557612234611ce3565b5b61223f8382611be8565b505050565b61224d836119d9565b61226161225982611de4565b848454612160565b825550505050565b612272816118b4565b811461227d57600080fd5b50565b612289816118e6565b811461229457600080fd5b50565b60009056fea264697066735822122084f5f1681ed8582b0b01a3c050af63e3bc886fc8eb1d7bfbad5710635ba9f00f64736f6c63430008040033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100cf5760003560e01c8063810a9afa1161008c578063b724de3a11610066578063b724de3a14610212578063cfb452b514610242578063ded8896b14610260578063f2fde38b1461027c576100cf565b8063810a9afa146101a65780638da5cb5b146101d6578063afc26911146101f4576100cf565b80630a874df6146100d4578063144ae85514610104578063362b3e63146101205780635893253c1461013c578063715018a61461016c578063788243d514610176575b600080fd5b6100ee60048036038101906100e99190610e06565b610298565b6040516100fb9190611323565b60405180910390f35b61011e60048036038101906101199190610e87565b61033d565b005b61013a60048036038101906101359190610e06565b6103a5565b005b61015660048036038101906101519190610e06565b6104f2565b6040516101639190611323565b60405180910390f35b610174610592565b005b610190600480360381019061018b9190610e06565b6105a6565b60405161019d91906112ed565b60405180910390f35b6101c060048036038101906101bb9190610e06565b6105e4565b6040516101cd9190611405565b60405180910390f35b6101de610762565b6040516101eb91906112ed565b60405180910390f35b6101fc61078c565b6040516102099190611427565b60405180910390f35b61022c60048036038101906102279190610dc1565b610792565b6040516102399190611427565b60405180910390f35b61024a61081a565b6040516102579190611427565b60405180910390f35b61027a60048036038101906102759190610e2f565b610820565b005b61029660048036038101906102919190610d98565b610989565b005b60606067600083815260200190815260200160002080546102b890611c2e565b80601f01602080910402602001604051908101604052809291908181526020018280546102e490611c2e565b80156103315780601f1061030657610100808354040283529160200191610331565b820191906000526020600020905b81548152906001019060200180831161031457829003601f168201915b50505050509050919050565b610345610a0d565b8060686000848152602001908152602001600020818161036591906121f5565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada8282604051610399929190611474565b60405180910390a15050565b60008060019054906101000a900460ff161590508080156103d65750600160008054906101000a900460ff1660ff16105b8061040357506103e530610a8b565b1580156104025750600160008054906101000a900460ff1660ff16145b5b610442576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161043990611385565b60405180910390fd5b60016000806101000a81548160ff021916908360ff160217905550801561047f576001600060016101000a81548160ff0219169083151502179055505b610487610aae565b816065819055508160668190555080156104ee5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516104e59190611308565b60405180910390a15b5050565b6067602052806000526040600020600091509050805461051190611c2e565b80601f016020809104026020016040519081016040528092919081815260200182805461053d90611c2e565b801561058a5780601f1061055f5761010080835404028352916020019161058a565b820191906000526020600020905b81548152906001019060200180831161056d57829003601f168201915b505050505081565b61059a610a0d565b6105a46000610b07565b565b60686020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b6105ec610c36565b606860008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b8282101561075357838290600052602060002090600202016040518060400160405290816000820180546106b890611c2e565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490611c2e565b80156107315780601f1061070657610100808354040283529160200191610731565b820191906000526020600020905b81548152906001019060200180831161071457829003601f168201915b5050505050815260200160018201548152505081526020019060010190610685565b50505050815250509050919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60665481565b600080606654905083836067600084815260200190815260200160002091906107bc929190610c66565b507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d8185856040516107f093929190611442565b60405180910390a16066600081548092919061080b90611c7c565b91905055508091505092915050565b60655481565b600060676000858152602001908152602001600020805461084090611c2e565b905014610882576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161087990611345565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166068600085815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610926576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091d906113e5565b60405180910390fd5b8181606760008681526020019081526020016000209190610948929190610c66565b507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c83838360405161097c93929190611442565b60405180910390a1505050565b610991610a0d565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610a01576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109f890611365565b60405180910390fd5b610a0a81610b07565b50565b610a15610bcd565b73ffffffffffffffffffffffffffffffffffffffff16610a33610762565b73ffffffffffffffffffffffffffffffffffffffff1614610a89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a80906113a5565b60405180910390fd5b565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610afd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af4906113c5565b60405180910390fd5b610b05610bd5565b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600060019054906101000a900460ff16610c24576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1b906113c5565b60405180910390fd5b610c34610c2f610bcd565b610b07565b565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b828054610c7290611c2e565b90600052602060002090601f016020900481019282610c945760008555610cdb565b82601f10610cad57803560ff1916838001178555610cdb565b82800160010185558215610cdb579182015b82811115610cda578235825591602001919060010190610cbf565b5b509050610ce89190610cec565b5090565b5b80821115610d05576000816000905550600101610ced565b5090565b600081359050610d1881612269565b92915050565b60008083601f840112610d3057600080fd5b8235905067ffffffffffffffff811115610d4957600080fd5b602083019150836001820283011115610d6157600080fd5b9250929050565b600060408284031215610d7a57600080fd5b81905092915050565b600081359050610d9281612280565b92915050565b600060208284031215610daa57600080fd5b6000610db884828501610d09565b91505092915050565b60008060208385031215610dd457600080fd5b600083013567ffffffffffffffff811115610dee57600080fd5b610dfa85828601610d1e565b92509250509250929050565b600060208284031215610e1857600080fd5b6000610e2684828501610d83565b91505092915050565b600080600060408486031215610e4457600080fd5b6000610e5286828701610d83565b935050602084013567ffffffffffffffff811115610e6f57600080fd5b610e7b86828701610d1e565b92509250509250925092565b60008060408385031215610e9a57600080fd5b6000610ea885828601610d83565b925050602083013567ffffffffffffffff811115610ec557600080fd5b610ed185828601610d68565b9150509250929050565b6000610ee78383611243565b905092915050565b6000610efb8383611292565b905092915050565b610f0c816118b4565b82525050565b610f1b816118b4565b82525050565b6000610f2d8385611622565b935083602084028501610f3f8461158d565b8060005b87811015610f83578484038952610f5a828461181f565b610f648582610edb565b9450610f6f83611608565b925060208a01995050600181019050610f43565b50829750879450505050509392505050565b6000610fa0826115dc565b610faa8185611622565b935083602082028501610fbc85611597565b8060005b85811015610ff85784840389528151610fd98582610eef565b9450610fe483611615565b925060208a01995050600181019050610fc0565b50829750879550505050505092915050565b611013816119a3565b82525050565b60006110258385611633565b9350611032838584611b60565b61103b83611ed3565b840190509392505050565b60006110528385611644565b935061105f838584611b60565b61106883611ed3565b840190509392505050565b600061107e826115fd565b6110888185611633565b9350611098818560208601611b6f565b6110a181611ed3565b840191505092915050565b60006110b7826115fd565b6110c18185611644565b93506110d1818560208601611b6f565b6110da81611ed3565b840191505092915050565b60006110f2601583611644565b91506110fd82611f5f565b602082019050919050565b6000611115602683611644565b915061112082611f88565b604082019050919050565b6000611138602e83611644565b915061114382611fd7565b604082019050919050565b600061115b602083611644565b915061116682612026565b602082019050919050565b600061117e602b83611644565b91506111898261204f565b604082019050919050565b60006111a1601983611644565b91506111ac8261209e565b602082019050919050565b6000604083016111ca600084018461175a565b6111d76000860182610f03565b506111e56020840184611771565b85830360208701526111f8838284610f21565b925050508091505092915050565b600060408301600083015161121e6000860182610f03565b50602083015184820360208601526112368282610f95565b9150508091505092915050565b60006040830161125660008401846117c8565b8583036000870152611269838284611019565b9250505061127a6020840184611843565b61128760208601826112cf565b508091505092915050565b600060408301600083015184820360008601526112af8282611073565b91505060208301516112c460208601826112cf565b508091505092915050565b6112d8816118e6565b82525050565b6112e7816118e6565b82525050565b60006020820190506113026000830184610f12565b92915050565b600060208201905061131d600083018461100a565b92915050565b6000602082019050818103600083015261133d81846110ac565b905092915050565b6000602082019050818103600083015261135e816110e5565b9050919050565b6000602082019050818103600083015261137e81611108565b9050919050565b6000602082019050818103600083015261139e8161112b565b9050919050565b600060208201905081810360008301526113be8161114e565b9050919050565b600060208201905081810360008301526113de81611171565b9050919050565b600060208201905081810360008301526113fe81611194565b9050919050565b6000602082019050818103600083015261141f8184611206565b905092915050565b600060208201905061143c60008301846112de565b92915050565b600060408201905061145760008301866112de565b818103602083015261146a818486611046565b9050949350505050565b600060408201905061148960008301856112de565b818103602083015261149b81846111b7565b90509392505050565b600080833560016020038436030381126114bd57600080fd5b80840192508235915067ffffffffffffffff8211156114db57600080fd5b6020830192506020820236038313156114f357600080fd5b509250929050565b6000808335600160200384360303811261151457600080fd5b80840192508235915067ffffffffffffffff82111561153257600080fd5b60208301925060018202360383131561154a57600080fd5b509250929050565b60008235600160400383360303811261156a57600080fd5b80830191505092915050565b600081905061158682600261185a565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b60208410600081146116ae57601f84116001811461167e576116778685611c60565b83556116a8565b611687836115bc565b61169c6020601f88010482016001830161190b565b6116a687856120c7565b505b506116f7565b6116b7826115bc565b6020601f8701048101601f871680156116d8576116d78160018403611d9f565b5b6116ea6020601f89010484018361190b565b6001886002021785555050505b5050505050565b6020831060008114611749576020851060008114611727576117208685611c60565b8355611743565b8360ff1916935083611738846115bc565b556001866002020183555b50611753565b6001856002020182555b5050505050565b60006117696020840184610d09565b905092915050565b6000808335600160200384360303811261178a57600080fd5b83810192508235915060208301925067ffffffffffffffff8211156117ae57600080fd5b6020820236038413156117c057600080fd5b509250929050565b600080833560016020038436030381126117e157600080fd5b83810192508235915060208301925067ffffffffffffffff82111561180557600080fd5b60018202360384131561181757600080fd5b509250929050565b60008235600160400383360303811261183757600080fd5b82810191505092915050565b60006118526020840184610d83565b905092915050565b6000611865826118e6565b9150611870836118e6565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156118a9576118a8611d12565b5b828202905092915050565b60006118bf826118c6565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b611908600082611e7e565b50565b5b8181101561192a5761191f600082611f47565b60018101905061190c565b5050565b5b8181101561194d57611942600082611f29565b60028101905061192f565b5050565b8181101561196f57611964600082611f47565b600181019050611951565b5050565b6119806000808301611f0b565b61198e600060018301611f47565b50565b600061199c826119b5565b9050919050565b60006119ae826118f0565b9050919050565b60006119c0826119c7565b9050919050565b60006119d2826118c6565b9050919050565b60006119e4826118e6565b9050919050565b6119f583836115d1565b6119ff8183611e1a565b611a088361158d565b611a11836115a7565b6000805b84811015611a4a57611a278488611552565b611a32818486612226565b60208501945060028401935050600181019050611a15565b5050505050505050565b611a5e83836115f2565b67ffffffffffffffff811115611a7757611a76611d70565b5b611a818254611c2e565b600080601f8411601f84111715611a9e57611a9b856115bc565b90505b601f831115611ad1576020601f85010481016020851015611abd578190505b611acf6020601f86010483018261190b565b505b601f841160018114611afe5760008515611aec578388013590505b611af68682611c60565b875550611b56565b601f1985168260005b82811015611b2c57858a01358255600182019150602086019550602081019050611b07565b87831015611b4957858a0135611b45601f8a1682611cc5565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b83811015611b8d578082015181840152602081019050611b72565b83811115611b9c576000848401525b50505050565b600081016000830180611bb481611dee565b9050611bc081846121b2565b5050506001810160208301611bd581856114a4565b611be08183866121d5565b505050505050565b6000810160008301611bfa81856114fb565b611c058183866121e5565b50505050600181016020830180611c1b81611e04565b9050611c278184612203565b5050505050565b60006002820490506001821680611c4657607f821691505b60208210811415611c5a57611c59611d41565b5b50919050565b6000611c6c8383611cc5565b9150826002028217905092915050565b6000611c87826118e6565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415611cba57611cb9611d12565b5b600182019050919050565b6000611cd660001984600802611efe565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611dcf7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83602003600802611efe565b815481168255505050565b6000819050919050565b6000819050919050565b60008135611dfb81612269565b80915050919050565b60008135611e1181612280565b80915050919050565b68010000000000000000821115611e3457611e33611d70565b5b611e3d816115e7565b82825580831015611e7957611e5181611576565b611e5a84611576565b611e63846115a7565b818101838201611e73818361192e565b50505050505b505050565b68010000000000000000821115611e9857611e97611d70565b5b8054611ea381611c2e565b80841115611eb857611eb7848284866116fe565b5b80841015611ecd57611ecc84828486611655565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b60008214611f1c57611f1b611ce3565b5b611f25816118fd565b5050565b60008214611f3a57611f39611ce3565b5b611f4381611973565b5050565b611f4f612297565b611f5a818484612244565b505050565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b6120d0816115bc565b6120db838254611c60565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff61210884611ee4565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61214a84611ee4565b9350801983169250808416831791505092915050565b6000600883026121907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82611ef1565b61219a8683611ef1565b95508019841693508086168417925050509392505050565b6121bb82611991565b6121ce6121c782611dda565b83546120e8565b8255505050565b6121e08383836119eb565b505050565b6121f0838383611a54565b505050565b6121ff8282611ba2565b5050565b61220c826119d9565b61221f61221882611de4565b835461211e565b8255505050565b811561223557612234611ce3565b5b61223f8382611be8565b505050565b61224d836119d9565b61226161225982611de4565b848454612160565b825550505050565b612272816118b4565b811461227d57600080fd5b50565b612289816118e6565b811461229457600080fd5b50565b60009056fea264697066735822122084f5f1681ed8582b0b01a3c050af63e3bc886fc8eb1d7bfbad5710635ba9f00f64736f6c63430008040033", + "bytecode": "0x60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d3565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000127565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff161015620000ed5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e4919062000149565b60405180910390a15b565b6000620000fe60278362000166565b91506200010b8262000184565b604082019050919050565b620001218162000177565b82525050565b600060208201905081810360008301526200014281620000ef565b9050919050565b600060208201905062000160600083018462000116565b92915050565b600082825260208201905092915050565b600060ff82169050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b6126a680620001e36000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c8063810a9afa11610097578063b724de3a11610066578063b724de3a14610298578063cfb452b5146102c8578063ded8896b146102e6578063f2fde38b14610302576100f5565b8063810a9afa146101fc57806382b7b5001461022c5780638da5cb5b1461025c578063afc269111461027a576100f5565b8063587a8cbf116100d3578063587a8cbf146101625780635893253c14610192578063715018a6146101c2578063788243d5146101cc576100f5565b8063144ae855146100fa578063362b3e63146101165780634f896d4f14610132575b600080fd5b610114600480360381019061010f919061111f565b61031e565b005b610130600480360381019061012b919061109e565b610386565b005b61014c6004803603810190610147919061109e565b6104d3565b604051610159919061161c565b60405180910390f35b61017c6004803603810190610177919061105d565b610578565b6040516101899190611740565b60405180910390f35b6101ac60048036038101906101a7919061109e565b6105a6565b6040516101b9919061161c565b60405180910390f35b6101ca610646565b005b6101e660048036038101906101e1919061109e565b61065a565b6040516101f391906115e6565b60405180910390f35b6102166004803603810190610211919061109e565b610698565b604051610223919061171e565b60405180910390f35b61024660048036038101906102419190611018565b610816565b6040516102539190611740565b60405180910390f35b610264610841565b60405161027191906115e6565b60405180910390f35b61028261086b565b60405161028f9190611740565b60405180910390f35b6102b260048036038101906102ad9190611018565b610871565b6040516102bf9190611740565b60405180910390f35b6102d0610981565b6040516102dd9190611740565b60405180910390f35b61030060048036038101906102fb91906110c7565b610987565b005b61031c60048036038101906103179190610fef565b610b78565b005b610326610bfc565b8060696000848152602001908152602001600020818161034691906125c9565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada828260405161037a92919061178d565b60405180910390a15050565b60008060019054906101000a900460ff161590508080156103b75750600160008054906101000a900460ff1660ff16105b806103e457506103c630610c7a565b1580156103e35750600160008054906101000a900460ff1660ff16145b5b610423576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041a9061169e565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015610460576001600060016101000a81548160ff0219169083151502179055505b610468610c9d565b816065819055508160668190555080156104cf5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516104c69190611601565b60405180910390a15b5050565b60606067600083815260200190815260200160002080546104f390611fa8565b80601f016020809104026020016040519081016040528092919081815260200182805461051f90611fa8565b801561056c5780601f106105415761010080835404028352916020019161056c565b820191906000526020600020905b81548152906001019060200180831161054f57829003601f168201915b50505050509050919050565b6068818051602081018201805184825260208301602085012081835280955050505050506000915090505481565b606760205280600052604060002060009150905080546105c590611fa8565b80601f01602080910402602001604051908101604052809291908181526020018280546105f190611fa8565b801561063e5780601f106106135761010080835404028352916020019161063e565b820191906000526020600020905b81548152906001019060200180831161062157829003601f168201915b505050505081565b61064e610bfc565b6106586000610cf6565b565b60696020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b6106a0610e25565b606960008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b82821015610807578382906000526020600020906002020160405180604001604052908160008201805461076c90611fa8565b80601f016020809104026020016040519081016040528092919081815260200182805461079890611fa8565b80156107e55780601f106107ba576101008083540402835291602001916107e5565b820191906000526020600020905b8154815290600101906020018083116107c857829003601f168201915b5050505050815260200160018201548152505081526020019060010190610739565b50505050815250509050919050565b60006068838360405161082a9291906115cd565b908152602001604051809103902054905092915050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60665481565b600080606884846040516108869291906115cd565b908152602001604051809103902054146108d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108cc9061167e565b60405180910390fd5b6000606654905083836067600084815260200190815260200160002091906108fe929190610e55565b5080606885856040516109129291906115cd565b9081526020016040518091039020819055507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d8185856040516109579392919061175b565b60405180910390a16066600081548092919061097290612027565b91905055508091505092915050565b60655481565b60006067600085815260200190815260200160002080546109a790611fa8565b9050146109e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e09061163e565b60405180910390fd5b6000606883836040516109fd9291906115cd565b90815260200160405180910390205414610a4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a439061167e565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166069600085815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610af0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae7906116fe565b60405180910390fd5b8181606760008681526020019081526020016000209190610b12929190610e55565b508260688383604051610b269291906115cd565b9081526020016040518091039020819055507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c838383604051610b6b9392919061175b565b60405180910390a1505050565b610b80610bfc565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610bf0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610be79061165e565b60405180910390fd5b610bf981610cf6565b50565b610c04610dbc565b73ffffffffffffffffffffffffffffffffffffffff16610c22610841565b73ffffffffffffffffffffffffffffffffffffffff1614610c78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6f906116be565b60405180910390fd5b565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610cec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce3906116de565b60405180910390fd5b610cf4610dc4565b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600060019054906101000a900460ff16610e13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0a906116de565b60405180910390fd5b610e23610e1e610dbc565b610cf6565b565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b828054610e6190611fa8565b90600052602060002090601f016020900481019282610e835760008555610eca565b82601f10610e9c57803560ff1916838001178555610eca565b82800160010185558215610eca579182015b82811115610ec9578235825591602001919060010190610eae565b5b509050610ed79190610edb565b5090565b5b80821115610ef4576000816000905550600101610edc565b5090565b6000610f0b610f06846118b4565b61188f565b905082815260208101848484011115610f2357600080fd5b610f2e848285611eda565b509392505050565b600081359050610f458161263d565b92915050565b60008083601f840112610f5d57600080fd5b8235905067ffffffffffffffff811115610f7657600080fd5b602083019150836001820283011115610f8e57600080fd5b9250929050565b600082601f830112610fa657600080fd5b8135610fb6848260208601610ef8565b91505092915050565b600060408284031215610fd157600080fd5b81905092915050565b600081359050610fe981612654565b92915050565b60006020828403121561100157600080fd5b600061100f84828501610f36565b91505092915050565b6000806020838503121561102b57600080fd5b600083013567ffffffffffffffff81111561104557600080fd5b61105185828601610f4b565b92509250509250929050565b60006020828403121561106f57600080fd5b600082013567ffffffffffffffff81111561108957600080fd5b61109584828501610f95565b91505092915050565b6000602082840312156110b057600080fd5b60006110be84828501610fda565b91505092915050565b6000806000604084860312156110dc57600080fd5b60006110ea86828701610fda565b935050602084013567ffffffffffffffff81111561110757600080fd5b61111386828701610f4b565b92509250509250925092565b6000806040838503121561113257600080fd5b600061114085828601610fda565b925050602083013567ffffffffffffffff81111561115d57600080fd5b61116985828601610fbf565b9150509250929050565b600061117f8383611523565b905092915050565b60006111938383611572565b905092915050565b6111a481611c2e565b82525050565b6111b381611c2e565b82525050565b60006111c58385611991565b9350836020840285016111d7846118fc565b8060005b8781101561121b5784840389526111f28284611b99565b6111fc8582611173565b945061120783611977565b925060208a019950506001810190506111db565b50829750879450505050509392505050565b60006112388261194b565b6112428185611991565b93508360208202850161125485611906565b8060005b8581101561129057848403895281516112718582611187565b945061127c83611984565b925060208a01995050600181019050611258565b50829750879550505050505092915050565b6112ab81611d1d565b82525050565b60006112bd83856119a2565b93506112ca838584611eda565b6112d38361227e565b840190509392505050565b60006112ea83856119b3565b93506112f7838584611eda565b6113008361227e565b840190509392505050565b600061131783856119c4565b9350611324838584611eda565b82840190509392505050565b600061133b8261196c565b61134581856119a2565b9350611355818560208601611ee9565b61135e8161227e565b840191505092915050565b60006113748261196c565b61137e81856119b3565b935061138e818560208601611ee9565b6113978161227e565b840191505092915050565b60006113af6015836119b3565b91506113ba8261230a565b602082019050919050565b60006113d26026836119b3565b91506113dd82612333565b604082019050919050565b60006113f56019836119b3565b915061140082612382565b602082019050919050565b6000611418602e836119b3565b9150611423826123ab565b604082019050919050565b600061143b6020836119b3565b9150611446826123fa565b602082019050919050565b600061145e602b836119b3565b915061146982612423565b604082019050919050565b60006114816019836119b3565b915061148c82612472565b602082019050919050565b6000604083016114aa6000840184611ad4565b6114b7600086018261119b565b506114c56020840184611aeb565b85830360208701526114d88382846111b9565b925050508091505092915050565b60006040830160008301516114fe600086018261119b565b5060208301518482036020860152611516828261122d565b9150508091505092915050565b6000604083016115366000840184611b42565b85830360008701526115498382846112b1565b9250505061155a6020840184611bbd565b61156760208601826115af565b508091505092915050565b6000604083016000830151848203600086015261158f8282611330565b91505060208301516115a460208601826115af565b508091505092915050565b6115b881611c60565b82525050565b6115c781611c60565b82525050565b60006115da82848661130b565b91508190509392505050565b60006020820190506115fb60008301846111aa565b92915050565b600060208201905061161660008301846112a2565b92915050565b600060208201905081810360008301526116368184611369565b905092915050565b60006020820190508181036000830152611657816113a2565b9050919050565b60006020820190508181036000830152611677816113c5565b9050919050565b60006020820190508181036000830152611697816113e8565b9050919050565b600060208201905081810360008301526116b78161140b565b9050919050565b600060208201905081810360008301526116d78161142e565b9050919050565b600060208201905081810360008301526116f781611451565b9050919050565b6000602082019050818103600083015261171781611474565b9050919050565b6000602082019050818103600083015261173881846114e6565b905092915050565b600060208201905061175560008301846115be565b92915050565b600060408201905061177060008301866115be565b81810360208301526117838184866112de565b9050949350505050565b60006040820190506117a260008301856115be565b81810360208301526117b48184611497565b90509392505050565b600080833560016020038436030381126117d657600080fd5b80840192508235915067ffffffffffffffff8211156117f457600080fd5b60208301925060208202360383131561180c57600080fd5b509250929050565b6000808335600160200384360303811261182d57600080fd5b80840192508235915067ffffffffffffffff82111561184b57600080fd5b60208301925060018202360383131561186357600080fd5b509250929050565b60008235600160400383360303811261188357600080fd5b80830191505092915050565b60006118996118aa565b90506118a58282611ff6565b919050565b6000604051905090565b600067ffffffffffffffff8211156118cf576118ce61211b565b5b6118d88261227e565b9050602081019050919050565b60008190506118f5826002611bd4565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6020841060008114611a2857601f8411600181146119f8576119f18685611fda565b8355611a22565b611a018361192b565b611a166020601f880104820160018301611c85565b611a20878561249b565b505b50611a71565b611a318261192b565b6020601f8701048101601f87168015611a5257611a51816001840361214a565b5b611a646020601f890104840183611c85565b6001886002021785555050505b5050505050565b6020831060008114611ac3576020851060008114611aa157611a9a8685611fda565b8355611abd565b8360ff1916935083611ab28461192b565b556001866002020183555b50611acd565b6001856002020182555b5050505050565b6000611ae36020840184610f36565b905092915050565b60008083356001602003843603038112611b0457600080fd5b83810192508235915060208301925067ffffffffffffffff821115611b2857600080fd5b602082023603841315611b3a57600080fd5b509250929050565b60008083356001602003843603038112611b5b57600080fd5b83810192508235915060208301925067ffffffffffffffff821115611b7f57600080fd5b600182023603841315611b9157600080fd5b509250929050565b600082356001604003833603038112611bb157600080fd5b82810191505092915050565b6000611bcc6020840184610fda565b905092915050565b6000611bdf82611c60565b9150611bea83611c60565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611c2357611c226120bd565b5b828202905092915050565b6000611c3982611c40565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b611c82600082612229565b50565b5b81811015611ca457611c996000826122f2565b600181019050611c86565b5050565b5b81811015611cc757611cbc6000826122d4565b600281019050611ca9565b5050565b81811015611ce957611cde6000826122f2565b600181019050611ccb565b5050565b611cfa60008083016122b6565b611d086000600183016122f2565b50565b6000611d1682611d2f565b9050919050565b6000611d2882611c6a565b9050919050565b6000611d3a82611d41565b9050919050565b6000611d4c82611c40565b9050919050565b6000611d5e82611c60565b9050919050565b611d6f8383611940565b611d7981836121c5565b611d82836118fc565b611d8b83611916565b6000805b84811015611dc457611da1848861186b565b611dac8184866125fa565b60208501945060028401935050600181019050611d8f565b5050505050505050565b611dd88383611961565b67ffffffffffffffff811115611df157611df061211b565b5b611dfb8254611fa8565b600080601f8411601f84111715611e1857611e158561192b565b90505b601f831115611e4b576020601f85010481016020851015611e37578190505b611e496020601f860104830182611c85565b505b601f841160018114611e785760008515611e66578388013590505b611e708682611fda565b875550611ed0565b601f1985168260005b82811015611ea657858a01358255600182019150602086019550602081019050611e81565b87831015611ec357858a0135611ebf601f8a1682612070565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b83811015611f07578082015181840152602081019050611eec565b83811115611f16576000848401525b50505050565b600081016000830180611f2e81612199565b9050611f3a8184612586565b5050506001810160208301611f4f81856117bd565b611f5a8183866125a9565b505050505050565b6000810160008301611f748185611814565b611f7f8183866125b9565b50505050600181016020830180611f95816121af565b9050611fa181846125d7565b5050505050565b60006002820490506001821680611fc057607f821691505b60208210811415611fd457611fd36120ec565b5b50919050565b6000611fe68383612070565b9150826002028217905092915050565b611fff8261227e565b810181811067ffffffffffffffff8211171561201e5761201d61211b565b5b80604052505050565b600061203282611c60565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612065576120646120bd565b5b600182019050919050565b6000612081600019846008026122a9565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61217a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff836020036008026122a9565b815481168255505050565b6000819050919050565b6000819050919050565b600081356121a68161263d565b80915050919050565b600081356121bc81612654565b80915050919050565b680100000000000000008211156121df576121de61211b565b5b6121e881611956565b82825580831015612224576121fc816118e5565b612205846118e5565b61220e84611916565b81810183820161221e8183611ca8565b50505050505b505050565b680100000000000000008211156122435761224261211b565b5b805461224e81611fa8565b808411156122635761226284828486611a78565b5b8084101561227857612277848284866119cf565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b600082146122c7576122c661208e565b5b6122d081611c77565b5050565b600082146122e5576122e461208e565b5b6122ee81611ced565b5050565b6122fa61266b565b612305818484612618565b505050565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f73747265616d20616c7265616479206861732061206450494400000000000000600082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b6124a48161192b565b6124af838254611fda565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff6124dc8461228f565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61251e8461228f565b9350801983169250808416831791505092915050565b6000600883026125647fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261229c565b61256e868361229c565b95508019841693508086168417925050509392505050565b61258f82611d0b565b6125a261259b82612185565b83546124bc565b8255505050565b6125b4838383611d65565b505050565b6125c4838383611dce565b505050565b6125d38282611f1c565b5050565b6125e082611d53565b6125f36125ec8261218f565b83546124f2565b8255505050565b81156126095761260861208e565b5b6126138382611f62565b505050565b61262183611d53565b61263561262d8261218f565b848454612534565b825550505050565b61264681611c2e565b811461265157600080fd5b50565b61265d81611c60565b811461266857600080fd5b50565b60009056fea2646970667358221220cb403f7adc2fb139c3c9359219d93f9c0d9a168b2bc26c7936cfd7429f94f50064736f6c63430008040033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100f55760003560e01c8063810a9afa11610097578063b724de3a11610066578063b724de3a14610298578063cfb452b5146102c8578063ded8896b146102e6578063f2fde38b14610302576100f5565b8063810a9afa146101fc57806382b7b5001461022c5780638da5cb5b1461025c578063afc269111461027a576100f5565b8063587a8cbf116100d3578063587a8cbf146101625780635893253c14610192578063715018a6146101c2578063788243d5146101cc576100f5565b8063144ae855146100fa578063362b3e63146101165780634f896d4f14610132575b600080fd5b610114600480360381019061010f919061111f565b61031e565b005b610130600480360381019061012b919061109e565b610386565b005b61014c6004803603810190610147919061109e565b6104d3565b604051610159919061161c565b60405180910390f35b61017c6004803603810190610177919061105d565b610578565b6040516101899190611740565b60405180910390f35b6101ac60048036038101906101a7919061109e565b6105a6565b6040516101b9919061161c565b60405180910390f35b6101ca610646565b005b6101e660048036038101906101e1919061109e565b61065a565b6040516101f391906115e6565b60405180910390f35b6102166004803603810190610211919061109e565b610698565b604051610223919061171e565b60405180910390f35b61024660048036038101906102419190611018565b610816565b6040516102539190611740565b60405180910390f35b610264610841565b60405161027191906115e6565b60405180910390f35b61028261086b565b60405161028f9190611740565b60405180910390f35b6102b260048036038101906102ad9190611018565b610871565b6040516102bf9190611740565b60405180910390f35b6102d0610981565b6040516102dd9190611740565b60405180910390f35b61030060048036038101906102fb91906110c7565b610987565b005b61031c60048036038101906103179190610fef565b610b78565b005b610326610bfc565b8060696000848152602001908152602001600020818161034691906125c9565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada828260405161037a92919061178d565b60405180910390a15050565b60008060019054906101000a900460ff161590508080156103b75750600160008054906101000a900460ff1660ff16105b806103e457506103c630610c7a565b1580156103e35750600160008054906101000a900460ff1660ff16145b5b610423576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041a9061169e565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015610460576001600060016101000a81548160ff0219169083151502179055505b610468610c9d565b816065819055508160668190555080156104cf5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516104c69190611601565b60405180910390a15b5050565b60606067600083815260200190815260200160002080546104f390611fa8565b80601f016020809104026020016040519081016040528092919081815260200182805461051f90611fa8565b801561056c5780601f106105415761010080835404028352916020019161056c565b820191906000526020600020905b81548152906001019060200180831161054f57829003601f168201915b50505050509050919050565b6068818051602081018201805184825260208301602085012081835280955050505050506000915090505481565b606760205280600052604060002060009150905080546105c590611fa8565b80601f01602080910402602001604051908101604052809291908181526020018280546105f190611fa8565b801561063e5780601f106106135761010080835404028352916020019161063e565b820191906000526020600020905b81548152906001019060200180831161062157829003601f168201915b505050505081565b61064e610bfc565b6106586000610cf6565b565b60696020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b6106a0610e25565b606960008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b82821015610807578382906000526020600020906002020160405180604001604052908160008201805461076c90611fa8565b80601f016020809104026020016040519081016040528092919081815260200182805461079890611fa8565b80156107e55780601f106107ba576101008083540402835291602001916107e5565b820191906000526020600020905b8154815290600101906020018083116107c857829003601f168201915b5050505050815260200160018201548152505081526020019060010190610739565b50505050815250509050919050565b60006068838360405161082a9291906115cd565b908152602001604051809103902054905092915050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60665481565b600080606884846040516108869291906115cd565b908152602001604051809103902054146108d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108cc9061167e565b60405180910390fd5b6000606654905083836067600084815260200190815260200160002091906108fe929190610e55565b5080606885856040516109129291906115cd565b9081526020016040518091039020819055507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d8185856040516109579392919061175b565b60405180910390a16066600081548092919061097290612027565b91905055508091505092915050565b60655481565b60006067600085815260200190815260200160002080546109a790611fa8565b9050146109e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e09061163e565b60405180910390fd5b6000606883836040516109fd9291906115cd565b90815260200160405180910390205414610a4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a439061167e565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166069600085815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610af0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae7906116fe565b60405180910390fd5b8181606760008681526020019081526020016000209190610b12929190610e55565b508260688383604051610b269291906115cd565b9081526020016040518091039020819055507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c838383604051610b6b9392919061175b565b60405180910390a1505050565b610b80610bfc565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610bf0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610be79061165e565b60405180910390fd5b610bf981610cf6565b50565b610c04610dbc565b73ffffffffffffffffffffffffffffffffffffffff16610c22610841565b73ffffffffffffffffffffffffffffffffffffffff1614610c78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6f906116be565b60405180910390fd5b565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610cec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce3906116de565b60405180910390fd5b610cf4610dc4565b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600060019054906101000a900460ff16610e13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0a906116de565b60405180910390fd5b610e23610e1e610dbc565b610cf6565b565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b828054610e6190611fa8565b90600052602060002090601f016020900481019282610e835760008555610eca565b82601f10610e9c57803560ff1916838001178555610eca565b82800160010185558215610eca579182015b82811115610ec9578235825591602001919060010190610eae565b5b509050610ed79190610edb565b5090565b5b80821115610ef4576000816000905550600101610edc565b5090565b6000610f0b610f06846118b4565b61188f565b905082815260208101848484011115610f2357600080fd5b610f2e848285611eda565b509392505050565b600081359050610f458161263d565b92915050565b60008083601f840112610f5d57600080fd5b8235905067ffffffffffffffff811115610f7657600080fd5b602083019150836001820283011115610f8e57600080fd5b9250929050565b600082601f830112610fa657600080fd5b8135610fb6848260208601610ef8565b91505092915050565b600060408284031215610fd157600080fd5b81905092915050565b600081359050610fe981612654565b92915050565b60006020828403121561100157600080fd5b600061100f84828501610f36565b91505092915050565b6000806020838503121561102b57600080fd5b600083013567ffffffffffffffff81111561104557600080fd5b61105185828601610f4b565b92509250509250929050565b60006020828403121561106f57600080fd5b600082013567ffffffffffffffff81111561108957600080fd5b61109584828501610f95565b91505092915050565b6000602082840312156110b057600080fd5b60006110be84828501610fda565b91505092915050565b6000806000604084860312156110dc57600080fd5b60006110ea86828701610fda565b935050602084013567ffffffffffffffff81111561110757600080fd5b61111386828701610f4b565b92509250509250925092565b6000806040838503121561113257600080fd5b600061114085828601610fda565b925050602083013567ffffffffffffffff81111561115d57600080fd5b61116985828601610fbf565b9150509250929050565b600061117f8383611523565b905092915050565b60006111938383611572565b905092915050565b6111a481611c2e565b82525050565b6111b381611c2e565b82525050565b60006111c58385611991565b9350836020840285016111d7846118fc565b8060005b8781101561121b5784840389526111f28284611b99565b6111fc8582611173565b945061120783611977565b925060208a019950506001810190506111db565b50829750879450505050509392505050565b60006112388261194b565b6112428185611991565b93508360208202850161125485611906565b8060005b8581101561129057848403895281516112718582611187565b945061127c83611984565b925060208a01995050600181019050611258565b50829750879550505050505092915050565b6112ab81611d1d565b82525050565b60006112bd83856119a2565b93506112ca838584611eda565b6112d38361227e565b840190509392505050565b60006112ea83856119b3565b93506112f7838584611eda565b6113008361227e565b840190509392505050565b600061131783856119c4565b9350611324838584611eda565b82840190509392505050565b600061133b8261196c565b61134581856119a2565b9350611355818560208601611ee9565b61135e8161227e565b840191505092915050565b60006113748261196c565b61137e81856119b3565b935061138e818560208601611ee9565b6113978161227e565b840191505092915050565b60006113af6015836119b3565b91506113ba8261230a565b602082019050919050565b60006113d26026836119b3565b91506113dd82612333565b604082019050919050565b60006113f56019836119b3565b915061140082612382565b602082019050919050565b6000611418602e836119b3565b9150611423826123ab565b604082019050919050565b600061143b6020836119b3565b9150611446826123fa565b602082019050919050565b600061145e602b836119b3565b915061146982612423565b604082019050919050565b60006114816019836119b3565b915061148c82612472565b602082019050919050565b6000604083016114aa6000840184611ad4565b6114b7600086018261119b565b506114c56020840184611aeb565b85830360208701526114d88382846111b9565b925050508091505092915050565b60006040830160008301516114fe600086018261119b565b5060208301518482036020860152611516828261122d565b9150508091505092915050565b6000604083016115366000840184611b42565b85830360008701526115498382846112b1565b9250505061155a6020840184611bbd565b61156760208601826115af565b508091505092915050565b6000604083016000830151848203600086015261158f8282611330565b91505060208301516115a460208601826115af565b508091505092915050565b6115b881611c60565b82525050565b6115c781611c60565b82525050565b60006115da82848661130b565b91508190509392505050565b60006020820190506115fb60008301846111aa565b92915050565b600060208201905061161660008301846112a2565b92915050565b600060208201905081810360008301526116368184611369565b905092915050565b60006020820190508181036000830152611657816113a2565b9050919050565b60006020820190508181036000830152611677816113c5565b9050919050565b60006020820190508181036000830152611697816113e8565b9050919050565b600060208201905081810360008301526116b78161140b565b9050919050565b600060208201905081810360008301526116d78161142e565b9050919050565b600060208201905081810360008301526116f781611451565b9050919050565b6000602082019050818103600083015261171781611474565b9050919050565b6000602082019050818103600083015261173881846114e6565b905092915050565b600060208201905061175560008301846115be565b92915050565b600060408201905061177060008301866115be565b81810360208301526117838184866112de565b9050949350505050565b60006040820190506117a260008301856115be565b81810360208301526117b48184611497565b90509392505050565b600080833560016020038436030381126117d657600080fd5b80840192508235915067ffffffffffffffff8211156117f457600080fd5b60208301925060208202360383131561180c57600080fd5b509250929050565b6000808335600160200384360303811261182d57600080fd5b80840192508235915067ffffffffffffffff82111561184b57600080fd5b60208301925060018202360383131561186357600080fd5b509250929050565b60008235600160400383360303811261188357600080fd5b80830191505092915050565b60006118996118aa565b90506118a58282611ff6565b919050565b6000604051905090565b600067ffffffffffffffff8211156118cf576118ce61211b565b5b6118d88261227e565b9050602081019050919050565b60008190506118f5826002611bd4565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6020841060008114611a2857601f8411600181146119f8576119f18685611fda565b8355611a22565b611a018361192b565b611a166020601f880104820160018301611c85565b611a20878561249b565b505b50611a71565b611a318261192b565b6020601f8701048101601f87168015611a5257611a51816001840361214a565b5b611a646020601f890104840183611c85565b6001886002021785555050505b5050505050565b6020831060008114611ac3576020851060008114611aa157611a9a8685611fda565b8355611abd565b8360ff1916935083611ab28461192b565b556001866002020183555b50611acd565b6001856002020182555b5050505050565b6000611ae36020840184610f36565b905092915050565b60008083356001602003843603038112611b0457600080fd5b83810192508235915060208301925067ffffffffffffffff821115611b2857600080fd5b602082023603841315611b3a57600080fd5b509250929050565b60008083356001602003843603038112611b5b57600080fd5b83810192508235915060208301925067ffffffffffffffff821115611b7f57600080fd5b600182023603841315611b9157600080fd5b509250929050565b600082356001604003833603038112611bb157600080fd5b82810191505092915050565b6000611bcc6020840184610fda565b905092915050565b6000611bdf82611c60565b9150611bea83611c60565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611c2357611c226120bd565b5b828202905092915050565b6000611c3982611c40565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b611c82600082612229565b50565b5b81811015611ca457611c996000826122f2565b600181019050611c86565b5050565b5b81811015611cc757611cbc6000826122d4565b600281019050611ca9565b5050565b81811015611ce957611cde6000826122f2565b600181019050611ccb565b5050565b611cfa60008083016122b6565b611d086000600183016122f2565b50565b6000611d1682611d2f565b9050919050565b6000611d2882611c6a565b9050919050565b6000611d3a82611d41565b9050919050565b6000611d4c82611c40565b9050919050565b6000611d5e82611c60565b9050919050565b611d6f8383611940565b611d7981836121c5565b611d82836118fc565b611d8b83611916565b6000805b84811015611dc457611da1848861186b565b611dac8184866125fa565b60208501945060028401935050600181019050611d8f565b5050505050505050565b611dd88383611961565b67ffffffffffffffff811115611df157611df061211b565b5b611dfb8254611fa8565b600080601f8411601f84111715611e1857611e158561192b565b90505b601f831115611e4b576020601f85010481016020851015611e37578190505b611e496020601f860104830182611c85565b505b601f841160018114611e785760008515611e66578388013590505b611e708682611fda565b875550611ed0565b601f1985168260005b82811015611ea657858a01358255600182019150602086019550602081019050611e81565b87831015611ec357858a0135611ebf601f8a1682612070565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b83811015611f07578082015181840152602081019050611eec565b83811115611f16576000848401525b50505050565b600081016000830180611f2e81612199565b9050611f3a8184612586565b5050506001810160208301611f4f81856117bd565b611f5a8183866125a9565b505050505050565b6000810160008301611f748185611814565b611f7f8183866125b9565b50505050600181016020830180611f95816121af565b9050611fa181846125d7565b5050505050565b60006002820490506001821680611fc057607f821691505b60208210811415611fd457611fd36120ec565b5b50919050565b6000611fe68383612070565b9150826002028217905092915050565b611fff8261227e565b810181811067ffffffffffffffff8211171561201e5761201d61211b565b5b80604052505050565b600061203282611c60565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612065576120646120bd565b5b600182019050919050565b6000612081600019846008026122a9565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61217a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff836020036008026122a9565b815481168255505050565b6000819050919050565b6000819050919050565b600081356121a68161263d565b80915050919050565b600081356121bc81612654565b80915050919050565b680100000000000000008211156121df576121de61211b565b5b6121e881611956565b82825580831015612224576121fc816118e5565b612205846118e5565b61220e84611916565b81810183820161221e8183611ca8565b50505050505b505050565b680100000000000000008211156122435761224261211b565b5b805461224e81611fa8565b808411156122635761226284828486611a78565b5b8084101561227857612277848284866119cf565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b600082146122c7576122c661208e565b5b6122d081611c77565b5050565b600082146122e5576122e461208e565b5b6122ee81611ced565b5050565b6122fa61266b565b612305818484612618565b505050565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f73747265616d20616c7265616479206861732061206450494400000000000000600082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b6124a48161192b565b6124af838254611fda565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff6124dc8461228f565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61251e8461228f565b9350801983169250808416831791505092915050565b6000600883026125647fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261229c565b61256e868361229c565b95508019841693508086168417925050509392505050565b61258f82611d0b565b6125a261259b82612185565b83546124bc565b8255505050565b6125b4838383611d65565b505050565b6125c4838383611dce565b505050565b6125d38282611f1c565b5050565b6125e082611d53565b6125f36125ec8261218f565b83546124f2565b8255505050565b81156126095761260861208e565b5b6126138382611f62565b505050565b61262183611d53565b61263561262d8261218f565b848454612534565b825550505050565b61264681611c2e565b811461265157600080fd5b50565b61265d81611c60565b811461266857600080fd5b50565b60009056fea2646970667358221220cb403f7adc2fb139c3c9359219d93f9c0d9a168b2bc26c7936cfd7429f94f50064736f6c63430008040033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/desci-contracts/contracts/DpidAliasRegistry.sol b/desci-contracts/contracts/DpidAliasRegistry.sol index f7b2010d..960df556 100644 --- a/desci-contracts/contracts/DpidAliasRegistry.sol +++ b/desci-contracts/contracts/DpidAliasRegistry.sol @@ -10,9 +10,11 @@ contract DpidAliasRegistry is OwnableUpgradeable { // Incremented on each dPID mint uint256 public nextDpid; - // dpid => codex streamID + // dpid => codex streamID (resolve dPID) mapping(uint256 => string) public registry; + // codex streamID => dpid (check for existing aliases) + mapping(string => uint256) public reverseRegistry; /// @custom:oz-upgrades-unsafe-allow constructor constructor() { @@ -26,13 +28,21 @@ contract DpidAliasRegistry is OwnableUpgradeable { } /** - * Lookup the codex stream ID of a given dPID - * @param dpid the alias to lookup + * Resolve the codex stream ID of a given dPID + * @param dpid the alias to resolve */ - function lookup(uint256 dpid) public view returns(string memory) { + function resolve(uint256 dpid) public view returns(string memory) { return registry[dpid]; } + /** + * Find the dPID of a given codex stream ID, if it exists + * @param streamId the codex stream ID to search for + */ + function find(string calldata streamId) public view returns(uint256) { + return reverseRegistry[streamId]; + } + event DpidMinted ( uint256 dpid, string streamID @@ -40,15 +50,23 @@ contract DpidAliasRegistry is OwnableUpgradeable { /** * Claim the next free dPID by pointing it to a codex stream ID - * + * * @param streamId the codex stream ID to alias */ - function mintDpid(string calldata streamId) public returns(uint256) { + function mintDpid(string calldata streamId) public returns(uint256) { + require(reverseRegistry[streamId] == 0, "stream already has a dPID"); + uint256 thisDpid = nextDpid; + + // map this dPID to the passed stream ID registry[thisDpid] = streamId; + // map the passed stream ID to this dPID + reverseRegistry[streamId] = thisDpid; + emit DpidMinted(thisDpid, streamId); - + + // Move counter to next free dPID nextDpid++; return thisDpid; } @@ -71,13 +89,14 @@ contract DpidAliasRegistry is OwnableUpgradeable { * Maps dPIDs before _firstDpid to it's complete history. * This allows resolving every old state of a legacy dPID * using only this contract. If the author wants to update - * this history, they need to call migrateDpid. - */ + * this history, they need to call upgradeDpid. + */ mapping(uint256 => LegacyDpidEntry) public legacy; /** - * Lookup the token ID of an unmigrated, legacy dPID. - * Use this to + * Lookup the state of an unmigrated, legacy dPID. + * Use this to resolve the history of a dPID that hasn't been updated + * since the protocol upgrade, or to check the timestamps of old versions. * @param dpid the alias to lookup */ function legacyLookup(uint256 dpid) public view returns(LegacyDpidEntry memory) { @@ -93,24 +112,30 @@ contract DpidAliasRegistry is OwnableUpgradeable { * The owner of a migrated ResearchObject token can call this function * to claim the same dPID in this alias registry by pointing it to a codex * streamID representing the same research object. - * + * * This is an at-most-once operation, as the registry is immutable. * The caller must make sure the stream represents the same history, * and that it controls the stream. - * + * * The legacy entry is deleted when migrated. - * + * * @param dpid the dPID to migrate * @param streamId the codex stream ID that shall supersede the legacy history */ function upgradeDpid(uint256 dpid, string calldata streamId) public { // Assert that this dPID has not been set in the main registry require(bytes(registry[dpid]).length == 0, "dpid already upgraded"); + + // ??????????????????????????????????????????????????? + // Assert that this stream hasn't already got an alias + require(reverseRegistry[streamId] == 0, "stream already has a dPID"); + // Assert that the tx was made by the owner of the imported entry require(legacy[dpid].owner == msg.sender, "unauthorized dpid upgrade"); // Reclaim old dpid registry[dpid] = streamId; + reverseRegistry[streamId] = dpid; emit UpgradedDpid(dpid, streamId); diff --git a/desci-contracts/index.ts b/desci-contracts/index.ts index 7ded7bf6..624df4a5 100644 --- a/desci-contracts/index.ts +++ b/desci-contracts/index.ts @@ -15,4 +15,7 @@ export const contracts = { prodRoInfo, prodDpidInfo, localDpidAliasInfo, + // TODO update as soon as deployment is done + devDpidAliasInfo: localDpidAliasInfo, + prodDpidAliasInfo: localDpidAliasInfo, }; diff --git a/desci-contracts/package.json b/desci-contracts/package.json index ba1f4829..7ae725f2 100644 --- a/desci-contracts/package.json +++ b/desci-contracts/package.json @@ -1,7 +1,7 @@ { "name": "@desci-labs/desci-contracts", "description": "Smart contracts implementing DeSci Nodes on-chain state and logic", - "version": "0.2.5-rc2", + "version": "0.2.5-rc4", "license": "MIT", "scripts": { "test": "hardhat clean && hardhat test", diff --git a/desci-contracts/test/DpidAliasRegistry.ts b/desci-contracts/test/DpidAliasRegistry.ts index fb4825a1..99643cb2 100644 --- a/desci-contracts/test/DpidAliasRegistry.ts +++ b/desci-contracts/test/DpidAliasRegistry.ts @@ -89,11 +89,11 @@ describe("dPID", () => { describe("alias registry", () => { const STREAM_A = "kjzl6kcym7w8y7i5ugaq9a3vlm7hhuaf4bpl5o5qykeh4qtsa12c6rb5ekw6aaa"; - + describe("entry", () => { let tx: ContractTransaction; let res: ContractReceipt; - + before(async () => { tx = await dpidAliasRegistry.mintDpid(STREAM_A); res = await tx.wait(); @@ -129,7 +129,7 @@ describe("dPID", () => { describe("legacy entry", () => { let migrationEntry: DpidAliasRegistry.LegacyDpidEntryStruct; - + before(async () => { migrationEntry = { owner: user1.address, // of dpid owner @@ -141,7 +141,7 @@ describe("dPID", () => { ], }; }); - + describe("import", () => { let successReceipt: ContractReceipt; @@ -154,7 +154,7 @@ describe("dPID", () => { it("can be resolved", async () => { const legacyEntry = await dpidAliasRegistry.legacyLookup(0); - + expect(legacyEntry.owner).to.equal(migrationEntry.owner); expect(legacyEntry.versions.length).to.equal(1); expect(legacyEntry.versions[0].cid).to.equal("bafybeihdwdcefgh4dqkjv67uzcmw7ojee6xedzdetojuzjevtenxquvyku"); @@ -170,15 +170,15 @@ describe("dPID", () => { expect(dpid).to.equal(0); expect(owner).to.equal(user1.address); }); - + it("can NOT be done by others", async () => { const doImport = async () => await dpidAliasRegistry .importLegacyDpid(1, migrationEntry); - + await expect(doImport()).to.be.rejectedWith("caller is not the owner"); }); }); - + describe("upgrade", () => { let successReceipt: ContractReceipt; @@ -186,7 +186,7 @@ describe("dPID", () => { const doUpgrade = async () => await dpidAliasRegistry .connect(user2) .upgradeDpid(0, STREAM_A); - + await expect(doUpgrade()).to.be.rejectedWith("unauthorized dpid upgrade"); }); @@ -202,14 +202,14 @@ describe("dPID", () => { const tx = await dpidAliasRegistry.upgradeDpid(0, STREAM_A); successReceipt = await tx.wait(); - const upgradedEntry = await dpidAliasRegistry.lookup(0); + const upgradedEntry = await dpidAliasRegistry.resolve(0); expect(upgradedEntry).to.equal(STREAM_A); }); it("cannot be done twice", async () => { const doSecondUpgrade = async () => await dpidAliasRegistry.upgradeDpid(0, STREAM_A); - + await expect(doSecondUpgrade()).to.be.rejectedWith("dpid already upgraded"); }); diff --git a/desci-contracts/typechain-types/DpidAliasRegistry.ts b/desci-contracts/typechain-types/DpidAliasRegistry.ts index 9e818892..7e8aa99c 100644 --- a/desci-contracts/typechain-types/DpidAliasRegistry.ts +++ b/desci-contracts/typechain-types/DpidAliasRegistry.ts @@ -43,16 +43,18 @@ export interface DpidAliasRegistryInterface extends utils.Interface { contractName: "DpidAliasRegistry"; functions: { "__DpidAliasRegistry_init(uint256)": FunctionFragment; + "find(string)": FunctionFragment; "firstDpid()": FunctionFragment; "importLegacyDpid(uint256,(address,(string,uint256)[]))": FunctionFragment; "legacy(uint256)": FunctionFragment; "legacyLookup(uint256)": FunctionFragment; - "lookup(uint256)": FunctionFragment; "mintDpid(string)": FunctionFragment; "nextDpid()": FunctionFragment; "owner()": FunctionFragment; "registry(uint256)": FunctionFragment; "renounceOwnership()": FunctionFragment; + "resolve(uint256)": FunctionFragment; + "reverseRegistry(string)": FunctionFragment; "transferOwnership(address)": FunctionFragment; "upgradeDpid(uint256,string)": FunctionFragment; }; @@ -61,6 +63,7 @@ export interface DpidAliasRegistryInterface extends utils.Interface { functionFragment: "__DpidAliasRegistry_init", values: [BigNumberish] ): string; + encodeFunctionData(functionFragment: "find", values: [string]): string; encodeFunctionData(functionFragment: "firstDpid", values?: undefined): string; encodeFunctionData( functionFragment: "importLegacyDpid", @@ -74,10 +77,6 @@ export interface DpidAliasRegistryInterface extends utils.Interface { functionFragment: "legacyLookup", values: [BigNumberish] ): string; - encodeFunctionData( - functionFragment: "lookup", - values: [BigNumberish] - ): string; encodeFunctionData(functionFragment: "mintDpid", values: [string]): string; encodeFunctionData(functionFragment: "nextDpid", values?: undefined): string; encodeFunctionData(functionFragment: "owner", values?: undefined): string; @@ -89,6 +88,14 @@ export interface DpidAliasRegistryInterface extends utils.Interface { functionFragment: "renounceOwnership", values?: undefined ): string; + encodeFunctionData( + functionFragment: "resolve", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "reverseRegistry", + values: [string] + ): string; encodeFunctionData( functionFragment: "transferOwnership", values: [string] @@ -102,6 +109,7 @@ export interface DpidAliasRegistryInterface extends utils.Interface { functionFragment: "__DpidAliasRegistry_init", data: BytesLike ): Result; + decodeFunctionResult(functionFragment: "find", data: BytesLike): Result; decodeFunctionResult(functionFragment: "firstDpid", data: BytesLike): Result; decodeFunctionResult( functionFragment: "importLegacyDpid", @@ -112,7 +120,6 @@ export interface DpidAliasRegistryInterface extends utils.Interface { functionFragment: "legacyLookup", data: BytesLike ): Result; - decodeFunctionResult(functionFragment: "lookup", data: BytesLike): Result; decodeFunctionResult(functionFragment: "mintDpid", data: BytesLike): Result; decodeFunctionResult(functionFragment: "nextDpid", data: BytesLike): Result; decodeFunctionResult(functionFragment: "owner", data: BytesLike): Result; @@ -121,6 +128,11 @@ export interface DpidAliasRegistryInterface extends utils.Interface { functionFragment: "renounceOwnership", data: BytesLike ): Result; + decodeFunctionResult(functionFragment: "resolve", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "reverseRegistry", + data: BytesLike + ): Result; decodeFunctionResult( functionFragment: "transferOwnership", data: BytesLike @@ -211,6 +223,8 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; + find(streamId: string, overrides?: CallOverrides): Promise<[BigNumber]>; + firstDpid(overrides?: CallOverrides): Promise<[BigNumber]>; importLegacyDpid( @@ -229,8 +243,6 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: CallOverrides ): Promise<[DpidAliasRegistry.LegacyDpidEntryStructOutput]>; - lookup(dpid: BigNumberish, overrides?: CallOverrides): Promise<[string]>; - mintDpid( streamId: string, overrides?: Overrides & { from?: string | Promise } @@ -246,6 +258,13 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; + resolve(dpid: BigNumberish, overrides?: CallOverrides): Promise<[string]>; + + reverseRegistry( + arg0: string, + overrides?: CallOverrides + ): Promise<[BigNumber]>; + transferOwnership( newOwner: string, overrides?: Overrides & { from?: string | Promise } @@ -263,6 +282,8 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; + find(streamId: string, overrides?: CallOverrides): Promise; + firstDpid(overrides?: CallOverrides): Promise; importLegacyDpid( @@ -278,8 +299,6 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: CallOverrides ): Promise; - lookup(dpid: BigNumberish, overrides?: CallOverrides): Promise; - mintDpid( streamId: string, overrides?: Overrides & { from?: string | Promise } @@ -295,6 +314,10 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; + resolve(dpid: BigNumberish, overrides?: CallOverrides): Promise; + + reverseRegistry(arg0: string, overrides?: CallOverrides): Promise; + transferOwnership( newOwner: string, overrides?: Overrides & { from?: string | Promise } @@ -312,6 +335,8 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: CallOverrides ): Promise; + find(streamId: string, overrides?: CallOverrides): Promise; + firstDpid(overrides?: CallOverrides): Promise; importLegacyDpid( @@ -327,8 +352,6 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: CallOverrides ): Promise; - lookup(dpid: BigNumberish, overrides?: CallOverrides): Promise; - mintDpid(streamId: string, overrides?: CallOverrides): Promise; nextDpid(overrides?: CallOverrides): Promise; @@ -339,6 +362,13 @@ export interface DpidAliasRegistry extends BaseContract { renounceOwnership(overrides?: CallOverrides): Promise; + resolve(dpid: BigNumberish, overrides?: CallOverrides): Promise; + + reverseRegistry( + arg0: string, + overrides?: CallOverrides + ): Promise; + transferOwnership( newOwner: string, overrides?: CallOverrides @@ -389,6 +419,8 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; + find(streamId: string, overrides?: CallOverrides): Promise; + firstDpid(overrides?: CallOverrides): Promise; importLegacyDpid( @@ -404,8 +436,6 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: CallOverrides ): Promise; - lookup(dpid: BigNumberish, overrides?: CallOverrides): Promise; - mintDpid( streamId: string, overrides?: Overrides & { from?: string | Promise } @@ -421,6 +451,13 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; + resolve(dpid: BigNumberish, overrides?: CallOverrides): Promise; + + reverseRegistry( + arg0: string, + overrides?: CallOverrides + ): Promise; + transferOwnership( newOwner: string, overrides?: Overrides & { from?: string | Promise } @@ -439,6 +476,11 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; + find( + streamId: string, + overrides?: CallOverrides + ): Promise; + firstDpid(overrides?: CallOverrides): Promise; importLegacyDpid( @@ -457,11 +499,6 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: CallOverrides ): Promise; - lookup( - dpid: BigNumberish, - overrides?: CallOverrides - ): Promise; - mintDpid( streamId: string, overrides?: Overrides & { from?: string | Promise } @@ -480,6 +517,16 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: Overrides & { from?: string | Promise } ): Promise; + resolve( + dpid: BigNumberish, + overrides?: CallOverrides + ): Promise; + + reverseRegistry( + arg0: string, + overrides?: CallOverrides + ): Promise; + transferOwnership( newOwner: string, overrides?: Overrides & { from?: string | Promise } diff --git a/desci-contracts/typechain-types/factories/DpidAliasRegistry__factory.ts b/desci-contracts/typechain-types/factories/DpidAliasRegistry__factory.ts index e333bfee..4598e9f9 100644 --- a/desci-contracts/typechain-types/factories/DpidAliasRegistry__factory.ts +++ b/desci-contracts/typechain-types/factories/DpidAliasRegistry__factory.ts @@ -140,6 +140,25 @@ const _abi = [ stateMutability: "nonpayable", type: "function", }, + { + inputs: [ + { + internalType: "string", + name: "streamId", + type: "string", + }, + ], + name: "find", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, { inputs: [], name: "firstDpid", @@ -257,25 +276,6 @@ const _abi = [ stateMutability: "view", type: "function", }, - { - inputs: [ - { - internalType: "uint256", - name: "dpid", - type: "uint256", - }, - ], - name: "lookup", - outputs: [ - { - internalType: "string", - name: "", - type: "string", - }, - ], - stateMutability: "view", - type: "function", - }, { inputs: [ { @@ -347,6 +347,44 @@ const _abi = [ stateMutability: "nonpayable", type: "function", }, + { + inputs: [ + { + internalType: "uint256", + name: "dpid", + type: "uint256", + }, + ], + name: "resolve", + outputs: [ + { + internalType: "string", + name: "", + type: "string", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "string", + name: "", + type: "string", + }, + ], + name: "reverseRegistry", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, { inputs: [ { @@ -381,7 +419,7 @@ const _abi = [ ]; const _bytecode = - "0x60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d3565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000127565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff161015620000ed5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e4919062000149565b60405180910390a15b565b6000620000fe60278362000166565b91506200010b8262000184565b604082019050919050565b620001218162000177565b82525050565b600060208201905081810360008301526200014281620000ef565b9050919050565b600060208201905062000160600083018462000116565b92915050565b600082825260208201905092915050565b600060ff82169050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b6122d280620001e36000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c8063810a9afa1161008c578063b724de3a11610066578063b724de3a14610212578063cfb452b514610242578063ded8896b14610260578063f2fde38b1461027c576100cf565b8063810a9afa146101a65780638da5cb5b146101d6578063afc26911146101f4576100cf565b80630a874df6146100d4578063144ae85514610104578063362b3e63146101205780635893253c1461013c578063715018a61461016c578063788243d514610176575b600080fd5b6100ee60048036038101906100e99190610e06565b610298565b6040516100fb9190611323565b60405180910390f35b61011e60048036038101906101199190610e87565b61033d565b005b61013a60048036038101906101359190610e06565b6103a5565b005b61015660048036038101906101519190610e06565b6104f2565b6040516101639190611323565b60405180910390f35b610174610592565b005b610190600480360381019061018b9190610e06565b6105a6565b60405161019d91906112ed565b60405180910390f35b6101c060048036038101906101bb9190610e06565b6105e4565b6040516101cd9190611405565b60405180910390f35b6101de610762565b6040516101eb91906112ed565b60405180910390f35b6101fc61078c565b6040516102099190611427565b60405180910390f35b61022c60048036038101906102279190610dc1565b610792565b6040516102399190611427565b60405180910390f35b61024a61081a565b6040516102579190611427565b60405180910390f35b61027a60048036038101906102759190610e2f565b610820565b005b61029660048036038101906102919190610d98565b610989565b005b60606067600083815260200190815260200160002080546102b890611c2e565b80601f01602080910402602001604051908101604052809291908181526020018280546102e490611c2e565b80156103315780601f1061030657610100808354040283529160200191610331565b820191906000526020600020905b81548152906001019060200180831161031457829003601f168201915b50505050509050919050565b610345610a0d565b8060686000848152602001908152602001600020818161036591906121f5565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada8282604051610399929190611474565b60405180910390a15050565b60008060019054906101000a900460ff161590508080156103d65750600160008054906101000a900460ff1660ff16105b8061040357506103e530610a8b565b1580156104025750600160008054906101000a900460ff1660ff16145b5b610442576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161043990611385565b60405180910390fd5b60016000806101000a81548160ff021916908360ff160217905550801561047f576001600060016101000a81548160ff0219169083151502179055505b610487610aae565b816065819055508160668190555080156104ee5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516104e59190611308565b60405180910390a15b5050565b6067602052806000526040600020600091509050805461051190611c2e565b80601f016020809104026020016040519081016040528092919081815260200182805461053d90611c2e565b801561058a5780601f1061055f5761010080835404028352916020019161058a565b820191906000526020600020905b81548152906001019060200180831161056d57829003601f168201915b505050505081565b61059a610a0d565b6105a46000610b07565b565b60686020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b6105ec610c36565b606860008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b8282101561075357838290600052602060002090600202016040518060400160405290816000820180546106b890611c2e565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490611c2e565b80156107315780601f1061070657610100808354040283529160200191610731565b820191906000526020600020905b81548152906001019060200180831161071457829003601f168201915b5050505050815260200160018201548152505081526020019060010190610685565b50505050815250509050919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60665481565b600080606654905083836067600084815260200190815260200160002091906107bc929190610c66565b507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d8185856040516107f093929190611442565b60405180910390a16066600081548092919061080b90611c7c565b91905055508091505092915050565b60655481565b600060676000858152602001908152602001600020805461084090611c2e565b905014610882576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161087990611345565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166068600085815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610926576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091d906113e5565b60405180910390fd5b8181606760008681526020019081526020016000209190610948929190610c66565b507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c83838360405161097c93929190611442565b60405180910390a1505050565b610991610a0d565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610a01576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109f890611365565b60405180910390fd5b610a0a81610b07565b50565b610a15610bcd565b73ffffffffffffffffffffffffffffffffffffffff16610a33610762565b73ffffffffffffffffffffffffffffffffffffffff1614610a89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a80906113a5565b60405180910390fd5b565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610afd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af4906113c5565b60405180910390fd5b610b05610bd5565b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600060019054906101000a900460ff16610c24576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1b906113c5565b60405180910390fd5b610c34610c2f610bcd565b610b07565b565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b828054610c7290611c2e565b90600052602060002090601f016020900481019282610c945760008555610cdb565b82601f10610cad57803560ff1916838001178555610cdb565b82800160010185558215610cdb579182015b82811115610cda578235825591602001919060010190610cbf565b5b509050610ce89190610cec565b5090565b5b80821115610d05576000816000905550600101610ced565b5090565b600081359050610d1881612269565b92915050565b60008083601f840112610d3057600080fd5b8235905067ffffffffffffffff811115610d4957600080fd5b602083019150836001820283011115610d6157600080fd5b9250929050565b600060408284031215610d7a57600080fd5b81905092915050565b600081359050610d9281612280565b92915050565b600060208284031215610daa57600080fd5b6000610db884828501610d09565b91505092915050565b60008060208385031215610dd457600080fd5b600083013567ffffffffffffffff811115610dee57600080fd5b610dfa85828601610d1e565b92509250509250929050565b600060208284031215610e1857600080fd5b6000610e2684828501610d83565b91505092915050565b600080600060408486031215610e4457600080fd5b6000610e5286828701610d83565b935050602084013567ffffffffffffffff811115610e6f57600080fd5b610e7b86828701610d1e565b92509250509250925092565b60008060408385031215610e9a57600080fd5b6000610ea885828601610d83565b925050602083013567ffffffffffffffff811115610ec557600080fd5b610ed185828601610d68565b9150509250929050565b6000610ee78383611243565b905092915050565b6000610efb8383611292565b905092915050565b610f0c816118b4565b82525050565b610f1b816118b4565b82525050565b6000610f2d8385611622565b935083602084028501610f3f8461158d565b8060005b87811015610f83578484038952610f5a828461181f565b610f648582610edb565b9450610f6f83611608565b925060208a01995050600181019050610f43565b50829750879450505050509392505050565b6000610fa0826115dc565b610faa8185611622565b935083602082028501610fbc85611597565b8060005b85811015610ff85784840389528151610fd98582610eef565b9450610fe483611615565b925060208a01995050600181019050610fc0565b50829750879550505050505092915050565b611013816119a3565b82525050565b60006110258385611633565b9350611032838584611b60565b61103b83611ed3565b840190509392505050565b60006110528385611644565b935061105f838584611b60565b61106883611ed3565b840190509392505050565b600061107e826115fd565b6110888185611633565b9350611098818560208601611b6f565b6110a181611ed3565b840191505092915050565b60006110b7826115fd565b6110c18185611644565b93506110d1818560208601611b6f565b6110da81611ed3565b840191505092915050565b60006110f2601583611644565b91506110fd82611f5f565b602082019050919050565b6000611115602683611644565b915061112082611f88565b604082019050919050565b6000611138602e83611644565b915061114382611fd7565b604082019050919050565b600061115b602083611644565b915061116682612026565b602082019050919050565b600061117e602b83611644565b91506111898261204f565b604082019050919050565b60006111a1601983611644565b91506111ac8261209e565b602082019050919050565b6000604083016111ca600084018461175a565b6111d76000860182610f03565b506111e56020840184611771565b85830360208701526111f8838284610f21565b925050508091505092915050565b600060408301600083015161121e6000860182610f03565b50602083015184820360208601526112368282610f95565b9150508091505092915050565b60006040830161125660008401846117c8565b8583036000870152611269838284611019565b9250505061127a6020840184611843565b61128760208601826112cf565b508091505092915050565b600060408301600083015184820360008601526112af8282611073565b91505060208301516112c460208601826112cf565b508091505092915050565b6112d8816118e6565b82525050565b6112e7816118e6565b82525050565b60006020820190506113026000830184610f12565b92915050565b600060208201905061131d600083018461100a565b92915050565b6000602082019050818103600083015261133d81846110ac565b905092915050565b6000602082019050818103600083015261135e816110e5565b9050919050565b6000602082019050818103600083015261137e81611108565b9050919050565b6000602082019050818103600083015261139e8161112b565b9050919050565b600060208201905081810360008301526113be8161114e565b9050919050565b600060208201905081810360008301526113de81611171565b9050919050565b600060208201905081810360008301526113fe81611194565b9050919050565b6000602082019050818103600083015261141f8184611206565b905092915050565b600060208201905061143c60008301846112de565b92915050565b600060408201905061145760008301866112de565b818103602083015261146a818486611046565b9050949350505050565b600060408201905061148960008301856112de565b818103602083015261149b81846111b7565b90509392505050565b600080833560016020038436030381126114bd57600080fd5b80840192508235915067ffffffffffffffff8211156114db57600080fd5b6020830192506020820236038313156114f357600080fd5b509250929050565b6000808335600160200384360303811261151457600080fd5b80840192508235915067ffffffffffffffff82111561153257600080fd5b60208301925060018202360383131561154a57600080fd5b509250929050565b60008235600160400383360303811261156a57600080fd5b80830191505092915050565b600081905061158682600261185a565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b60208410600081146116ae57601f84116001811461167e576116778685611c60565b83556116a8565b611687836115bc565b61169c6020601f88010482016001830161190b565b6116a687856120c7565b505b506116f7565b6116b7826115bc565b6020601f8701048101601f871680156116d8576116d78160018403611d9f565b5b6116ea6020601f89010484018361190b565b6001886002021785555050505b5050505050565b6020831060008114611749576020851060008114611727576117208685611c60565b8355611743565b8360ff1916935083611738846115bc565b556001866002020183555b50611753565b6001856002020182555b5050505050565b60006117696020840184610d09565b905092915050565b6000808335600160200384360303811261178a57600080fd5b83810192508235915060208301925067ffffffffffffffff8211156117ae57600080fd5b6020820236038413156117c057600080fd5b509250929050565b600080833560016020038436030381126117e157600080fd5b83810192508235915060208301925067ffffffffffffffff82111561180557600080fd5b60018202360384131561181757600080fd5b509250929050565b60008235600160400383360303811261183757600080fd5b82810191505092915050565b60006118526020840184610d83565b905092915050565b6000611865826118e6565b9150611870836118e6565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156118a9576118a8611d12565b5b828202905092915050565b60006118bf826118c6565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b611908600082611e7e565b50565b5b8181101561192a5761191f600082611f47565b60018101905061190c565b5050565b5b8181101561194d57611942600082611f29565b60028101905061192f565b5050565b8181101561196f57611964600082611f47565b600181019050611951565b5050565b6119806000808301611f0b565b61198e600060018301611f47565b50565b600061199c826119b5565b9050919050565b60006119ae826118f0565b9050919050565b60006119c0826119c7565b9050919050565b60006119d2826118c6565b9050919050565b60006119e4826118e6565b9050919050565b6119f583836115d1565b6119ff8183611e1a565b611a088361158d565b611a11836115a7565b6000805b84811015611a4a57611a278488611552565b611a32818486612226565b60208501945060028401935050600181019050611a15565b5050505050505050565b611a5e83836115f2565b67ffffffffffffffff811115611a7757611a76611d70565b5b611a818254611c2e565b600080601f8411601f84111715611a9e57611a9b856115bc565b90505b601f831115611ad1576020601f85010481016020851015611abd578190505b611acf6020601f86010483018261190b565b505b601f841160018114611afe5760008515611aec578388013590505b611af68682611c60565b875550611b56565b601f1985168260005b82811015611b2c57858a01358255600182019150602086019550602081019050611b07565b87831015611b4957858a0135611b45601f8a1682611cc5565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b83811015611b8d578082015181840152602081019050611b72565b83811115611b9c576000848401525b50505050565b600081016000830180611bb481611dee565b9050611bc081846121b2565b5050506001810160208301611bd581856114a4565b611be08183866121d5565b505050505050565b6000810160008301611bfa81856114fb565b611c058183866121e5565b50505050600181016020830180611c1b81611e04565b9050611c278184612203565b5050505050565b60006002820490506001821680611c4657607f821691505b60208210811415611c5a57611c59611d41565b5b50919050565b6000611c6c8383611cc5565b9150826002028217905092915050565b6000611c87826118e6565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415611cba57611cb9611d12565b5b600182019050919050565b6000611cd660001984600802611efe565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611dcf7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83602003600802611efe565b815481168255505050565b6000819050919050565b6000819050919050565b60008135611dfb81612269565b80915050919050565b60008135611e1181612280565b80915050919050565b68010000000000000000821115611e3457611e33611d70565b5b611e3d816115e7565b82825580831015611e7957611e5181611576565b611e5a84611576565b611e63846115a7565b818101838201611e73818361192e565b50505050505b505050565b68010000000000000000821115611e9857611e97611d70565b5b8054611ea381611c2e565b80841115611eb857611eb7848284866116fe565b5b80841015611ecd57611ecc84828486611655565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b60008214611f1c57611f1b611ce3565b5b611f25816118fd565b5050565b60008214611f3a57611f39611ce3565b5b611f4381611973565b5050565b611f4f612297565b611f5a818484612244565b505050565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b6120d0816115bc565b6120db838254611c60565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff61210884611ee4565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61214a84611ee4565b9350801983169250808416831791505092915050565b6000600883026121907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82611ef1565b61219a8683611ef1565b95508019841693508086168417925050509392505050565b6121bb82611991565b6121ce6121c782611dda565b83546120e8565b8255505050565b6121e08383836119eb565b505050565b6121f0838383611a54565b505050565b6121ff8282611ba2565b5050565b61220c826119d9565b61221f61221882611de4565b835461211e565b8255505050565b811561223557612234611ce3565b5b61223f8382611be8565b505050565b61224d836119d9565b61226161225982611de4565b848454612160565b825550505050565b612272816118b4565b811461227d57600080fd5b50565b612289816118e6565b811461229457600080fd5b50565b60009056fea264697066735822122084f5f1681ed8582b0b01a3c050af63e3bc886fc8eb1d7bfbad5710635ba9f00f64736f6c63430008040033"; + "0x60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d3565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000127565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff161015620000ed5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e4919062000149565b60405180910390a15b565b6000620000fe60278362000166565b91506200010b8262000184565b604082019050919050565b620001218162000177565b82525050565b600060208201905081810360008301526200014281620000ef565b9050919050565b600060208201905062000160600083018462000116565b92915050565b600082825260208201905092915050565b600060ff82169050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b6126a680620001e36000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c8063810a9afa11610097578063b724de3a11610066578063b724de3a14610298578063cfb452b5146102c8578063ded8896b146102e6578063f2fde38b14610302576100f5565b8063810a9afa146101fc57806382b7b5001461022c5780638da5cb5b1461025c578063afc269111461027a576100f5565b8063587a8cbf116100d3578063587a8cbf146101625780635893253c14610192578063715018a6146101c2578063788243d5146101cc576100f5565b8063144ae855146100fa578063362b3e63146101165780634f896d4f14610132575b600080fd5b610114600480360381019061010f919061111f565b61031e565b005b610130600480360381019061012b919061109e565b610386565b005b61014c6004803603810190610147919061109e565b6104d3565b604051610159919061161c565b60405180910390f35b61017c6004803603810190610177919061105d565b610578565b6040516101899190611740565b60405180910390f35b6101ac60048036038101906101a7919061109e565b6105a6565b6040516101b9919061161c565b60405180910390f35b6101ca610646565b005b6101e660048036038101906101e1919061109e565b61065a565b6040516101f391906115e6565b60405180910390f35b6102166004803603810190610211919061109e565b610698565b604051610223919061171e565b60405180910390f35b61024660048036038101906102419190611018565b610816565b6040516102539190611740565b60405180910390f35b610264610841565b60405161027191906115e6565b60405180910390f35b61028261086b565b60405161028f9190611740565b60405180910390f35b6102b260048036038101906102ad9190611018565b610871565b6040516102bf9190611740565b60405180910390f35b6102d0610981565b6040516102dd9190611740565b60405180910390f35b61030060048036038101906102fb91906110c7565b610987565b005b61031c60048036038101906103179190610fef565b610b78565b005b610326610bfc565b8060696000848152602001908152602001600020818161034691906125c9565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada828260405161037a92919061178d565b60405180910390a15050565b60008060019054906101000a900460ff161590508080156103b75750600160008054906101000a900460ff1660ff16105b806103e457506103c630610c7a565b1580156103e35750600160008054906101000a900460ff1660ff16145b5b610423576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041a9061169e565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015610460576001600060016101000a81548160ff0219169083151502179055505b610468610c9d565b816065819055508160668190555080156104cf5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516104c69190611601565b60405180910390a15b5050565b60606067600083815260200190815260200160002080546104f390611fa8565b80601f016020809104026020016040519081016040528092919081815260200182805461051f90611fa8565b801561056c5780601f106105415761010080835404028352916020019161056c565b820191906000526020600020905b81548152906001019060200180831161054f57829003601f168201915b50505050509050919050565b6068818051602081018201805184825260208301602085012081835280955050505050506000915090505481565b606760205280600052604060002060009150905080546105c590611fa8565b80601f01602080910402602001604051908101604052809291908181526020018280546105f190611fa8565b801561063e5780601f106106135761010080835404028352916020019161063e565b820191906000526020600020905b81548152906001019060200180831161062157829003601f168201915b505050505081565b61064e610bfc565b6106586000610cf6565b565b60696020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b6106a0610e25565b606960008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b82821015610807578382906000526020600020906002020160405180604001604052908160008201805461076c90611fa8565b80601f016020809104026020016040519081016040528092919081815260200182805461079890611fa8565b80156107e55780601f106107ba576101008083540402835291602001916107e5565b820191906000526020600020905b8154815290600101906020018083116107c857829003601f168201915b5050505050815260200160018201548152505081526020019060010190610739565b50505050815250509050919050565b60006068838360405161082a9291906115cd565b908152602001604051809103902054905092915050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60665481565b600080606884846040516108869291906115cd565b908152602001604051809103902054146108d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108cc9061167e565b60405180910390fd5b6000606654905083836067600084815260200190815260200160002091906108fe929190610e55565b5080606885856040516109129291906115cd565b9081526020016040518091039020819055507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d8185856040516109579392919061175b565b60405180910390a16066600081548092919061097290612027565b91905055508091505092915050565b60655481565b60006067600085815260200190815260200160002080546109a790611fa8565b9050146109e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e09061163e565b60405180910390fd5b6000606883836040516109fd9291906115cd565b90815260200160405180910390205414610a4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a439061167e565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166069600085815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610af0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae7906116fe565b60405180910390fd5b8181606760008681526020019081526020016000209190610b12929190610e55565b508260688383604051610b269291906115cd565b9081526020016040518091039020819055507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c838383604051610b6b9392919061175b565b60405180910390a1505050565b610b80610bfc565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610bf0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610be79061165e565b60405180910390fd5b610bf981610cf6565b50565b610c04610dbc565b73ffffffffffffffffffffffffffffffffffffffff16610c22610841565b73ffffffffffffffffffffffffffffffffffffffff1614610c78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6f906116be565b60405180910390fd5b565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610cec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce3906116de565b60405180910390fd5b610cf4610dc4565b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600060019054906101000a900460ff16610e13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0a906116de565b60405180910390fd5b610e23610e1e610dbc565b610cf6565b565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b828054610e6190611fa8565b90600052602060002090601f016020900481019282610e835760008555610eca565b82601f10610e9c57803560ff1916838001178555610eca565b82800160010185558215610eca579182015b82811115610ec9578235825591602001919060010190610eae565b5b509050610ed79190610edb565b5090565b5b80821115610ef4576000816000905550600101610edc565b5090565b6000610f0b610f06846118b4565b61188f565b905082815260208101848484011115610f2357600080fd5b610f2e848285611eda565b509392505050565b600081359050610f458161263d565b92915050565b60008083601f840112610f5d57600080fd5b8235905067ffffffffffffffff811115610f7657600080fd5b602083019150836001820283011115610f8e57600080fd5b9250929050565b600082601f830112610fa657600080fd5b8135610fb6848260208601610ef8565b91505092915050565b600060408284031215610fd157600080fd5b81905092915050565b600081359050610fe981612654565b92915050565b60006020828403121561100157600080fd5b600061100f84828501610f36565b91505092915050565b6000806020838503121561102b57600080fd5b600083013567ffffffffffffffff81111561104557600080fd5b61105185828601610f4b565b92509250509250929050565b60006020828403121561106f57600080fd5b600082013567ffffffffffffffff81111561108957600080fd5b61109584828501610f95565b91505092915050565b6000602082840312156110b057600080fd5b60006110be84828501610fda565b91505092915050565b6000806000604084860312156110dc57600080fd5b60006110ea86828701610fda565b935050602084013567ffffffffffffffff81111561110757600080fd5b61111386828701610f4b565b92509250509250925092565b6000806040838503121561113257600080fd5b600061114085828601610fda565b925050602083013567ffffffffffffffff81111561115d57600080fd5b61116985828601610fbf565b9150509250929050565b600061117f8383611523565b905092915050565b60006111938383611572565b905092915050565b6111a481611c2e565b82525050565b6111b381611c2e565b82525050565b60006111c58385611991565b9350836020840285016111d7846118fc565b8060005b8781101561121b5784840389526111f28284611b99565b6111fc8582611173565b945061120783611977565b925060208a019950506001810190506111db565b50829750879450505050509392505050565b60006112388261194b565b6112428185611991565b93508360208202850161125485611906565b8060005b8581101561129057848403895281516112718582611187565b945061127c83611984565b925060208a01995050600181019050611258565b50829750879550505050505092915050565b6112ab81611d1d565b82525050565b60006112bd83856119a2565b93506112ca838584611eda565b6112d38361227e565b840190509392505050565b60006112ea83856119b3565b93506112f7838584611eda565b6113008361227e565b840190509392505050565b600061131783856119c4565b9350611324838584611eda565b82840190509392505050565b600061133b8261196c565b61134581856119a2565b9350611355818560208601611ee9565b61135e8161227e565b840191505092915050565b60006113748261196c565b61137e81856119b3565b935061138e818560208601611ee9565b6113978161227e565b840191505092915050565b60006113af6015836119b3565b91506113ba8261230a565b602082019050919050565b60006113d26026836119b3565b91506113dd82612333565b604082019050919050565b60006113f56019836119b3565b915061140082612382565b602082019050919050565b6000611418602e836119b3565b9150611423826123ab565b604082019050919050565b600061143b6020836119b3565b9150611446826123fa565b602082019050919050565b600061145e602b836119b3565b915061146982612423565b604082019050919050565b60006114816019836119b3565b915061148c82612472565b602082019050919050565b6000604083016114aa6000840184611ad4565b6114b7600086018261119b565b506114c56020840184611aeb565b85830360208701526114d88382846111b9565b925050508091505092915050565b60006040830160008301516114fe600086018261119b565b5060208301518482036020860152611516828261122d565b9150508091505092915050565b6000604083016115366000840184611b42565b85830360008701526115498382846112b1565b9250505061155a6020840184611bbd565b61156760208601826115af565b508091505092915050565b6000604083016000830151848203600086015261158f8282611330565b91505060208301516115a460208601826115af565b508091505092915050565b6115b881611c60565b82525050565b6115c781611c60565b82525050565b60006115da82848661130b565b91508190509392505050565b60006020820190506115fb60008301846111aa565b92915050565b600060208201905061161660008301846112a2565b92915050565b600060208201905081810360008301526116368184611369565b905092915050565b60006020820190508181036000830152611657816113a2565b9050919050565b60006020820190508181036000830152611677816113c5565b9050919050565b60006020820190508181036000830152611697816113e8565b9050919050565b600060208201905081810360008301526116b78161140b565b9050919050565b600060208201905081810360008301526116d78161142e565b9050919050565b600060208201905081810360008301526116f781611451565b9050919050565b6000602082019050818103600083015261171781611474565b9050919050565b6000602082019050818103600083015261173881846114e6565b905092915050565b600060208201905061175560008301846115be565b92915050565b600060408201905061177060008301866115be565b81810360208301526117838184866112de565b9050949350505050565b60006040820190506117a260008301856115be565b81810360208301526117b48184611497565b90509392505050565b600080833560016020038436030381126117d657600080fd5b80840192508235915067ffffffffffffffff8211156117f457600080fd5b60208301925060208202360383131561180c57600080fd5b509250929050565b6000808335600160200384360303811261182d57600080fd5b80840192508235915067ffffffffffffffff82111561184b57600080fd5b60208301925060018202360383131561186357600080fd5b509250929050565b60008235600160400383360303811261188357600080fd5b80830191505092915050565b60006118996118aa565b90506118a58282611ff6565b919050565b6000604051905090565b600067ffffffffffffffff8211156118cf576118ce61211b565b5b6118d88261227e565b9050602081019050919050565b60008190506118f5826002611bd4565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6020841060008114611a2857601f8411600181146119f8576119f18685611fda565b8355611a22565b611a018361192b565b611a166020601f880104820160018301611c85565b611a20878561249b565b505b50611a71565b611a318261192b565b6020601f8701048101601f87168015611a5257611a51816001840361214a565b5b611a646020601f890104840183611c85565b6001886002021785555050505b5050505050565b6020831060008114611ac3576020851060008114611aa157611a9a8685611fda565b8355611abd565b8360ff1916935083611ab28461192b565b556001866002020183555b50611acd565b6001856002020182555b5050505050565b6000611ae36020840184610f36565b905092915050565b60008083356001602003843603038112611b0457600080fd5b83810192508235915060208301925067ffffffffffffffff821115611b2857600080fd5b602082023603841315611b3a57600080fd5b509250929050565b60008083356001602003843603038112611b5b57600080fd5b83810192508235915060208301925067ffffffffffffffff821115611b7f57600080fd5b600182023603841315611b9157600080fd5b509250929050565b600082356001604003833603038112611bb157600080fd5b82810191505092915050565b6000611bcc6020840184610fda565b905092915050565b6000611bdf82611c60565b9150611bea83611c60565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611c2357611c226120bd565b5b828202905092915050565b6000611c3982611c40565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b611c82600082612229565b50565b5b81811015611ca457611c996000826122f2565b600181019050611c86565b5050565b5b81811015611cc757611cbc6000826122d4565b600281019050611ca9565b5050565b81811015611ce957611cde6000826122f2565b600181019050611ccb565b5050565b611cfa60008083016122b6565b611d086000600183016122f2565b50565b6000611d1682611d2f565b9050919050565b6000611d2882611c6a565b9050919050565b6000611d3a82611d41565b9050919050565b6000611d4c82611c40565b9050919050565b6000611d5e82611c60565b9050919050565b611d6f8383611940565b611d7981836121c5565b611d82836118fc565b611d8b83611916565b6000805b84811015611dc457611da1848861186b565b611dac8184866125fa565b60208501945060028401935050600181019050611d8f565b5050505050505050565b611dd88383611961565b67ffffffffffffffff811115611df157611df061211b565b5b611dfb8254611fa8565b600080601f8411601f84111715611e1857611e158561192b565b90505b601f831115611e4b576020601f85010481016020851015611e37578190505b611e496020601f860104830182611c85565b505b601f841160018114611e785760008515611e66578388013590505b611e708682611fda565b875550611ed0565b601f1985168260005b82811015611ea657858a01358255600182019150602086019550602081019050611e81565b87831015611ec357858a0135611ebf601f8a1682612070565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b83811015611f07578082015181840152602081019050611eec565b83811115611f16576000848401525b50505050565b600081016000830180611f2e81612199565b9050611f3a8184612586565b5050506001810160208301611f4f81856117bd565b611f5a8183866125a9565b505050505050565b6000810160008301611f748185611814565b611f7f8183866125b9565b50505050600181016020830180611f95816121af565b9050611fa181846125d7565b5050505050565b60006002820490506001821680611fc057607f821691505b60208210811415611fd457611fd36120ec565b5b50919050565b6000611fe68383612070565b9150826002028217905092915050565b611fff8261227e565b810181811067ffffffffffffffff8211171561201e5761201d61211b565b5b80604052505050565b600061203282611c60565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612065576120646120bd565b5b600182019050919050565b6000612081600019846008026122a9565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61217a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff836020036008026122a9565b815481168255505050565b6000819050919050565b6000819050919050565b600081356121a68161263d565b80915050919050565b600081356121bc81612654565b80915050919050565b680100000000000000008211156121df576121de61211b565b5b6121e881611956565b82825580831015612224576121fc816118e5565b612205846118e5565b61220e84611916565b81810183820161221e8183611ca8565b50505050505b505050565b680100000000000000008211156122435761224261211b565b5b805461224e81611fa8565b808411156122635761226284828486611a78565b5b8084101561227857612277848284866119cf565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b600082146122c7576122c661208e565b5b6122d081611c77565b5050565b600082146122e5576122e461208e565b5b6122ee81611ced565b5050565b6122fa61266b565b612305818484612618565b505050565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f73747265616d20616c7265616479206861732061206450494400000000000000600082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b6124a48161192b565b6124af838254611fda565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff6124dc8461228f565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61251e8461228f565b9350801983169250808416831791505092915050565b6000600883026125647fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261229c565b61256e868361229c565b95508019841693508086168417925050509392505050565b61258f82611d0b565b6125a261259b82612185565b83546124bc565b8255505050565b6125b4838383611d65565b505050565b6125c4838383611dce565b505050565b6125d38282611f1c565b5050565b6125e082611d53565b6125f36125ec8261218f565b83546124f2565b8255505050565b81156126095761260861208e565b5b6126138382611f62565b505050565b61262183611d53565b61263561262d8261218f565b848454612534565b825550505050565b61264681611c2e565b811461265157600080fd5b50565b61265d81611c60565b811461266857600080fd5b50565b60009056fea2646970667358221220cb403f7adc2fb139c3c9359219d93f9c0d9a168b2bc26c7936cfd7429f94f50064736f6c63430008040033"; type DpidAliasRegistryConstructorParams = | [signer?: Signer] From 231ac58c2daf308932965a6008d4691f00bf20b1 Mon Sep 17 00:00:00 2001 From: m0ar Date: Thu, 30 May 2024 11:59:04 +0200 Subject: [PATCH 120/278] contracts: improve migration/sync scripts, add mig freeze method --- .../DpidAliasRegistry.json | 50 +++++--- .../contracts/DpidAliasRegistry.sol | 112 ++++++++++++++---- desci-contracts/package.json | 2 +- .../scripts/deployDpidAliasRegistry.js | 8 +- .../scripts/migrateToAliasRegistry.mjs | 100 +++++++++++++--- .../scripts/syncAliasRegistryMigration.mjs | 97 +++++++++++++++ desci-contracts/test/DpidAliasRegistry.ts | 23 ++-- .../typechain-types/DpidAliasRegistry.ts | 109 +++++++++++------ .../factories/DpidAliasRegistry__factory.ts | 48 +++++--- 9 files changed, 431 insertions(+), 118 deletions(-) create mode 100644 desci-contracts/scripts/syncAliasRegistryMigration.mjs diff --git a/desci-contracts/artifacts/contracts/DpidAliasRegistry.sol/DpidAliasRegistry.json b/desci-contracts/artifacts/contracts/DpidAliasRegistry.sol/DpidAliasRegistry.json index da4e58c7..9aed9232 100644 --- a/desci-contracts/artifacts/contracts/DpidAliasRegistry.sol/DpidAliasRegistry.json +++ b/desci-contracts/artifacts/contracts/DpidAliasRegistry.sol/DpidAliasRegistry.json @@ -121,19 +121,6 @@ "name": "UpgradedDpid", "type": "event" }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_firstDpid", - "type": "uint256" - } - ], - "name": "__DpidAliasRegistry_init", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [ { @@ -166,6 +153,13 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "freezeMigration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -208,6 +202,19 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_firstDpid", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -270,6 +277,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "migrationFrozen", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -411,8 +431,8 @@ "type": "function" } ], - "bytecode": "0x60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d3565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000127565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff161015620000ed5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e4919062000149565b60405180910390a15b565b6000620000fe60278362000166565b91506200010b8262000184565b604082019050919050565b620001218162000177565b82525050565b600060208201905081810360008301526200014281620000ef565b9050919050565b600060208201905062000160600083018462000116565b92915050565b600082825260208201905092915050565b600060ff82169050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b6126a680620001e36000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c8063810a9afa11610097578063b724de3a11610066578063b724de3a14610298578063cfb452b5146102c8578063ded8896b146102e6578063f2fde38b14610302576100f5565b8063810a9afa146101fc57806382b7b5001461022c5780638da5cb5b1461025c578063afc269111461027a576100f5565b8063587a8cbf116100d3578063587a8cbf146101625780635893253c14610192578063715018a6146101c2578063788243d5146101cc576100f5565b8063144ae855146100fa578063362b3e63146101165780634f896d4f14610132575b600080fd5b610114600480360381019061010f919061111f565b61031e565b005b610130600480360381019061012b919061109e565b610386565b005b61014c6004803603810190610147919061109e565b6104d3565b604051610159919061161c565b60405180910390f35b61017c6004803603810190610177919061105d565b610578565b6040516101899190611740565b60405180910390f35b6101ac60048036038101906101a7919061109e565b6105a6565b6040516101b9919061161c565b60405180910390f35b6101ca610646565b005b6101e660048036038101906101e1919061109e565b61065a565b6040516101f391906115e6565b60405180910390f35b6102166004803603810190610211919061109e565b610698565b604051610223919061171e565b60405180910390f35b61024660048036038101906102419190611018565b610816565b6040516102539190611740565b60405180910390f35b610264610841565b60405161027191906115e6565b60405180910390f35b61028261086b565b60405161028f9190611740565b60405180910390f35b6102b260048036038101906102ad9190611018565b610871565b6040516102bf9190611740565b60405180910390f35b6102d0610981565b6040516102dd9190611740565b60405180910390f35b61030060048036038101906102fb91906110c7565b610987565b005b61031c60048036038101906103179190610fef565b610b78565b005b610326610bfc565b8060696000848152602001908152602001600020818161034691906125c9565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada828260405161037a92919061178d565b60405180910390a15050565b60008060019054906101000a900460ff161590508080156103b75750600160008054906101000a900460ff1660ff16105b806103e457506103c630610c7a565b1580156103e35750600160008054906101000a900460ff1660ff16145b5b610423576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041a9061169e565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015610460576001600060016101000a81548160ff0219169083151502179055505b610468610c9d565b816065819055508160668190555080156104cf5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516104c69190611601565b60405180910390a15b5050565b60606067600083815260200190815260200160002080546104f390611fa8565b80601f016020809104026020016040519081016040528092919081815260200182805461051f90611fa8565b801561056c5780601f106105415761010080835404028352916020019161056c565b820191906000526020600020905b81548152906001019060200180831161054f57829003601f168201915b50505050509050919050565b6068818051602081018201805184825260208301602085012081835280955050505050506000915090505481565b606760205280600052604060002060009150905080546105c590611fa8565b80601f01602080910402602001604051908101604052809291908181526020018280546105f190611fa8565b801561063e5780601f106106135761010080835404028352916020019161063e565b820191906000526020600020905b81548152906001019060200180831161062157829003601f168201915b505050505081565b61064e610bfc565b6106586000610cf6565b565b60696020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b6106a0610e25565b606960008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b82821015610807578382906000526020600020906002020160405180604001604052908160008201805461076c90611fa8565b80601f016020809104026020016040519081016040528092919081815260200182805461079890611fa8565b80156107e55780601f106107ba576101008083540402835291602001916107e5565b820191906000526020600020905b8154815290600101906020018083116107c857829003601f168201915b5050505050815260200160018201548152505081526020019060010190610739565b50505050815250509050919050565b60006068838360405161082a9291906115cd565b908152602001604051809103902054905092915050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60665481565b600080606884846040516108869291906115cd565b908152602001604051809103902054146108d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108cc9061167e565b60405180910390fd5b6000606654905083836067600084815260200190815260200160002091906108fe929190610e55565b5080606885856040516109129291906115cd565b9081526020016040518091039020819055507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d8185856040516109579392919061175b565b60405180910390a16066600081548092919061097290612027565b91905055508091505092915050565b60655481565b60006067600085815260200190815260200160002080546109a790611fa8565b9050146109e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e09061163e565b60405180910390fd5b6000606883836040516109fd9291906115cd565b90815260200160405180910390205414610a4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a439061167e565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166069600085815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610af0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae7906116fe565b60405180910390fd5b8181606760008681526020019081526020016000209190610b12929190610e55565b508260688383604051610b269291906115cd565b9081526020016040518091039020819055507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c838383604051610b6b9392919061175b565b60405180910390a1505050565b610b80610bfc565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610bf0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610be79061165e565b60405180910390fd5b610bf981610cf6565b50565b610c04610dbc565b73ffffffffffffffffffffffffffffffffffffffff16610c22610841565b73ffffffffffffffffffffffffffffffffffffffff1614610c78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6f906116be565b60405180910390fd5b565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610cec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce3906116de565b60405180910390fd5b610cf4610dc4565b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600060019054906101000a900460ff16610e13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0a906116de565b60405180910390fd5b610e23610e1e610dbc565b610cf6565b565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b828054610e6190611fa8565b90600052602060002090601f016020900481019282610e835760008555610eca565b82601f10610e9c57803560ff1916838001178555610eca565b82800160010185558215610eca579182015b82811115610ec9578235825591602001919060010190610eae565b5b509050610ed79190610edb565b5090565b5b80821115610ef4576000816000905550600101610edc565b5090565b6000610f0b610f06846118b4565b61188f565b905082815260208101848484011115610f2357600080fd5b610f2e848285611eda565b509392505050565b600081359050610f458161263d565b92915050565b60008083601f840112610f5d57600080fd5b8235905067ffffffffffffffff811115610f7657600080fd5b602083019150836001820283011115610f8e57600080fd5b9250929050565b600082601f830112610fa657600080fd5b8135610fb6848260208601610ef8565b91505092915050565b600060408284031215610fd157600080fd5b81905092915050565b600081359050610fe981612654565b92915050565b60006020828403121561100157600080fd5b600061100f84828501610f36565b91505092915050565b6000806020838503121561102b57600080fd5b600083013567ffffffffffffffff81111561104557600080fd5b61105185828601610f4b565b92509250509250929050565b60006020828403121561106f57600080fd5b600082013567ffffffffffffffff81111561108957600080fd5b61109584828501610f95565b91505092915050565b6000602082840312156110b057600080fd5b60006110be84828501610fda565b91505092915050565b6000806000604084860312156110dc57600080fd5b60006110ea86828701610fda565b935050602084013567ffffffffffffffff81111561110757600080fd5b61111386828701610f4b565b92509250509250925092565b6000806040838503121561113257600080fd5b600061114085828601610fda565b925050602083013567ffffffffffffffff81111561115d57600080fd5b61116985828601610fbf565b9150509250929050565b600061117f8383611523565b905092915050565b60006111938383611572565b905092915050565b6111a481611c2e565b82525050565b6111b381611c2e565b82525050565b60006111c58385611991565b9350836020840285016111d7846118fc565b8060005b8781101561121b5784840389526111f28284611b99565b6111fc8582611173565b945061120783611977565b925060208a019950506001810190506111db565b50829750879450505050509392505050565b60006112388261194b565b6112428185611991565b93508360208202850161125485611906565b8060005b8581101561129057848403895281516112718582611187565b945061127c83611984565b925060208a01995050600181019050611258565b50829750879550505050505092915050565b6112ab81611d1d565b82525050565b60006112bd83856119a2565b93506112ca838584611eda565b6112d38361227e565b840190509392505050565b60006112ea83856119b3565b93506112f7838584611eda565b6113008361227e565b840190509392505050565b600061131783856119c4565b9350611324838584611eda565b82840190509392505050565b600061133b8261196c565b61134581856119a2565b9350611355818560208601611ee9565b61135e8161227e565b840191505092915050565b60006113748261196c565b61137e81856119b3565b935061138e818560208601611ee9565b6113978161227e565b840191505092915050565b60006113af6015836119b3565b91506113ba8261230a565b602082019050919050565b60006113d26026836119b3565b91506113dd82612333565b604082019050919050565b60006113f56019836119b3565b915061140082612382565b602082019050919050565b6000611418602e836119b3565b9150611423826123ab565b604082019050919050565b600061143b6020836119b3565b9150611446826123fa565b602082019050919050565b600061145e602b836119b3565b915061146982612423565b604082019050919050565b60006114816019836119b3565b915061148c82612472565b602082019050919050565b6000604083016114aa6000840184611ad4565b6114b7600086018261119b565b506114c56020840184611aeb565b85830360208701526114d88382846111b9565b925050508091505092915050565b60006040830160008301516114fe600086018261119b565b5060208301518482036020860152611516828261122d565b9150508091505092915050565b6000604083016115366000840184611b42565b85830360008701526115498382846112b1565b9250505061155a6020840184611bbd565b61156760208601826115af565b508091505092915050565b6000604083016000830151848203600086015261158f8282611330565b91505060208301516115a460208601826115af565b508091505092915050565b6115b881611c60565b82525050565b6115c781611c60565b82525050565b60006115da82848661130b565b91508190509392505050565b60006020820190506115fb60008301846111aa565b92915050565b600060208201905061161660008301846112a2565b92915050565b600060208201905081810360008301526116368184611369565b905092915050565b60006020820190508181036000830152611657816113a2565b9050919050565b60006020820190508181036000830152611677816113c5565b9050919050565b60006020820190508181036000830152611697816113e8565b9050919050565b600060208201905081810360008301526116b78161140b565b9050919050565b600060208201905081810360008301526116d78161142e565b9050919050565b600060208201905081810360008301526116f781611451565b9050919050565b6000602082019050818103600083015261171781611474565b9050919050565b6000602082019050818103600083015261173881846114e6565b905092915050565b600060208201905061175560008301846115be565b92915050565b600060408201905061177060008301866115be565b81810360208301526117838184866112de565b9050949350505050565b60006040820190506117a260008301856115be565b81810360208301526117b48184611497565b90509392505050565b600080833560016020038436030381126117d657600080fd5b80840192508235915067ffffffffffffffff8211156117f457600080fd5b60208301925060208202360383131561180c57600080fd5b509250929050565b6000808335600160200384360303811261182d57600080fd5b80840192508235915067ffffffffffffffff82111561184b57600080fd5b60208301925060018202360383131561186357600080fd5b509250929050565b60008235600160400383360303811261188357600080fd5b80830191505092915050565b60006118996118aa565b90506118a58282611ff6565b919050565b6000604051905090565b600067ffffffffffffffff8211156118cf576118ce61211b565b5b6118d88261227e565b9050602081019050919050565b60008190506118f5826002611bd4565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6020841060008114611a2857601f8411600181146119f8576119f18685611fda565b8355611a22565b611a018361192b565b611a166020601f880104820160018301611c85565b611a20878561249b565b505b50611a71565b611a318261192b565b6020601f8701048101601f87168015611a5257611a51816001840361214a565b5b611a646020601f890104840183611c85565b6001886002021785555050505b5050505050565b6020831060008114611ac3576020851060008114611aa157611a9a8685611fda565b8355611abd565b8360ff1916935083611ab28461192b565b556001866002020183555b50611acd565b6001856002020182555b5050505050565b6000611ae36020840184610f36565b905092915050565b60008083356001602003843603038112611b0457600080fd5b83810192508235915060208301925067ffffffffffffffff821115611b2857600080fd5b602082023603841315611b3a57600080fd5b509250929050565b60008083356001602003843603038112611b5b57600080fd5b83810192508235915060208301925067ffffffffffffffff821115611b7f57600080fd5b600182023603841315611b9157600080fd5b509250929050565b600082356001604003833603038112611bb157600080fd5b82810191505092915050565b6000611bcc6020840184610fda565b905092915050565b6000611bdf82611c60565b9150611bea83611c60565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611c2357611c226120bd565b5b828202905092915050565b6000611c3982611c40565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b611c82600082612229565b50565b5b81811015611ca457611c996000826122f2565b600181019050611c86565b5050565b5b81811015611cc757611cbc6000826122d4565b600281019050611ca9565b5050565b81811015611ce957611cde6000826122f2565b600181019050611ccb565b5050565b611cfa60008083016122b6565b611d086000600183016122f2565b50565b6000611d1682611d2f565b9050919050565b6000611d2882611c6a565b9050919050565b6000611d3a82611d41565b9050919050565b6000611d4c82611c40565b9050919050565b6000611d5e82611c60565b9050919050565b611d6f8383611940565b611d7981836121c5565b611d82836118fc565b611d8b83611916565b6000805b84811015611dc457611da1848861186b565b611dac8184866125fa565b60208501945060028401935050600181019050611d8f565b5050505050505050565b611dd88383611961565b67ffffffffffffffff811115611df157611df061211b565b5b611dfb8254611fa8565b600080601f8411601f84111715611e1857611e158561192b565b90505b601f831115611e4b576020601f85010481016020851015611e37578190505b611e496020601f860104830182611c85565b505b601f841160018114611e785760008515611e66578388013590505b611e708682611fda565b875550611ed0565b601f1985168260005b82811015611ea657858a01358255600182019150602086019550602081019050611e81565b87831015611ec357858a0135611ebf601f8a1682612070565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b83811015611f07578082015181840152602081019050611eec565b83811115611f16576000848401525b50505050565b600081016000830180611f2e81612199565b9050611f3a8184612586565b5050506001810160208301611f4f81856117bd565b611f5a8183866125a9565b505050505050565b6000810160008301611f748185611814565b611f7f8183866125b9565b50505050600181016020830180611f95816121af565b9050611fa181846125d7565b5050505050565b60006002820490506001821680611fc057607f821691505b60208210811415611fd457611fd36120ec565b5b50919050565b6000611fe68383612070565b9150826002028217905092915050565b611fff8261227e565b810181811067ffffffffffffffff8211171561201e5761201d61211b565b5b80604052505050565b600061203282611c60565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612065576120646120bd565b5b600182019050919050565b6000612081600019846008026122a9565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61217a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff836020036008026122a9565b815481168255505050565b6000819050919050565b6000819050919050565b600081356121a68161263d565b80915050919050565b600081356121bc81612654565b80915050919050565b680100000000000000008211156121df576121de61211b565b5b6121e881611956565b82825580831015612224576121fc816118e5565b612205846118e5565b61220e84611916565b81810183820161221e8183611ca8565b50505050505b505050565b680100000000000000008211156122435761224261211b565b5b805461224e81611fa8565b808411156122635761226284828486611a78565b5b8084101561227857612277848284866119cf565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b600082146122c7576122c661208e565b5b6122d081611c77565b5050565b600082146122e5576122e461208e565b5b6122ee81611ced565b5050565b6122fa61266b565b612305818484612618565b505050565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f73747265616d20616c7265616479206861732061206450494400000000000000600082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b6124a48161192b565b6124af838254611fda565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff6124dc8461228f565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61251e8461228f565b9350801983169250808416831791505092915050565b6000600883026125647fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261229c565b61256e868361229c565b95508019841693508086168417925050509392505050565b61258f82611d0b565b6125a261259b82612185565b83546124bc565b8255505050565b6125b4838383611d65565b505050565b6125c4838383611dce565b505050565b6125d38282611f1c565b5050565b6125e082611d53565b6125f36125ec8261218f565b83546124f2565b8255505050565b81156126095761260861208e565b5b6126138382611f62565b505050565b61262183611d53565b61263561262d8261218f565b848454612534565b825550505050565b61264681611c2e565b811461265157600080fd5b50565b61265d81611c60565b811461266857600080fd5b50565b60009056fea2646970667358221220cb403f7adc2fb139c3c9359219d93f9c0d9a168b2bc26c7936cfd7429f94f50064736f6c63430008040033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100f55760003560e01c8063810a9afa11610097578063b724de3a11610066578063b724de3a14610298578063cfb452b5146102c8578063ded8896b146102e6578063f2fde38b14610302576100f5565b8063810a9afa146101fc57806382b7b5001461022c5780638da5cb5b1461025c578063afc269111461027a576100f5565b8063587a8cbf116100d3578063587a8cbf146101625780635893253c14610192578063715018a6146101c2578063788243d5146101cc576100f5565b8063144ae855146100fa578063362b3e63146101165780634f896d4f14610132575b600080fd5b610114600480360381019061010f919061111f565b61031e565b005b610130600480360381019061012b919061109e565b610386565b005b61014c6004803603810190610147919061109e565b6104d3565b604051610159919061161c565b60405180910390f35b61017c6004803603810190610177919061105d565b610578565b6040516101899190611740565b60405180910390f35b6101ac60048036038101906101a7919061109e565b6105a6565b6040516101b9919061161c565b60405180910390f35b6101ca610646565b005b6101e660048036038101906101e1919061109e565b61065a565b6040516101f391906115e6565b60405180910390f35b6102166004803603810190610211919061109e565b610698565b604051610223919061171e565b60405180910390f35b61024660048036038101906102419190611018565b610816565b6040516102539190611740565b60405180910390f35b610264610841565b60405161027191906115e6565b60405180910390f35b61028261086b565b60405161028f9190611740565b60405180910390f35b6102b260048036038101906102ad9190611018565b610871565b6040516102bf9190611740565b60405180910390f35b6102d0610981565b6040516102dd9190611740565b60405180910390f35b61030060048036038101906102fb91906110c7565b610987565b005b61031c60048036038101906103179190610fef565b610b78565b005b610326610bfc565b8060696000848152602001908152602001600020818161034691906125c9565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada828260405161037a92919061178d565b60405180910390a15050565b60008060019054906101000a900460ff161590508080156103b75750600160008054906101000a900460ff1660ff16105b806103e457506103c630610c7a565b1580156103e35750600160008054906101000a900460ff1660ff16145b5b610423576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041a9061169e565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015610460576001600060016101000a81548160ff0219169083151502179055505b610468610c9d565b816065819055508160668190555080156104cf5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516104c69190611601565b60405180910390a15b5050565b60606067600083815260200190815260200160002080546104f390611fa8565b80601f016020809104026020016040519081016040528092919081815260200182805461051f90611fa8565b801561056c5780601f106105415761010080835404028352916020019161056c565b820191906000526020600020905b81548152906001019060200180831161054f57829003601f168201915b50505050509050919050565b6068818051602081018201805184825260208301602085012081835280955050505050506000915090505481565b606760205280600052604060002060009150905080546105c590611fa8565b80601f01602080910402602001604051908101604052809291908181526020018280546105f190611fa8565b801561063e5780601f106106135761010080835404028352916020019161063e565b820191906000526020600020905b81548152906001019060200180831161062157829003601f168201915b505050505081565b61064e610bfc565b6106586000610cf6565b565b60696020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b6106a0610e25565b606960008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b82821015610807578382906000526020600020906002020160405180604001604052908160008201805461076c90611fa8565b80601f016020809104026020016040519081016040528092919081815260200182805461079890611fa8565b80156107e55780601f106107ba576101008083540402835291602001916107e5565b820191906000526020600020905b8154815290600101906020018083116107c857829003601f168201915b5050505050815260200160018201548152505081526020019060010190610739565b50505050815250509050919050565b60006068838360405161082a9291906115cd565b908152602001604051809103902054905092915050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60665481565b600080606884846040516108869291906115cd565b908152602001604051809103902054146108d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108cc9061167e565b60405180910390fd5b6000606654905083836067600084815260200190815260200160002091906108fe929190610e55565b5080606885856040516109129291906115cd565b9081526020016040518091039020819055507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d8185856040516109579392919061175b565b60405180910390a16066600081548092919061097290612027565b91905055508091505092915050565b60655481565b60006067600085815260200190815260200160002080546109a790611fa8565b9050146109e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e09061163e565b60405180910390fd5b6000606883836040516109fd9291906115cd565b90815260200160405180910390205414610a4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a439061167e565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166069600085815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610af0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae7906116fe565b60405180910390fd5b8181606760008681526020019081526020016000209190610b12929190610e55565b508260688383604051610b269291906115cd565b9081526020016040518091039020819055507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c838383604051610b6b9392919061175b565b60405180910390a1505050565b610b80610bfc565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610bf0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610be79061165e565b60405180910390fd5b610bf981610cf6565b50565b610c04610dbc565b73ffffffffffffffffffffffffffffffffffffffff16610c22610841565b73ffffffffffffffffffffffffffffffffffffffff1614610c78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6f906116be565b60405180910390fd5b565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610cec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce3906116de565b60405180910390fd5b610cf4610dc4565b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600060019054906101000a900460ff16610e13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0a906116de565b60405180910390fd5b610e23610e1e610dbc565b610cf6565b565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b828054610e6190611fa8565b90600052602060002090601f016020900481019282610e835760008555610eca565b82601f10610e9c57803560ff1916838001178555610eca565b82800160010185558215610eca579182015b82811115610ec9578235825591602001919060010190610eae565b5b509050610ed79190610edb565b5090565b5b80821115610ef4576000816000905550600101610edc565b5090565b6000610f0b610f06846118b4565b61188f565b905082815260208101848484011115610f2357600080fd5b610f2e848285611eda565b509392505050565b600081359050610f458161263d565b92915050565b60008083601f840112610f5d57600080fd5b8235905067ffffffffffffffff811115610f7657600080fd5b602083019150836001820283011115610f8e57600080fd5b9250929050565b600082601f830112610fa657600080fd5b8135610fb6848260208601610ef8565b91505092915050565b600060408284031215610fd157600080fd5b81905092915050565b600081359050610fe981612654565b92915050565b60006020828403121561100157600080fd5b600061100f84828501610f36565b91505092915050565b6000806020838503121561102b57600080fd5b600083013567ffffffffffffffff81111561104557600080fd5b61105185828601610f4b565b92509250509250929050565b60006020828403121561106f57600080fd5b600082013567ffffffffffffffff81111561108957600080fd5b61109584828501610f95565b91505092915050565b6000602082840312156110b057600080fd5b60006110be84828501610fda565b91505092915050565b6000806000604084860312156110dc57600080fd5b60006110ea86828701610fda565b935050602084013567ffffffffffffffff81111561110757600080fd5b61111386828701610f4b565b92509250509250925092565b6000806040838503121561113257600080fd5b600061114085828601610fda565b925050602083013567ffffffffffffffff81111561115d57600080fd5b61116985828601610fbf565b9150509250929050565b600061117f8383611523565b905092915050565b60006111938383611572565b905092915050565b6111a481611c2e565b82525050565b6111b381611c2e565b82525050565b60006111c58385611991565b9350836020840285016111d7846118fc565b8060005b8781101561121b5784840389526111f28284611b99565b6111fc8582611173565b945061120783611977565b925060208a019950506001810190506111db565b50829750879450505050509392505050565b60006112388261194b565b6112428185611991565b93508360208202850161125485611906565b8060005b8581101561129057848403895281516112718582611187565b945061127c83611984565b925060208a01995050600181019050611258565b50829750879550505050505092915050565b6112ab81611d1d565b82525050565b60006112bd83856119a2565b93506112ca838584611eda565b6112d38361227e565b840190509392505050565b60006112ea83856119b3565b93506112f7838584611eda565b6113008361227e565b840190509392505050565b600061131783856119c4565b9350611324838584611eda565b82840190509392505050565b600061133b8261196c565b61134581856119a2565b9350611355818560208601611ee9565b61135e8161227e565b840191505092915050565b60006113748261196c565b61137e81856119b3565b935061138e818560208601611ee9565b6113978161227e565b840191505092915050565b60006113af6015836119b3565b91506113ba8261230a565b602082019050919050565b60006113d26026836119b3565b91506113dd82612333565b604082019050919050565b60006113f56019836119b3565b915061140082612382565b602082019050919050565b6000611418602e836119b3565b9150611423826123ab565b604082019050919050565b600061143b6020836119b3565b9150611446826123fa565b602082019050919050565b600061145e602b836119b3565b915061146982612423565b604082019050919050565b60006114816019836119b3565b915061148c82612472565b602082019050919050565b6000604083016114aa6000840184611ad4565b6114b7600086018261119b565b506114c56020840184611aeb565b85830360208701526114d88382846111b9565b925050508091505092915050565b60006040830160008301516114fe600086018261119b565b5060208301518482036020860152611516828261122d565b9150508091505092915050565b6000604083016115366000840184611b42565b85830360008701526115498382846112b1565b9250505061155a6020840184611bbd565b61156760208601826115af565b508091505092915050565b6000604083016000830151848203600086015261158f8282611330565b91505060208301516115a460208601826115af565b508091505092915050565b6115b881611c60565b82525050565b6115c781611c60565b82525050565b60006115da82848661130b565b91508190509392505050565b60006020820190506115fb60008301846111aa565b92915050565b600060208201905061161660008301846112a2565b92915050565b600060208201905081810360008301526116368184611369565b905092915050565b60006020820190508181036000830152611657816113a2565b9050919050565b60006020820190508181036000830152611677816113c5565b9050919050565b60006020820190508181036000830152611697816113e8565b9050919050565b600060208201905081810360008301526116b78161140b565b9050919050565b600060208201905081810360008301526116d78161142e565b9050919050565b600060208201905081810360008301526116f781611451565b9050919050565b6000602082019050818103600083015261171781611474565b9050919050565b6000602082019050818103600083015261173881846114e6565b905092915050565b600060208201905061175560008301846115be565b92915050565b600060408201905061177060008301866115be565b81810360208301526117838184866112de565b9050949350505050565b60006040820190506117a260008301856115be565b81810360208301526117b48184611497565b90509392505050565b600080833560016020038436030381126117d657600080fd5b80840192508235915067ffffffffffffffff8211156117f457600080fd5b60208301925060208202360383131561180c57600080fd5b509250929050565b6000808335600160200384360303811261182d57600080fd5b80840192508235915067ffffffffffffffff82111561184b57600080fd5b60208301925060018202360383131561186357600080fd5b509250929050565b60008235600160400383360303811261188357600080fd5b80830191505092915050565b60006118996118aa565b90506118a58282611ff6565b919050565b6000604051905090565b600067ffffffffffffffff8211156118cf576118ce61211b565b5b6118d88261227e565b9050602081019050919050565b60008190506118f5826002611bd4565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6020841060008114611a2857601f8411600181146119f8576119f18685611fda565b8355611a22565b611a018361192b565b611a166020601f880104820160018301611c85565b611a20878561249b565b505b50611a71565b611a318261192b565b6020601f8701048101601f87168015611a5257611a51816001840361214a565b5b611a646020601f890104840183611c85565b6001886002021785555050505b5050505050565b6020831060008114611ac3576020851060008114611aa157611a9a8685611fda565b8355611abd565b8360ff1916935083611ab28461192b565b556001866002020183555b50611acd565b6001856002020182555b5050505050565b6000611ae36020840184610f36565b905092915050565b60008083356001602003843603038112611b0457600080fd5b83810192508235915060208301925067ffffffffffffffff821115611b2857600080fd5b602082023603841315611b3a57600080fd5b509250929050565b60008083356001602003843603038112611b5b57600080fd5b83810192508235915060208301925067ffffffffffffffff821115611b7f57600080fd5b600182023603841315611b9157600080fd5b509250929050565b600082356001604003833603038112611bb157600080fd5b82810191505092915050565b6000611bcc6020840184610fda565b905092915050565b6000611bdf82611c60565b9150611bea83611c60565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611c2357611c226120bd565b5b828202905092915050565b6000611c3982611c40565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b611c82600082612229565b50565b5b81811015611ca457611c996000826122f2565b600181019050611c86565b5050565b5b81811015611cc757611cbc6000826122d4565b600281019050611ca9565b5050565b81811015611ce957611cde6000826122f2565b600181019050611ccb565b5050565b611cfa60008083016122b6565b611d086000600183016122f2565b50565b6000611d1682611d2f565b9050919050565b6000611d2882611c6a565b9050919050565b6000611d3a82611d41565b9050919050565b6000611d4c82611c40565b9050919050565b6000611d5e82611c60565b9050919050565b611d6f8383611940565b611d7981836121c5565b611d82836118fc565b611d8b83611916565b6000805b84811015611dc457611da1848861186b565b611dac8184866125fa565b60208501945060028401935050600181019050611d8f565b5050505050505050565b611dd88383611961565b67ffffffffffffffff811115611df157611df061211b565b5b611dfb8254611fa8565b600080601f8411601f84111715611e1857611e158561192b565b90505b601f831115611e4b576020601f85010481016020851015611e37578190505b611e496020601f860104830182611c85565b505b601f841160018114611e785760008515611e66578388013590505b611e708682611fda565b875550611ed0565b601f1985168260005b82811015611ea657858a01358255600182019150602086019550602081019050611e81565b87831015611ec357858a0135611ebf601f8a1682612070565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b83811015611f07578082015181840152602081019050611eec565b83811115611f16576000848401525b50505050565b600081016000830180611f2e81612199565b9050611f3a8184612586565b5050506001810160208301611f4f81856117bd565b611f5a8183866125a9565b505050505050565b6000810160008301611f748185611814565b611f7f8183866125b9565b50505050600181016020830180611f95816121af565b9050611fa181846125d7565b5050505050565b60006002820490506001821680611fc057607f821691505b60208210811415611fd457611fd36120ec565b5b50919050565b6000611fe68383612070565b9150826002028217905092915050565b611fff8261227e565b810181811067ffffffffffffffff8211171561201e5761201d61211b565b5b80604052505050565b600061203282611c60565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612065576120646120bd565b5b600182019050919050565b6000612081600019846008026122a9565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61217a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff836020036008026122a9565b815481168255505050565b6000819050919050565b6000819050919050565b600081356121a68161263d565b80915050919050565b600081356121bc81612654565b80915050919050565b680100000000000000008211156121df576121de61211b565b5b6121e881611956565b82825580831015612224576121fc816118e5565b612205846118e5565b61220e84611916565b81810183820161221e8183611ca8565b50505050505b505050565b680100000000000000008211156122435761224261211b565b5b805461224e81611fa8565b808411156122635761226284828486611a78565b5b8084101561227857612277848284866119cf565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b600082146122c7576122c661208e565b5b6122d081611c77565b5050565b600082146122e5576122e461208e565b5b6122ee81611ced565b5050565b6122fa61266b565b612305818484612618565b505050565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f73747265616d20616c7265616479206861732061206450494400000000000000600082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b6124a48161192b565b6124af838254611fda565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff6124dc8461228f565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61251e8461228f565b9350801983169250808416831791505092915050565b6000600883026125647fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261229c565b61256e868361229c565b95508019841693508086168417925050509392505050565b61258f82611d0b565b6125a261259b82612185565b83546124bc565b8255505050565b6125b4838383611d65565b505050565b6125c4838383611dce565b505050565b6125d38282611f1c565b5050565b6125e082611d53565b6125f36125ec8261218f565b83546124f2565b8255505050565b81156126095761260861208e565b5b6126138382611f62565b505050565b61262183611d53565b61263561262d8261218f565b848454612534565b825550505050565b61264681611c2e565b811461265157600080fd5b50565b61265d81611c60565b811461266857600080fd5b50565b60009056fea2646970667358221220cb403f7adc2fb139c3c9359219d93f9c0d9a168b2bc26c7936cfd7429f94f50064736f6c63430008040033", + "bytecode": "0x60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d3565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000127565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff161015620000ed5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e4919062000149565b60405180910390a15b565b6000620000fe60278362000166565b91506200010b8262000184565b604082019050919050565b620001218162000177565b82525050565b600060208201905081810360008301526200014281620000ef565b9050919050565b600060208201905062000160600083018462000116565b92915050565b600082825260208201905092915050565b600060ff82169050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b61281d80620001e36000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806382b7b500116100a2578063b9e2924111610071578063b9e29241146102cc578063cfb452b5146102ea578063ded8896b14610308578063f2fde38b14610324578063fe4b84df146103405761010b565b806382b7b500146102305780638da5cb5b14610260578063afc269111461027e578063b724de3a1461029c5761010b565b80635893253c116100de5780635893253c14610196578063715018a6146101c6578063788243d5146101d0578063810a9afa146102005761010b565b80630d70b3aa14610110578063144ae8551461011a5780634f896d4f14610136578063587a8cbf14610166575b600080fd5b61011861035c565b005b610134600480360381019061012f91906111f4565b610381565b005b610150600480360381019061014b9190611173565b61043f565b60405161015d919061173e565b60405180910390f35b610180600480360381019061017b9190611132565b6104e4565b60405161018d9190611882565b60405180910390f35b6101b060048036038101906101ab9190611173565b610512565b6040516101bd919061173e565b60405180910390f35b6101ce6105b2565b005b6101ea60048036038101906101e59190611173565b6105c6565b6040516101f791906116ed565b60405180910390f35b61021a60048036038101906102159190611173565b610604565b6040516102279190611860565b60405180910390f35b61024a600480360381019061024591906110ed565b610782565b6040516102579190611882565b60405180910390f35b6102686107ad565b60405161027591906116ed565b60405180910390f35b6102866107d7565b6040516102939190611882565b60405180910390f35b6102b660048036038101906102b191906110ed565b6107dd565b6040516102c39190611882565b60405180910390f35b6102d46108f2565b6040516102e19190611708565b60405180910390f35b6102f2610905565b6040516102ff9190611882565b60405180910390f35b610322600480360381019061031d919061119c565b61090b565b005b61033e600480360381019061033991906110c4565b610b00565b005b61035a60048036038101906103559190611173565b610b84565b005b610364610cd1565b6001606760006101000a81548160ff021916908315150217905550565b610389610cd1565b60001515606760009054906101000a900460ff161515146103df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103d6906117a0565b60405180910390fd5b80606a600084815260200190815260200160002081816103ff9190612740565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada82826040516104339291906118cf565b60405180910390a15050565b606060686000838152602001908152602001600020805461045f906120f6565b80601f016020809104026020016040519081016040528092919081815260200182805461048b906120f6565b80156104d85780601f106104ad576101008083540402835291602001916104d8565b820191906000526020600020905b8154815290600101906020018083116104bb57829003601f168201915b50505050509050919050565b6069818051602081018201805184825260208301602085012081835280955050505050506000915090505481565b60686020528060005260406000206000915090508054610531906120f6565b80601f016020809104026020016040519081016040528092919081815260200182805461055d906120f6565b80156105aa5780601f1061057f576101008083540402835291602001916105aa565b820191906000526020600020905b81548152906001019060200180831161058d57829003601f168201915b505050505081565b6105ba610cd1565b6105c46000610d4f565b565b606a6020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b61060c610efa565b606a60008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b8282101561077357838290600052602060002090600202016040518060400160405290816000820180546106d8906120f6565b80601f0160208091040260200160405190810160405280929190818152602001828054610704906120f6565b80156107515780601f1061072657610100808354040283529160200191610751565b820191906000526020600020905b81548152906001019060200180831161073457829003601f168201915b50505050508152602001600182015481525050815260200190600101906106a5565b50505050815250509050919050565b6000606983836040516107969291906116d4565b908152602001604051809103902054905092915050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60665481565b600082826000606983836040516107f59291906116d4565b90815260200160405180910390205414610844576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161083b906117c0565b60405180910390fd5b60006066549050858560686000848152602001908152602001600020919061086d929190610f2a565b5080606987876040516108819291906116d4565b9081526020016040518091039020819055507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d8187876040516108c69392919061189d565b60405180910390a1606660008154809291906108e190612175565b919050555080935050505092915050565b606760009054906101000a900460ff1681565b60655481565b81816000606983836040516109219291906116d4565b90815260200160405180910390205414610970576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610967906117c0565b60405180910390fd5b6000606860008781526020019081526020016000208054610990906120f6565b9050146109d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109c990611760565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16606a600087815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610a76576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6d90611840565b60405180910390fd5b8383606860008881526020019081526020016000209190610a98929190610f2a565b508460698585604051610aac9291906116d4565b9081526020016040518091039020819055507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c858585604051610af19392919061189d565b60405180910390a15050505050565b610b08610cd1565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610b78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b6f90611780565b60405180910390fd5b610b8181610d4f565b50565b60008060019054906101000a900460ff16159050808015610bb55750600160008054906101000a900460ff1660ff16105b80610be25750610bc430610e15565b158015610be15750600160008054906101000a900460ff1660ff16145b5b610c21576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c18906117e0565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015610c5e576001600060016101000a81548160ff0219169083151502179055505b610c66610e38565b81606581905550816066819055508015610ccd5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024986001604051610cc49190611723565b60405180910390a15b5050565b610cd9610e91565b73ffffffffffffffffffffffffffffffffffffffff16610cf76107ad565b73ffffffffffffffffffffffffffffffffffffffff1614610d4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d4490611800565b60405180910390fd5b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610e87576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e7e90611820565b60405180910390fd5b610e8f610e99565b565b600033905090565b600060019054906101000a900460ff16610ee8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610edf90611820565b60405180910390fd5b610ef8610ef3610e91565b610d4f565b565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b828054610f36906120f6565b90600052602060002090601f016020900481019282610f585760008555610f9f565b82601f10610f7157803560ff1916838001178555610f9f565b82800160010185558215610f9f579182015b82811115610f9e578235825591602001919060010190610f83565b5b509050610fac9190610fb0565b5090565b5b80821115610fc9576000816000905550600101610fb1565b5090565b6000610fe0610fdb846119f6565b6119d1565b905082815260208101848484011115610ff857600080fd5b611003848285612028565b509392505050565b60008135905061101a816127b4565b92915050565b60008083601f84011261103257600080fd5b8235905067ffffffffffffffff81111561104b57600080fd5b60208301915083600182028301111561106357600080fd5b9250929050565b600082601f83011261107b57600080fd5b813561108b848260208601610fcd565b91505092915050565b6000604082840312156110a657600080fd5b81905092915050565b6000813590506110be816127cb565b92915050565b6000602082840312156110d657600080fd5b60006110e48482850161100b565b91505092915050565b6000806020838503121561110057600080fd5b600083013567ffffffffffffffff81111561111a57600080fd5b61112685828601611020565b92509250509250929050565b60006020828403121561114457600080fd5b600082013567ffffffffffffffff81111561115e57600080fd5b61116a8482850161106a565b91505092915050565b60006020828403121561118557600080fd5b6000611193848285016110af565b91505092915050565b6000806000604084860312156111b157600080fd5b60006111bf868287016110af565b935050602084013567ffffffffffffffff8111156111dc57600080fd5b6111e886828701611020565b92509250509250925092565b6000806040838503121561120757600080fd5b6000611215858286016110af565b925050602083013567ffffffffffffffff81111561123257600080fd5b61123e85828601611094565b9150509250929050565b6000611254838361162a565b905092915050565b60006112688383611679565b905092915050565b61127981611d70565b82525050565b61128881611d70565b82525050565b600061129a8385611ad3565b9350836020840285016112ac84611a3e565b8060005b878110156112f05784840389526112c78284611cdb565b6112d18582611248565b94506112dc83611ab9565b925060208a019950506001810190506112b0565b50829750879450505050509392505050565b600061130d82611a8d565b6113178185611ad3565b93508360208202850161132985611a48565b8060005b858110156113655784840389528151611346858261125c565b945061135183611ac6565b925060208a0199505060018101905061132d565b50829750879550505050505092915050565b61138081611d82565b82525050565b61138f81611e6b565b82525050565b60006113a18385611ae4565b93506113ae838584612028565b6113b7836123cc565b840190509392505050565b60006113ce8385611af5565b93506113db838584612028565b6113e4836123cc565b840190509392505050565b60006113fb8385611b06565b9350611408838584612028565b82840190509392505050565b600061141f82611aae565b6114298185611ae4565b9350611439818560208601612037565b611442816123cc565b840191505092915050565b600061145882611aae565b6114628185611af5565b9350611472818560208601612037565b61147b816123cc565b840191505092915050565b6000611493601583611af5565b915061149e82612458565b602082019050919050565b60006114b6602683611af5565b91506114c182612481565b604082019050919050565b60006114d9601383611af5565b91506114e4826124d0565b602082019050919050565b60006114fc601983611af5565b9150611507826124f9565b602082019050919050565b600061151f602e83611af5565b915061152a82612522565b604082019050919050565b6000611542602083611af5565b915061154d82612571565b602082019050919050565b6000611565602b83611af5565b91506115708261259a565b604082019050919050565b6000611588601983611af5565b9150611593826125e9565b602082019050919050565b6000604083016115b16000840184611c16565b6115be6000860182611270565b506115cc6020840184611c2d565b85830360208701526115df83828461128e565b925050508091505092915050565b60006040830160008301516116056000860182611270565b506020830151848203602086015261161d8282611302565b9150508091505092915050565b60006040830161163d6000840184611c84565b8583036000870152611650838284611395565b925050506116616020840184611cff565b61166e60208601826116b6565b508091505092915050565b600060408301600083015184820360008601526116968282611414565b91505060208301516116ab60208601826116b6565b508091505092915050565b6116bf81611dae565b82525050565b6116ce81611dae565b82525050565b60006116e18284866113ef565b91508190509392505050565b6000602082019050611702600083018461127f565b92915050565b600060208201905061171d6000830184611377565b92915050565b60006020820190506117386000830184611386565b92915050565b60006020820190508181036000830152611758818461144d565b905092915050565b6000602082019050818103600083015261177981611486565b9050919050565b60006020820190508181036000830152611799816114a9565b9050919050565b600060208201905081810360008301526117b9816114cc565b9050919050565b600060208201905081810360008301526117d9816114ef565b9050919050565b600060208201905081810360008301526117f981611512565b9050919050565b6000602082019050818103600083015261181981611535565b9050919050565b6000602082019050818103600083015261183981611558565b9050919050565b600060208201905081810360008301526118598161157b565b9050919050565b6000602082019050818103600083015261187a81846115ed565b905092915050565b600060208201905061189760008301846116c5565b92915050565b60006040820190506118b260008301866116c5565b81810360208301526118c58184866113c2565b9050949350505050565b60006040820190506118e460008301856116c5565b81810360208301526118f6818461159e565b90509392505050565b6000808335600160200384360303811261191857600080fd5b80840192508235915067ffffffffffffffff82111561193657600080fd5b60208301925060208202360383131561194e57600080fd5b509250929050565b6000808335600160200384360303811261196f57600080fd5b80840192508235915067ffffffffffffffff82111561198d57600080fd5b6020830192506001820236038313156119a557600080fd5b509250929050565b6000823560016040038336030381126119c557600080fd5b80830191505092915050565b60006119db6119ec565b90506119e78282612144565b919050565b6000604051905090565b600067ffffffffffffffff821115611a1157611a10612269565b5b611a1a826123cc565b9050602081019050919050565b6000819050611a37826002611d16565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6020841060008114611b6a57601f841160018114611b3a57611b338685612128565b8355611b64565b611b4383611a6d565b611b586020601f880104820160018301611dd3565b611b628785612612565b505b50611bb3565b611b7382611a6d565b6020601f8701048101601f87168015611b9457611b938160018403612298565b5b611ba66020601f890104840183611dd3565b6001886002021785555050505b5050505050565b6020831060008114611c05576020851060008114611be357611bdc8685612128565b8355611bff565b8360ff1916935083611bf484611a6d565b556001866002020183555b50611c0f565b6001856002020182555b5050505050565b6000611c25602084018461100b565b905092915050565b60008083356001602003843603038112611c4657600080fd5b83810192508235915060208301925067ffffffffffffffff821115611c6a57600080fd5b602082023603841315611c7c57600080fd5b509250929050565b60008083356001602003843603038112611c9d57600080fd5b83810192508235915060208301925067ffffffffffffffff821115611cc157600080fd5b600182023603841315611cd357600080fd5b509250929050565b600082356001604003833603038112611cf357600080fd5b82810191505092915050565b6000611d0e60208401846110af565b905092915050565b6000611d2182611dae565b9150611d2c83611dae565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611d6557611d6461220b565b5b828202905092915050565b6000611d7b82611d8e565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b611dd0600082612377565b50565b5b81811015611df257611de7600082612440565b600181019050611dd4565b5050565b5b81811015611e1557611e0a600082612422565b600281019050611df7565b5050565b81811015611e3757611e2c600082612440565b600181019050611e19565b5050565b611e486000808301612404565b611e56600060018301612440565b50565b6000611e6482611e7d565b9050919050565b6000611e7682611db8565b9050919050565b6000611e8882611e8f565b9050919050565b6000611e9a82611d8e565b9050919050565b6000611eac82611dae565b9050919050565b611ebd8383611a82565b611ec78183612313565b611ed083611a3e565b611ed983611a58565b6000805b84811015611f1257611eef84886119ad565b611efa818486612771565b60208501945060028401935050600181019050611edd565b5050505050505050565b611f268383611aa3565b67ffffffffffffffff811115611f3f57611f3e612269565b5b611f4982546120f6565b600080601f8411601f84111715611f6657611f6385611a6d565b90505b601f831115611f99576020601f85010481016020851015611f85578190505b611f976020601f860104830182611dd3565b505b601f841160018114611fc65760008515611fb4578388013590505b611fbe8682612128565b87555061201e565b601f1985168260005b82811015611ff457858a01358255600182019150602086019550602081019050611fcf565b8783101561201157858a013561200d601f8a16826121be565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b8381101561205557808201518184015260208101905061203a565b83811115612064576000848401525b50505050565b60008101600083018061207c816122e7565b905061208881846126fd565b505050600181016020830161209d81856118ff565b6120a8818386612720565b505050505050565b60008101600083016120c28185611956565b6120cd818386612730565b505050506001810160208301806120e3816122fd565b90506120ef818461274e565b5050505050565b6000600282049050600182168061210e57607f821691505b602082108114156121225761212161223a565b5b50919050565b600061213483836121be565b9150826002028217905092915050565b61214d826123cc565b810181811067ffffffffffffffff8211171561216c5761216b612269565b5b80604052505050565b600061218082611dae565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156121b3576121b261220b565b5b600182019050919050565b60006121cf600019846008026123f7565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6122c87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff836020036008026123f7565b815481168255505050565b6000819050919050565b6000819050919050565b600081356122f4816127b4565b80915050919050565b6000813561230a816127cb565b80915050919050565b6801000000000000000082111561232d5761232c612269565b5b61233681611a98565b828255808310156123725761234a81611a27565b61235384611a27565b61235c84611a58565b81810183820161236c8183611df6565b50505050505b505050565b6801000000000000000082111561239157612390612269565b5b805461239c816120f6565b808411156123b1576123b084828486611bba565b5b808410156123c6576123c584828486611b11565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b60008214612415576124146121dc565b5b61241e81611dc5565b5050565b60008214612433576124326121dc565b5b61243c81611e3b565b5050565b6124486127e2565b61245381848461278f565b505050565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f6d6967726174696f6e2069732066726f7a656e00000000000000000000000000600082015250565b7f73747265616d20616c7265616479206861732061206450494400000000000000600082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b61261b81611a6d565b612626838254612128565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff612653846123dd565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612695846123dd565b9350801983169250808416831791505092915050565b6000600883026126db7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826123ea565b6126e586836123ea565b95508019841693508086168417925050509392505050565b61270682611e59565b612719612712826122d3565b8354612633565b8255505050565b61272b838383611eb3565b505050565b61273b838383611f1c565b505050565b61274a828261206a565b5050565b61275782611ea1565b61276a612763826122dd565b8354612669565b8255505050565b81156127805761277f6121dc565b5b61278a83826120b0565b505050565b61279883611ea1565b6127ac6127a4826122dd565b8484546126ab565b825550505050565b6127bd81611d70565b81146127c857600080fd5b50565b6127d481611dae565b81146127df57600080fd5b50565b60009056fea26469706673582212203cd9493558aa831bec9e62a003cae25d442665c9c02edcb7c1725ad3e5bb65db64736f6c63430008040033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061010b5760003560e01c806382b7b500116100a2578063b9e2924111610071578063b9e29241146102cc578063cfb452b5146102ea578063ded8896b14610308578063f2fde38b14610324578063fe4b84df146103405761010b565b806382b7b500146102305780638da5cb5b14610260578063afc269111461027e578063b724de3a1461029c5761010b565b80635893253c116100de5780635893253c14610196578063715018a6146101c6578063788243d5146101d0578063810a9afa146102005761010b565b80630d70b3aa14610110578063144ae8551461011a5780634f896d4f14610136578063587a8cbf14610166575b600080fd5b61011861035c565b005b610134600480360381019061012f91906111f4565b610381565b005b610150600480360381019061014b9190611173565b61043f565b60405161015d919061173e565b60405180910390f35b610180600480360381019061017b9190611132565b6104e4565b60405161018d9190611882565b60405180910390f35b6101b060048036038101906101ab9190611173565b610512565b6040516101bd919061173e565b60405180910390f35b6101ce6105b2565b005b6101ea60048036038101906101e59190611173565b6105c6565b6040516101f791906116ed565b60405180910390f35b61021a60048036038101906102159190611173565b610604565b6040516102279190611860565b60405180910390f35b61024a600480360381019061024591906110ed565b610782565b6040516102579190611882565b60405180910390f35b6102686107ad565b60405161027591906116ed565b60405180910390f35b6102866107d7565b6040516102939190611882565b60405180910390f35b6102b660048036038101906102b191906110ed565b6107dd565b6040516102c39190611882565b60405180910390f35b6102d46108f2565b6040516102e19190611708565b60405180910390f35b6102f2610905565b6040516102ff9190611882565b60405180910390f35b610322600480360381019061031d919061119c565b61090b565b005b61033e600480360381019061033991906110c4565b610b00565b005b61035a60048036038101906103559190611173565b610b84565b005b610364610cd1565b6001606760006101000a81548160ff021916908315150217905550565b610389610cd1565b60001515606760009054906101000a900460ff161515146103df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103d6906117a0565b60405180910390fd5b80606a600084815260200190815260200160002081816103ff9190612740565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada82826040516104339291906118cf565b60405180910390a15050565b606060686000838152602001908152602001600020805461045f906120f6565b80601f016020809104026020016040519081016040528092919081815260200182805461048b906120f6565b80156104d85780601f106104ad576101008083540402835291602001916104d8565b820191906000526020600020905b8154815290600101906020018083116104bb57829003601f168201915b50505050509050919050565b6069818051602081018201805184825260208301602085012081835280955050505050506000915090505481565b60686020528060005260406000206000915090508054610531906120f6565b80601f016020809104026020016040519081016040528092919081815260200182805461055d906120f6565b80156105aa5780601f1061057f576101008083540402835291602001916105aa565b820191906000526020600020905b81548152906001019060200180831161058d57829003601f168201915b505050505081565b6105ba610cd1565b6105c46000610d4f565b565b606a6020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b61060c610efa565b606a60008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b8282101561077357838290600052602060002090600202016040518060400160405290816000820180546106d8906120f6565b80601f0160208091040260200160405190810160405280929190818152602001828054610704906120f6565b80156107515780601f1061072657610100808354040283529160200191610751565b820191906000526020600020905b81548152906001019060200180831161073457829003601f168201915b50505050508152602001600182015481525050815260200190600101906106a5565b50505050815250509050919050565b6000606983836040516107969291906116d4565b908152602001604051809103902054905092915050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60665481565b600082826000606983836040516107f59291906116d4565b90815260200160405180910390205414610844576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161083b906117c0565b60405180910390fd5b60006066549050858560686000848152602001908152602001600020919061086d929190610f2a565b5080606987876040516108819291906116d4565b9081526020016040518091039020819055507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d8187876040516108c69392919061189d565b60405180910390a1606660008154809291906108e190612175565b919050555080935050505092915050565b606760009054906101000a900460ff1681565b60655481565b81816000606983836040516109219291906116d4565b90815260200160405180910390205414610970576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610967906117c0565b60405180910390fd5b6000606860008781526020019081526020016000208054610990906120f6565b9050146109d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109c990611760565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16606a600087815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610a76576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6d90611840565b60405180910390fd5b8383606860008881526020019081526020016000209190610a98929190610f2a565b508460698585604051610aac9291906116d4565b9081526020016040518091039020819055507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c858585604051610af19392919061189d565b60405180910390a15050505050565b610b08610cd1565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610b78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b6f90611780565b60405180910390fd5b610b8181610d4f565b50565b60008060019054906101000a900460ff16159050808015610bb55750600160008054906101000a900460ff1660ff16105b80610be25750610bc430610e15565b158015610be15750600160008054906101000a900460ff1660ff16145b5b610c21576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c18906117e0565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015610c5e576001600060016101000a81548160ff0219169083151502179055505b610c66610e38565b81606581905550816066819055508015610ccd5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024986001604051610cc49190611723565b60405180910390a15b5050565b610cd9610e91565b73ffffffffffffffffffffffffffffffffffffffff16610cf76107ad565b73ffffffffffffffffffffffffffffffffffffffff1614610d4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d4490611800565b60405180910390fd5b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610e87576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e7e90611820565b60405180910390fd5b610e8f610e99565b565b600033905090565b600060019054906101000a900460ff16610ee8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610edf90611820565b60405180910390fd5b610ef8610ef3610e91565b610d4f565b565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b828054610f36906120f6565b90600052602060002090601f016020900481019282610f585760008555610f9f565b82601f10610f7157803560ff1916838001178555610f9f565b82800160010185558215610f9f579182015b82811115610f9e578235825591602001919060010190610f83565b5b509050610fac9190610fb0565b5090565b5b80821115610fc9576000816000905550600101610fb1565b5090565b6000610fe0610fdb846119f6565b6119d1565b905082815260208101848484011115610ff857600080fd5b611003848285612028565b509392505050565b60008135905061101a816127b4565b92915050565b60008083601f84011261103257600080fd5b8235905067ffffffffffffffff81111561104b57600080fd5b60208301915083600182028301111561106357600080fd5b9250929050565b600082601f83011261107b57600080fd5b813561108b848260208601610fcd565b91505092915050565b6000604082840312156110a657600080fd5b81905092915050565b6000813590506110be816127cb565b92915050565b6000602082840312156110d657600080fd5b60006110e48482850161100b565b91505092915050565b6000806020838503121561110057600080fd5b600083013567ffffffffffffffff81111561111a57600080fd5b61112685828601611020565b92509250509250929050565b60006020828403121561114457600080fd5b600082013567ffffffffffffffff81111561115e57600080fd5b61116a8482850161106a565b91505092915050565b60006020828403121561118557600080fd5b6000611193848285016110af565b91505092915050565b6000806000604084860312156111b157600080fd5b60006111bf868287016110af565b935050602084013567ffffffffffffffff8111156111dc57600080fd5b6111e886828701611020565b92509250509250925092565b6000806040838503121561120757600080fd5b6000611215858286016110af565b925050602083013567ffffffffffffffff81111561123257600080fd5b61123e85828601611094565b9150509250929050565b6000611254838361162a565b905092915050565b60006112688383611679565b905092915050565b61127981611d70565b82525050565b61128881611d70565b82525050565b600061129a8385611ad3565b9350836020840285016112ac84611a3e565b8060005b878110156112f05784840389526112c78284611cdb565b6112d18582611248565b94506112dc83611ab9565b925060208a019950506001810190506112b0565b50829750879450505050509392505050565b600061130d82611a8d565b6113178185611ad3565b93508360208202850161132985611a48565b8060005b858110156113655784840389528151611346858261125c565b945061135183611ac6565b925060208a0199505060018101905061132d565b50829750879550505050505092915050565b61138081611d82565b82525050565b61138f81611e6b565b82525050565b60006113a18385611ae4565b93506113ae838584612028565b6113b7836123cc565b840190509392505050565b60006113ce8385611af5565b93506113db838584612028565b6113e4836123cc565b840190509392505050565b60006113fb8385611b06565b9350611408838584612028565b82840190509392505050565b600061141f82611aae565b6114298185611ae4565b9350611439818560208601612037565b611442816123cc565b840191505092915050565b600061145882611aae565b6114628185611af5565b9350611472818560208601612037565b61147b816123cc565b840191505092915050565b6000611493601583611af5565b915061149e82612458565b602082019050919050565b60006114b6602683611af5565b91506114c182612481565b604082019050919050565b60006114d9601383611af5565b91506114e4826124d0565b602082019050919050565b60006114fc601983611af5565b9150611507826124f9565b602082019050919050565b600061151f602e83611af5565b915061152a82612522565b604082019050919050565b6000611542602083611af5565b915061154d82612571565b602082019050919050565b6000611565602b83611af5565b91506115708261259a565b604082019050919050565b6000611588601983611af5565b9150611593826125e9565b602082019050919050565b6000604083016115b16000840184611c16565b6115be6000860182611270565b506115cc6020840184611c2d565b85830360208701526115df83828461128e565b925050508091505092915050565b60006040830160008301516116056000860182611270565b506020830151848203602086015261161d8282611302565b9150508091505092915050565b60006040830161163d6000840184611c84565b8583036000870152611650838284611395565b925050506116616020840184611cff565b61166e60208601826116b6565b508091505092915050565b600060408301600083015184820360008601526116968282611414565b91505060208301516116ab60208601826116b6565b508091505092915050565b6116bf81611dae565b82525050565b6116ce81611dae565b82525050565b60006116e18284866113ef565b91508190509392505050565b6000602082019050611702600083018461127f565b92915050565b600060208201905061171d6000830184611377565b92915050565b60006020820190506117386000830184611386565b92915050565b60006020820190508181036000830152611758818461144d565b905092915050565b6000602082019050818103600083015261177981611486565b9050919050565b60006020820190508181036000830152611799816114a9565b9050919050565b600060208201905081810360008301526117b9816114cc565b9050919050565b600060208201905081810360008301526117d9816114ef565b9050919050565b600060208201905081810360008301526117f981611512565b9050919050565b6000602082019050818103600083015261181981611535565b9050919050565b6000602082019050818103600083015261183981611558565b9050919050565b600060208201905081810360008301526118598161157b565b9050919050565b6000602082019050818103600083015261187a81846115ed565b905092915050565b600060208201905061189760008301846116c5565b92915050565b60006040820190506118b260008301866116c5565b81810360208301526118c58184866113c2565b9050949350505050565b60006040820190506118e460008301856116c5565b81810360208301526118f6818461159e565b90509392505050565b6000808335600160200384360303811261191857600080fd5b80840192508235915067ffffffffffffffff82111561193657600080fd5b60208301925060208202360383131561194e57600080fd5b509250929050565b6000808335600160200384360303811261196f57600080fd5b80840192508235915067ffffffffffffffff82111561198d57600080fd5b6020830192506001820236038313156119a557600080fd5b509250929050565b6000823560016040038336030381126119c557600080fd5b80830191505092915050565b60006119db6119ec565b90506119e78282612144565b919050565b6000604051905090565b600067ffffffffffffffff821115611a1157611a10612269565b5b611a1a826123cc565b9050602081019050919050565b6000819050611a37826002611d16565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6020841060008114611b6a57601f841160018114611b3a57611b338685612128565b8355611b64565b611b4383611a6d565b611b586020601f880104820160018301611dd3565b611b628785612612565b505b50611bb3565b611b7382611a6d565b6020601f8701048101601f87168015611b9457611b938160018403612298565b5b611ba66020601f890104840183611dd3565b6001886002021785555050505b5050505050565b6020831060008114611c05576020851060008114611be357611bdc8685612128565b8355611bff565b8360ff1916935083611bf484611a6d565b556001866002020183555b50611c0f565b6001856002020182555b5050505050565b6000611c25602084018461100b565b905092915050565b60008083356001602003843603038112611c4657600080fd5b83810192508235915060208301925067ffffffffffffffff821115611c6a57600080fd5b602082023603841315611c7c57600080fd5b509250929050565b60008083356001602003843603038112611c9d57600080fd5b83810192508235915060208301925067ffffffffffffffff821115611cc157600080fd5b600182023603841315611cd357600080fd5b509250929050565b600082356001604003833603038112611cf357600080fd5b82810191505092915050565b6000611d0e60208401846110af565b905092915050565b6000611d2182611dae565b9150611d2c83611dae565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611d6557611d6461220b565b5b828202905092915050565b6000611d7b82611d8e565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b611dd0600082612377565b50565b5b81811015611df257611de7600082612440565b600181019050611dd4565b5050565b5b81811015611e1557611e0a600082612422565b600281019050611df7565b5050565b81811015611e3757611e2c600082612440565b600181019050611e19565b5050565b611e486000808301612404565b611e56600060018301612440565b50565b6000611e6482611e7d565b9050919050565b6000611e7682611db8565b9050919050565b6000611e8882611e8f565b9050919050565b6000611e9a82611d8e565b9050919050565b6000611eac82611dae565b9050919050565b611ebd8383611a82565b611ec78183612313565b611ed083611a3e565b611ed983611a58565b6000805b84811015611f1257611eef84886119ad565b611efa818486612771565b60208501945060028401935050600181019050611edd565b5050505050505050565b611f268383611aa3565b67ffffffffffffffff811115611f3f57611f3e612269565b5b611f4982546120f6565b600080601f8411601f84111715611f6657611f6385611a6d565b90505b601f831115611f99576020601f85010481016020851015611f85578190505b611f976020601f860104830182611dd3565b505b601f841160018114611fc65760008515611fb4578388013590505b611fbe8682612128565b87555061201e565b601f1985168260005b82811015611ff457858a01358255600182019150602086019550602081019050611fcf565b8783101561201157858a013561200d601f8a16826121be565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b8381101561205557808201518184015260208101905061203a565b83811115612064576000848401525b50505050565b60008101600083018061207c816122e7565b905061208881846126fd565b505050600181016020830161209d81856118ff565b6120a8818386612720565b505050505050565b60008101600083016120c28185611956565b6120cd818386612730565b505050506001810160208301806120e3816122fd565b90506120ef818461274e565b5050505050565b6000600282049050600182168061210e57607f821691505b602082108114156121225761212161223a565b5b50919050565b600061213483836121be565b9150826002028217905092915050565b61214d826123cc565b810181811067ffffffffffffffff8211171561216c5761216b612269565b5b80604052505050565b600061218082611dae565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156121b3576121b261220b565b5b600182019050919050565b60006121cf600019846008026123f7565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6122c87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff836020036008026123f7565b815481168255505050565b6000819050919050565b6000819050919050565b600081356122f4816127b4565b80915050919050565b6000813561230a816127cb565b80915050919050565b6801000000000000000082111561232d5761232c612269565b5b61233681611a98565b828255808310156123725761234a81611a27565b61235384611a27565b61235c84611a58565b81810183820161236c8183611df6565b50505050505b505050565b6801000000000000000082111561239157612390612269565b5b805461239c816120f6565b808411156123b1576123b084828486611bba565b5b808410156123c6576123c584828486611b11565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b60008214612415576124146121dc565b5b61241e81611dc5565b5050565b60008214612433576124326121dc565b5b61243c81611e3b565b5050565b6124486127e2565b61245381848461278f565b505050565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f6d6967726174696f6e2069732066726f7a656e00000000000000000000000000600082015250565b7f73747265616d20616c7265616479206861732061206450494400000000000000600082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b61261b81611a6d565b612626838254612128565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff612653846123dd565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612695846123dd565b9350801983169250808416831791505092915050565b6000600883026126db7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826123ea565b6126e586836123ea565b95508019841693508086168417925050509392505050565b61270682611e59565b612719612712826122d3565b8354612633565b8255505050565b61272b838383611eb3565b505050565b61273b838383611f1c565b505050565b61274a828261206a565b5050565b61275782611ea1565b61276a612763826122dd565b8354612669565b8255505050565b81156127805761277f6121dc565b5b61278a83826120b0565b505050565b61279883611ea1565b6127ac6127a4826122dd565b8484546126ab565b825550505050565b6127bd81611d70565b81146127c857600080fd5b50565b6127d481611dae565b81146127df57600080fd5b50565b60009056fea26469706673582212203cd9493558aa831bec9e62a003cae25d442665c9c02edcb7c1725ad3e5bb65db64736f6c63430008040033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/desci-contracts/contracts/DpidAliasRegistry.sol b/desci-contracts/contracts/DpidAliasRegistry.sol index 960df556..ba8b4809 100644 --- a/desci-contracts/contracts/DpidAliasRegistry.sol +++ b/desci-contracts/contracts/DpidAliasRegistry.sol @@ -4,12 +4,15 @@ pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; contract DpidAliasRegistry is OwnableUpgradeable { - // Only written at time of initialization + // Starting point of new aliases (set at initialization) uint256 public firstDpid; // Incremented on each dPID mint uint256 public nextDpid; + // When this is set to true, further edits of the legacy entries are blocked + bool public migrationFrozen; + // dpid => codex streamID (resolve dPID) mapping(uint256 => string) public registry; @@ -21,7 +24,7 @@ contract DpidAliasRegistry is OwnableUpgradeable { _disableInitializers(); } - function __DpidAliasRegistry_init(uint256 _firstDpid) public initializer { + function initialize(uint256 _firstDpid) public initializer { OwnableUpgradeable.__Ownable_init(); firstDpid = _firstDpid; nextDpid = _firstDpid; @@ -43,19 +46,36 @@ contract DpidAliasRegistry is OwnableUpgradeable { return reverseRegistry[streamId]; } + /** + * Signal that a stream has been bound to a new dPID alias. + * + * @param dpid the new alias + * @param streamID the bound stream + */ event DpidMinted ( uint256 dpid, string streamID ); /** - * Claim the next free dPID by pointing it to a codex stream ID + * Ensure the streamId to alias is not already bound to a dPID. * - * @param streamId the codex stream ID to alias + * @param streamId the stream that is requesting a dPID */ - function mintDpid(string calldata streamId) public returns(uint256) { + modifier onlyUnaliasedStream(string calldata streamId) { require(reverseRegistry[streamId] == 0, "stream already has a dPID"); + _; + } + /** + * Claim the next free dPID by pointing it to a codex stream ID. + * This can only be done once, as a given steam can only have one dPID. + * + * @param streamId the codex stream ID to alias + */ + function mintDpid( + string calldata streamId + ) public onlyUnaliasedStream(streamId) returns(uint256) { uint256 thisDpid = nextDpid; // map this dPID to the passed stream ID @@ -66,7 +86,7 @@ contract DpidAliasRegistry is OwnableUpgradeable { emit DpidMinted(thisDpid, streamId); - // Move counter to next free dPID + // Move counter to a free dPID nextDpid++; return thisDpid; } @@ -75,21 +95,34 @@ contract DpidAliasRegistry is OwnableUpgradeable { // Backward compatibility // // ---------------------- // + /** + * Represents a single update in the history of a legacy dPID + */ struct LegacyVersion { string cid; uint256 time; } + /** + * Represents the entire lineage of a legacy dPID, associated with it's owner. + * This owner information is what gates the upgrade of a dPID. + */ struct LegacyDpidEntry { address owner; LegacyVersion[] versions; } /** - * Maps dPIDs before _firstDpid to it's complete history. + * Maps legacy dPIDs to their complete history. * This allows resolving every old state of a legacy dPID * using only this contract. If the author wants to update * this history, they need to call upgradeDpid. + * + * This mapping stays populated even after a dPID is upgraded, + * to allow finding the timestamps for previous versions if needed. + * Additionally, if the stream that claims the dPID as an alias + * does not represent the same history, this allows falling back + * to resolving the historical state regardless. */ mapping(uint256 => LegacyDpidEntry) public legacy; @@ -97,39 +130,47 @@ contract DpidAliasRegistry is OwnableUpgradeable { * Lookup the state of an unmigrated, legacy dPID. * Use this to resolve the history of a dPID that hasn't been updated * since the protocol upgrade, or to check the timestamps of old versions. + * * @param dpid the alias to lookup */ function legacyLookup(uint256 dpid) public view returns(LegacyDpidEntry memory) { return legacy[dpid]; } + /** + * Signal that a legacy dPID has been upgraded and bound to a stream. + * + * @param dpid the dPID which has been upgraded + * @param streamId the bound stream + */ event UpgradedDpid ( uint256 dpid, string streamId ); /** - * The owner of a migrated ResearchObject token can call this function - * to claim the same dPID in this alias registry by pointing it to a codex - * streamID representing the same research object. + * The owner of a legacy dPID can call this function to claim the same dPID + * in this alias registry, by pointing it to a codex stream. + * + * This function can only be called with a stream that hasn't already + * minted an alias, as each stream only can have one dPID. * * This is an at-most-once operation, as the registry is immutable. * The caller must make sure the stream represents the same history, - * and that it controls the stream. - * - * The legacy entry is deleted when migrated. + * and that it controls the stream. This cannot be formally guaranteed, + * which is why the legacy entires are kept to ensure continued deterministic + * resolution of versions as they were originally created. * - * @param dpid the dPID to migrate - * @param streamId the codex stream ID that shall supersede the legacy history + * @param dpid the dPID to upgrade + * @param streamId the stream representing that same dPID */ - function upgradeDpid(uint256 dpid, string calldata streamId) public { + function upgradeDpid( + uint256 dpid, + string calldata streamId + ) public onlyUnaliasedStream(streamId) { // Assert that this dPID has not been set in the main registry require(bytes(registry[dpid]).length == 0, "dpid already upgraded"); - // ??????????????????????????????????????????????????? - // Assert that this stream hasn't already got an alias - require(reverseRegistry[streamId] == 0, "stream already has a dPID"); - // Assert that the tx was made by the owner of the imported entry require(legacy[dpid].owner == msg.sender, "unauthorized dpid upgrade"); @@ -138,22 +179,45 @@ contract DpidAliasRegistry is OwnableUpgradeable { reverseRegistry[streamId] = dpid; emit UpgradedDpid(dpid, streamId); - - // Delete the legacy entry ? - // delete legacy[dpid]; } // ---------------------------- // // Population of legacy mapping // // ---------------------------- // + /** + * Signal that a legacy dPID has been imported into the legacy registry. + * + * @param dpid the imported dPID + * @param entry the historical information to store + */ event ImportedDpid ( uint256 dpid, LegacyDpidEntry entry ); - function importLegacyDpid(uint256 dpid, LegacyDpidEntry calldata entry) public onlyOwner { + /** + * Import the history and ownership information about a legacy dPID into + * the registry. This allows overwriting to correct migration errors, + * but can be locked for further imports. + * + * @param dpid the dPID to import + * @param entry the historical and ownership information + */ + function importLegacyDpid( + uint256 dpid, + LegacyDpidEntry calldata entry + ) public onlyOwner { + require(migrationFrozen == false, "migration is frozen"); legacy[dpid] = entry; emit ImportedDpid(dpid, entry); } + + /** + * This permanently blocks importing/overwriting legacy dPID entries, + * effectively freezing history. + */ + function freezeMigration() public onlyOwner { + migrationFrozen = true; + } } diff --git a/desci-contracts/package.json b/desci-contracts/package.json index 7ae725f2..38beb3db 100644 --- a/desci-contracts/package.json +++ b/desci-contracts/package.json @@ -11,7 +11,7 @@ "docker:push": "docker tag desci-hardhat-node:latest 523044037273.dkr.ecr.us-east-2.amazonaws.com/desci-hardhat-node:latest && docker push 523044037273.dkr.ecr.us-east-2.amazonaws.com/desci-hardhat-node:latest", "deploy:ganache": "yarn stubHardhatAnalytics && hardhat run scripts/deployResearchObject.js --network ganache", "deploy:dpid:ganache": "yarn stubHardhatAnalytics && hardhat run scripts/deployDpidRegistry.js --network ganache", - "deploy:alias:ganache": "yarn stubHardhatAnalytics && hardhat run scripts/deployDpidAliasRegistry.js --network ganache", + "deploy:alias:ganache": "yarn stubHardhatAnalytics && export FIRST_DPID=500 && hardhat run scripts/deployDpidAliasRegistry.js --network ganache", "migrate": "hardhat run scripts/migrateToNewContract.js --network ganache && touch ./.openzeppelin/migration-complete.json", "graph:codegen": "graph codegen subgraph/subgraph.yaml -o subgraph/generated", "graph:build": "graph build subgraph/subgraph.yaml", diff --git a/desci-contracts/scripts/deployDpidAliasRegistry.js b/desci-contracts/scripts/deployDpidAliasRegistry.js index c6d8efef..e5f7740b 100644 --- a/desci-contracts/scripts/deployDpidAliasRegistry.js +++ b/desci-contracts/scripts/deployDpidAliasRegistry.js @@ -1,9 +1,11 @@ const { ethers, upgrades } = require("hardhat"); const fs = require('fs'); -const FIRST_DPID = 500; +const FIRST_DPID = process.env.FIRST_DPID; +if (FIRST_DPID === undefined) { + throw new Error("FIRST_DPID unset"); +}; -console.log(process.cwd()) async function main() { fs.rmSync(".openzeppelin/unknown-dpid-alias-registry.json", { force: true }); fs.rmSync(".openzeppelin/unknown-1337.json", { force: true }); @@ -16,7 +18,7 @@ async function main() { FIRST_DPID // firstDpid ], { - initializer: "__DpidAliasRegistry_init" + initializer: "initialize" } ); await proxy.deployed(); diff --git a/desci-contracts/scripts/migrateToAliasRegistry.mjs b/desci-contracts/scripts/migrateToAliasRegistry.mjs index 916ad9f2..0ac02c1d 100644 --- a/desci-contracts/scripts/migrateToAliasRegistry.mjs +++ b/desci-contracts/scripts/migrateToAliasRegistry.mjs @@ -1,24 +1,44 @@ import hardhat from "hardhat"; -const { ethers } = hardhat; +const { ethers, hardhatArguments } = hardhat; import axios from "axios"; +import { writeFileSync } from "fs"; + +const FIRST_DPID = process.env.FIRST_DPID; +if (FIRST_DPID === undefined) { + throw new Error("FIRST_DPID unset"); +}; + +const ENV = process.env.ENV; +if (ENV === undefined) { + throw new Error("ENV unset"); +}; + +let dpidApi; +if (ENV === "dev") { + dpidApi = "dev-beta"; +} else if (ENV === "prod") { + dpidApi = "beta"; +} else { + throw new Error(`Env "${ENV} unknown (use "dev" or "prod")`); +}; const getDpidPage = async (page) => { const { data } = await axios.get( - `https://dev-beta.dpid.org/api/v1/dpid?size=100&page=${page}` + `https://${dpidApi}.dpid.org/api/v1/dpid?size=100&page=${page}` ); return data; }; const allDpids = (await Promise.all( [1,2,3].map(getDpidPage) -)).flat(); +)).flat().sort((d1, d2) => parseInt(d1.dpid) - parseInt(d2.dpid)); const toImportEntry = (dpid) => [ dpid.dpid, { owner: dpid.researchObject.owner, versions: dpid.researchObject.versions.map(v => ({cid: v.cid, time: v.time})) - } + }, ]; const importEntries = allDpids.map(toImportEntry); @@ -28,34 +48,80 @@ const DpidAliasRegistryFactory = await ethers.getContractFactory("DpidAliasRegis const registry = await upgrades.deployProxy( DpidAliasRegistryFactory, [ - 500 // firstDpid + FIRST_DPID ], { - initializer: "__DpidAliasRegistry_init" + initializer: "initialize" } ); await registry.deployed(); +console.log(`📃 Contract deployed to ${registry.address}`); -const sliceToImport = importEntries.slice(0,5); -console.log("Importing dPIDs:", sliceToImport.map(s => s[0]).join(", ")) - -const results = []; +const results = { + address: registry.address, + dpids: [], +}; +let totalGas = 0; +const startTime = Date.now(); -for (const [ dpid, entry ] of importEntries.slice(0, 5)) { - console.log(`✨ Importing dPID ${dpid}...`) - await registry.importLegacyDpid(dpid, entry); +for (const [ dpid, entry ] of importEntries) { + console.log(`📥 Importing dPID ${dpid}...`) + const tx = await registry.importLegacyDpid(dpid, entry); + const receipt = await tx.wait(); + totalGas += ethers.BigNumber.from(receipt.gasUsed).toNumber(); - console.log(`🔎 Resolving dPID ${dpid} from new contract...`) const fromContract = await registry.legacyLookup(dpid); - const result = { + const imported = { dpid, owner: fromContract[0], versions: fromContract[1].map(([cid, time]) => ({cid, time: ethers.BigNumber.from(time).toNumber() })) }; - console.log(`🎊 Found migrated history of dPID ${dpid} in new contract: \n${JSON.stringify(result, undefined, 2)}`) - console.log("-----------------------------------------------------------------") + console.log(`🔎 Verifying dPID ${dpid}:`); + + const originalDpid = allDpids.find(e => e.dpid === dpid); + const originalOwner = originalDpid.researchObject.owner; + const originalVersions = originalDpid.researchObject.versions; + + let validationError = false; + + const ownerCorrect = originalOwner === imported.owner.toLowerCase(); + console.log(` - Ownership: ${ownerCorrect ? "✅" : "❌"} (${originalOwner})`); + if (!ownerCorrect) validationError = true; + + console.log(` - History:`) + for (let i = 0; i < originalVersions.length; i++) { + console.log(` - v${i}:`) + const cidCorrect = originalVersions[i].cid === imported.versions[i].cid; + const timeCorrect = originalVersions[i].time === imported.versions[i].time; + + console.log(` - cid: ${cidCorrect ? "✅" : "❌"} (${originalVersions[i].cid})`); + console.log(` - time: ${timeCorrect ? "✅" : "❌"} (${originalVersions[i].time})`); + if (!(cidCorrect && timeCorrect)) { + validationError = true; + }; + }; + results.dpids.push({ dpid, owner: imported.owner, versions: imported.versions, importError: validationError }); +}; + +const failures = results.dpids.filter(r => r.validationError); +console.log(`🚦 dPIDs which failed validation: ${JSON.stringify(failures)}`) + +const missingNumbers = []; +for (let i = 0; i < importEntries.length; i++) { + if (!allDpids.find(e => e.dpid === i.toString())) { + missingNumbers.push(i); + }; }; +console.log(`❓ dPID's missing from original set: ${JSON.stringify(missingNumbers)}`) + +const duration = Math.ceil((Date.now() - startTime) / 1000); +console.log(`🏁 migration done in ${duration}s for a total of ${totalGas} gas`) + +const dateString = new Date().toUTCString().replaceAll(" ", "_"); +const logFilePath = `migration-data/aliasRegistry_${dateString}.json`; +writeFileSync(logFilePath, JSON.stringify(results, undefined, 2)); +console.log(`📝 migration data written to ${logFilePath}`); diff --git a/desci-contracts/scripts/syncAliasRegistryMigration.mjs b/desci-contracts/scripts/syncAliasRegistryMigration.mjs new file mode 100644 index 00000000..36631517 --- /dev/null +++ b/desci-contracts/scripts/syncAliasRegistryMigration.mjs @@ -0,0 +1,97 @@ +import hardhat from "hardhat"; +const { ethers, hardhatArguments } = hardhat; +import axios from "axios"; +import { writeFileSync } from "fs"; + +const REGISTRY_ADDRESS = process.env.REGISTRY_ADDRESS; +if (REGISTRY_ADDRESS === undefined) { + throw new Error("REGISTRY_ADDRESS unset"); +}; + +const getDpidPage = async (page) => { + const { data } = await axios.get( + `https://dev-beta.dpid.org/api/v1/dpid?size=100&page=${page}` + ); + return data; +}; + +const allDpids = (await Promise.all( + [1,2,3].map(getDpidPage) +)).flat().sort((d1, d2) => parseInt(d1.dpid) - parseInt(d2.dpid)); + +const toImportEntry = (dpid) => [ + dpid.dpid, + { + owner: dpid.researchObject.owner, + versions: dpid.researchObject.versions.map(v => ({cid: v.cid, time: v.time})) + } +]; + +const importEntries = allDpids.map(toImportEntry); + +const DpidAliasRegistryFactory = await ethers.getContractFactory("DpidAliasRegistry"); +const registry = DpidAliasRegistryFactory + .attach(REGISTRY_ADDRESS); + +const results = []; +let totalGas = 0; +const startTime = Date.now(); + +for (const [ dpid, entry ] of importEntries) { + const [owner, versions] = await registry.legacyLookup(dpid); + const notImported = owner === "0x0000000000000000000000000000000000000000"; + + if (notImported) { + console.log(`❗ dPID ${dpid} not found, importing...`); + const tx = await registry.importLegacyDpid(dpid, entry); + const receipt = await tx.wait(); + totalGas += ethers.BigNumber.from(receipt.gasUsed).toNumber(); + }; + + const fromContract = await registry.legacyLookup(dpid); + + const imported = { + dpid, + owner: fromContract[0], + versions: fromContract[1].map(([cid, time]) => ({cid, time: ethers.BigNumber.from(time).toNumber() })) + }; + + console.log(`🔎 Verifying dPID ${dpid}:`); + + const originalDpid = allDpids.find(e => e.dpid === dpid); + const originalOwner = originalDpid.researchObject.owner; + const originalVersions = originalDpid.researchObject.versions; + + let validationError = false; + + const ownerCorrect = originalOwner === imported.owner.toLowerCase(); + console.log(` - Ownership: ${ownerCorrect ? "✅" : "❌"} (${originalOwner})`); + if (!ownerCorrect) validationError = true; + + console.log(` - History:`) + for (let i = 0; i < originalVersions.length; i++) { + console.log(` - v${i}:`) + const cidCorrect = originalVersions[i].cid === imported.versions[i].cid; + const timeCorrect = originalVersions[i].time === imported.versions[i].time; + + console.log(` - cid: ${cidCorrect ? "✅" : "❌"} (${originalVersions[i].cid})`); + console.log(` - time: ${timeCorrect ? "✅" : "❌"} (${originalVersions[i].time})`); + if (!(cidCorrect && timeCorrect)) { + validationError = true; + }; + }; + + + results.push({ dpid, owner: imported.owner, versions: imported.versions, importError: validationError }); +}; + +const failures = results.filter(r => r.validationError); +console.log(`🚦 dPIDs which failed validation (manually import to overwrite): ${JSON.stringify(failures)}`) + +const duration = Math.ceil((Date.now() - startTime) / 1000); +console.log(`🏁 migration done in ${duration}s for a total of ${totalGas} gas`) + +const dateString = new Date().toUTCString().replaceAll(" ", "_"); +const logFilePath = `migration-data/aliasRegistry_${dateString}.json`; +writeFileSync(logFilePath, JSON.stringify(results, undefined, 2)); +console.log(`📝 migration data written to ${logFilePath}`); diff --git a/desci-contracts/test/DpidAliasRegistry.ts b/desci-contracts/test/DpidAliasRegistry.ts index 99643cb2..44151dfa 100644 --- a/desci-contracts/test/DpidAliasRegistry.ts +++ b/desci-contracts/test/DpidAliasRegistry.ts @@ -8,6 +8,7 @@ import { } from "../typechain-types"; import { TransactionReceipt } from "@ethersproject/abstract-provider"; import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; +import { receiveMessageOnPort } from "worker_threads"; use(chaiAsPromised); @@ -37,7 +38,7 @@ describe("dPID", () => { FIRST_DPID // firstDpid ], { - initializer: "__DpidAliasRegistry_init" + initializer: "initialize", } ) as DpidAliasRegistry; await dpidAliasRegistry.deployed(); @@ -56,11 +57,10 @@ describe("dPID", () => { reciept = await dpidAliasRegistry.deployTransaction.wait(); proxyAddress = reciept.contractAddress; implAddress = await upgrades.erc1967.getImplementationAddress(proxyAddress); - proxyAdmin = await upgrades.erc1967.getAdminAddress(proxyAddress); console.log({ implAddress, - proxyAdmin, + proxyAddress, implOwner: await dpidAliasRegistry.owner(), }) }); @@ -76,9 +76,9 @@ describe("dPID", () => { expect(proxyAddress).not.to.equal(implAddress); }); - it("deploys implementation with proxy admin as owner", async () => { + it("deploys implementation with proxy owner as owner", async () => { const registryOwner = await dpidAliasRegistry.owner(); - expect(registryOwner).to.equal(proxyAdmin); + expect(registryOwner).to.equal(owner.address); }); it("respects initializer dpid offset", async () => { @@ -181,11 +181,12 @@ describe("dPID", () => { describe("upgrade", () => { let successReceipt: ContractReceipt; + const STREAM_C = "kjzl6kcym7w8y7i5ugaq9a3vlm7hhuaf4bpl5o5qykeh4qtsa12c6rb5ekw6ccc"; it("can NOT be done by others", async () => { const doUpgrade = async () => await dpidAliasRegistry .connect(user2) - .upgradeDpid(0, STREAM_A); + .upgradeDpid(0, STREAM_C); await expect(doUpgrade()).to.be.rejectedWith("unauthorized dpid upgrade"); }); @@ -193,22 +194,22 @@ describe("dPID", () => { it("can NOT be done by contract owner", async () => { const doUpgrade = async () => await dpidAliasRegistry .connect(owner) - .upgradeDpid(0, STREAM_A); + .upgradeDpid(0, STREAM_C); await expect(doUpgrade()).to.be.rejectedWith("unauthorized dpid upgrade"); }); it("can be done by dpid owner", async () => { - const tx = await dpidAliasRegistry.upgradeDpid(0, STREAM_A); + const tx = await dpidAliasRegistry.upgradeDpid(0, STREAM_C); successReceipt = await tx.wait(); const upgradedEntry = await dpidAliasRegistry.resolve(0); - expect(upgradedEntry).to.equal(STREAM_A); + expect(upgradedEntry).to.equal(STREAM_C); }); it("cannot be done twice", async () => { const doSecondUpgrade = async () => - await dpidAliasRegistry.upgradeDpid(0, STREAM_A); + await dpidAliasRegistry.upgradeDpid(0, STREAM_C); await expect(doSecondUpgrade()).to.be.rejectedWith("dpid already upgraded"); }); @@ -219,7 +220,7 @@ describe("dPID", () => { expect(event.event).to.equal("UpgradedDpid"); expect(dpid).to.equal(0); - expect(streamId).to.equal(STREAM_A); + expect(streamId).to.equal(STREAM_C); }); }); }); diff --git a/desci-contracts/typechain-types/DpidAliasRegistry.ts b/desci-contracts/typechain-types/DpidAliasRegistry.ts index 7e8aa99c..efc29a83 100644 --- a/desci-contracts/typechain-types/DpidAliasRegistry.ts +++ b/desci-contracts/typechain-types/DpidAliasRegistry.ts @@ -42,12 +42,14 @@ export declare namespace DpidAliasRegistry { export interface DpidAliasRegistryInterface extends utils.Interface { contractName: "DpidAliasRegistry"; functions: { - "__DpidAliasRegistry_init(uint256)": FunctionFragment; "find(string)": FunctionFragment; "firstDpid()": FunctionFragment; + "freezeMigration()": FunctionFragment; "importLegacyDpid(uint256,(address,(string,uint256)[]))": FunctionFragment; + "initialize(uint256)": FunctionFragment; "legacy(uint256)": FunctionFragment; "legacyLookup(uint256)": FunctionFragment; + "migrationFrozen()": FunctionFragment; "mintDpid(string)": FunctionFragment; "nextDpid()": FunctionFragment; "owner()": FunctionFragment; @@ -59,16 +61,20 @@ export interface DpidAliasRegistryInterface extends utils.Interface { "upgradeDpid(uint256,string)": FunctionFragment; }; - encodeFunctionData( - functionFragment: "__DpidAliasRegistry_init", - values: [BigNumberish] - ): string; encodeFunctionData(functionFragment: "find", values: [string]): string; encodeFunctionData(functionFragment: "firstDpid", values?: undefined): string; + encodeFunctionData( + functionFragment: "freezeMigration", + values?: undefined + ): string; encodeFunctionData( functionFragment: "importLegacyDpid", values: [BigNumberish, DpidAliasRegistry.LegacyDpidEntryStruct] ): string; + encodeFunctionData( + functionFragment: "initialize", + values: [BigNumberish] + ): string; encodeFunctionData( functionFragment: "legacy", values: [BigNumberish] @@ -77,6 +83,10 @@ export interface DpidAliasRegistryInterface extends utils.Interface { functionFragment: "legacyLookup", values: [BigNumberish] ): string; + encodeFunctionData( + functionFragment: "migrationFrozen", + values?: undefined + ): string; encodeFunctionData(functionFragment: "mintDpid", values: [string]): string; encodeFunctionData(functionFragment: "nextDpid", values?: undefined): string; encodeFunctionData(functionFragment: "owner", values?: undefined): string; @@ -105,21 +115,26 @@ export interface DpidAliasRegistryInterface extends utils.Interface { values: [BigNumberish, string] ): string; + decodeFunctionResult(functionFragment: "find", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "firstDpid", data: BytesLike): Result; decodeFunctionResult( - functionFragment: "__DpidAliasRegistry_init", + functionFragment: "freezeMigration", data: BytesLike ): Result; - decodeFunctionResult(functionFragment: "find", data: BytesLike): Result; - decodeFunctionResult(functionFragment: "firstDpid", data: BytesLike): Result; decodeFunctionResult( functionFragment: "importLegacyDpid", data: BytesLike ): Result; + decodeFunctionResult(functionFragment: "initialize", data: BytesLike): Result; decodeFunctionResult(functionFragment: "legacy", data: BytesLike): Result; decodeFunctionResult( functionFragment: "legacyLookup", data: BytesLike ): Result; + decodeFunctionResult( + functionFragment: "migrationFrozen", + data: BytesLike + ): Result; decodeFunctionResult(functionFragment: "mintDpid", data: BytesLike): Result; decodeFunctionResult(functionFragment: "nextDpid", data: BytesLike): Result; decodeFunctionResult(functionFragment: "owner", data: BytesLike): Result; @@ -218,21 +233,25 @@ export interface DpidAliasRegistry extends BaseContract { removeListener: OnEvent; functions: { - __DpidAliasRegistry_init( - _firstDpid: BigNumberish, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - find(streamId: string, overrides?: CallOverrides): Promise<[BigNumber]>; firstDpid(overrides?: CallOverrides): Promise<[BigNumber]>; + freezeMigration( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + importLegacyDpid( dpid: BigNumberish, entry: DpidAliasRegistry.LegacyDpidEntryStruct, overrides?: Overrides & { from?: string | Promise } ): Promise; + initialize( + _firstDpid: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + legacy( arg0: BigNumberish, overrides?: CallOverrides @@ -243,6 +262,8 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: CallOverrides ): Promise<[DpidAliasRegistry.LegacyDpidEntryStructOutput]>; + migrationFrozen(overrides?: CallOverrides): Promise<[boolean]>; + mintDpid( streamId: string, overrides?: Overrides & { from?: string | Promise } @@ -277,21 +298,25 @@ export interface DpidAliasRegistry extends BaseContract { ): Promise; }; - __DpidAliasRegistry_init( - _firstDpid: BigNumberish, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - find(streamId: string, overrides?: CallOverrides): Promise; firstDpid(overrides?: CallOverrides): Promise; + freezeMigration( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + importLegacyDpid( dpid: BigNumberish, entry: DpidAliasRegistry.LegacyDpidEntryStruct, overrides?: Overrides & { from?: string | Promise } ): Promise; + initialize( + _firstDpid: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + legacy(arg0: BigNumberish, overrides?: CallOverrides): Promise; legacyLookup( @@ -299,6 +324,8 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: CallOverrides ): Promise; + migrationFrozen(overrides?: CallOverrides): Promise; + mintDpid( streamId: string, overrides?: Overrides & { from?: string | Promise } @@ -330,21 +357,23 @@ export interface DpidAliasRegistry extends BaseContract { ): Promise; callStatic: { - __DpidAliasRegistry_init( - _firstDpid: BigNumberish, - overrides?: CallOverrides - ): Promise; - find(streamId: string, overrides?: CallOverrides): Promise; firstDpid(overrides?: CallOverrides): Promise; + freezeMigration(overrides?: CallOverrides): Promise; + importLegacyDpid( dpid: BigNumberish, entry: DpidAliasRegistry.LegacyDpidEntryStruct, overrides?: CallOverrides ): Promise; + initialize( + _firstDpid: BigNumberish, + overrides?: CallOverrides + ): Promise; + legacy(arg0: BigNumberish, overrides?: CallOverrides): Promise; legacyLookup( @@ -352,6 +381,8 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: CallOverrides ): Promise; + migrationFrozen(overrides?: CallOverrides): Promise; + mintDpid(streamId: string, overrides?: CallOverrides): Promise; nextDpid(overrides?: CallOverrides): Promise; @@ -414,21 +445,25 @@ export interface DpidAliasRegistry extends BaseContract { }; estimateGas: { - __DpidAliasRegistry_init( - _firstDpid: BigNumberish, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - find(streamId: string, overrides?: CallOverrides): Promise; firstDpid(overrides?: CallOverrides): Promise; + freezeMigration( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + importLegacyDpid( dpid: BigNumberish, entry: DpidAliasRegistry.LegacyDpidEntryStruct, overrides?: Overrides & { from?: string | Promise } ): Promise; + initialize( + _firstDpid: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + legacy(arg0: BigNumberish, overrides?: CallOverrides): Promise; legacyLookup( @@ -436,6 +471,8 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: CallOverrides ): Promise; + migrationFrozen(overrides?: CallOverrides): Promise; + mintDpid( streamId: string, overrides?: Overrides & { from?: string | Promise } @@ -471,11 +508,6 @@ export interface DpidAliasRegistry extends BaseContract { }; populateTransaction: { - __DpidAliasRegistry_init( - _firstDpid: BigNumberish, - overrides?: Overrides & { from?: string | Promise } - ): Promise; - find( streamId: string, overrides?: CallOverrides @@ -483,12 +515,21 @@ export interface DpidAliasRegistry extends BaseContract { firstDpid(overrides?: CallOverrides): Promise; + freezeMigration( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + importLegacyDpid( dpid: BigNumberish, entry: DpidAliasRegistry.LegacyDpidEntryStruct, overrides?: Overrides & { from?: string | Promise } ): Promise; + initialize( + _firstDpid: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + legacy( arg0: BigNumberish, overrides?: CallOverrides @@ -499,6 +540,8 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: CallOverrides ): Promise; + migrationFrozen(overrides?: CallOverrides): Promise; + mintDpid( streamId: string, overrides?: Overrides & { from?: string | Promise } diff --git a/desci-contracts/typechain-types/factories/DpidAliasRegistry__factory.ts b/desci-contracts/typechain-types/factories/DpidAliasRegistry__factory.ts index 4598e9f9..5339dc20 100644 --- a/desci-contracts/typechain-types/factories/DpidAliasRegistry__factory.ts +++ b/desci-contracts/typechain-types/factories/DpidAliasRegistry__factory.ts @@ -127,19 +127,6 @@ const _abi = [ name: "UpgradedDpid", type: "event", }, - { - inputs: [ - { - internalType: "uint256", - name: "_firstDpid", - type: "uint256", - }, - ], - name: "__DpidAliasRegistry_init", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, { inputs: [ { @@ -172,6 +159,13 @@ const _abi = [ stateMutability: "view", type: "function", }, + { + inputs: [], + name: "freezeMigration", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, { inputs: [ { @@ -214,6 +208,19 @@ const _abi = [ stateMutability: "nonpayable", type: "function", }, + { + inputs: [ + { + internalType: "uint256", + name: "_firstDpid", + type: "uint256", + }, + ], + name: "initialize", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, { inputs: [ { @@ -276,6 +283,19 @@ const _abi = [ stateMutability: "view", type: "function", }, + { + inputs: [], + name: "migrationFrozen", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, { inputs: [ { @@ -419,7 +439,7 @@ const _abi = [ ]; const _bytecode = - "0x60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d3565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000127565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff161015620000ed5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e4919062000149565b60405180910390a15b565b6000620000fe60278362000166565b91506200010b8262000184565b604082019050919050565b620001218162000177565b82525050565b600060208201905081810360008301526200014281620000ef565b9050919050565b600060208201905062000160600083018462000116565b92915050565b600082825260208201905092915050565b600060ff82169050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b6126a680620001e36000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c8063810a9afa11610097578063b724de3a11610066578063b724de3a14610298578063cfb452b5146102c8578063ded8896b146102e6578063f2fde38b14610302576100f5565b8063810a9afa146101fc57806382b7b5001461022c5780638da5cb5b1461025c578063afc269111461027a576100f5565b8063587a8cbf116100d3578063587a8cbf146101625780635893253c14610192578063715018a6146101c2578063788243d5146101cc576100f5565b8063144ae855146100fa578063362b3e63146101165780634f896d4f14610132575b600080fd5b610114600480360381019061010f919061111f565b61031e565b005b610130600480360381019061012b919061109e565b610386565b005b61014c6004803603810190610147919061109e565b6104d3565b604051610159919061161c565b60405180910390f35b61017c6004803603810190610177919061105d565b610578565b6040516101899190611740565b60405180910390f35b6101ac60048036038101906101a7919061109e565b6105a6565b6040516101b9919061161c565b60405180910390f35b6101ca610646565b005b6101e660048036038101906101e1919061109e565b61065a565b6040516101f391906115e6565b60405180910390f35b6102166004803603810190610211919061109e565b610698565b604051610223919061171e565b60405180910390f35b61024660048036038101906102419190611018565b610816565b6040516102539190611740565b60405180910390f35b610264610841565b60405161027191906115e6565b60405180910390f35b61028261086b565b60405161028f9190611740565b60405180910390f35b6102b260048036038101906102ad9190611018565b610871565b6040516102bf9190611740565b60405180910390f35b6102d0610981565b6040516102dd9190611740565b60405180910390f35b61030060048036038101906102fb91906110c7565b610987565b005b61031c60048036038101906103179190610fef565b610b78565b005b610326610bfc565b8060696000848152602001908152602001600020818161034691906125c9565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada828260405161037a92919061178d565b60405180910390a15050565b60008060019054906101000a900460ff161590508080156103b75750600160008054906101000a900460ff1660ff16105b806103e457506103c630610c7a565b1580156103e35750600160008054906101000a900460ff1660ff16145b5b610423576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041a9061169e565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015610460576001600060016101000a81548160ff0219169083151502179055505b610468610c9d565b816065819055508160668190555080156104cf5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516104c69190611601565b60405180910390a15b5050565b60606067600083815260200190815260200160002080546104f390611fa8565b80601f016020809104026020016040519081016040528092919081815260200182805461051f90611fa8565b801561056c5780601f106105415761010080835404028352916020019161056c565b820191906000526020600020905b81548152906001019060200180831161054f57829003601f168201915b50505050509050919050565b6068818051602081018201805184825260208301602085012081835280955050505050506000915090505481565b606760205280600052604060002060009150905080546105c590611fa8565b80601f01602080910402602001604051908101604052809291908181526020018280546105f190611fa8565b801561063e5780601f106106135761010080835404028352916020019161063e565b820191906000526020600020905b81548152906001019060200180831161062157829003601f168201915b505050505081565b61064e610bfc565b6106586000610cf6565b565b60696020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b6106a0610e25565b606960008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b82821015610807578382906000526020600020906002020160405180604001604052908160008201805461076c90611fa8565b80601f016020809104026020016040519081016040528092919081815260200182805461079890611fa8565b80156107e55780601f106107ba576101008083540402835291602001916107e5565b820191906000526020600020905b8154815290600101906020018083116107c857829003601f168201915b5050505050815260200160018201548152505081526020019060010190610739565b50505050815250509050919050565b60006068838360405161082a9291906115cd565b908152602001604051809103902054905092915050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60665481565b600080606884846040516108869291906115cd565b908152602001604051809103902054146108d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108cc9061167e565b60405180910390fd5b6000606654905083836067600084815260200190815260200160002091906108fe929190610e55565b5080606885856040516109129291906115cd565b9081526020016040518091039020819055507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d8185856040516109579392919061175b565b60405180910390a16066600081548092919061097290612027565b91905055508091505092915050565b60655481565b60006067600085815260200190815260200160002080546109a790611fa8565b9050146109e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e09061163e565b60405180910390fd5b6000606883836040516109fd9291906115cd565b90815260200160405180910390205414610a4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a439061167e565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166069600085815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610af0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae7906116fe565b60405180910390fd5b8181606760008681526020019081526020016000209190610b12929190610e55565b508260688383604051610b269291906115cd565b9081526020016040518091039020819055507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c838383604051610b6b9392919061175b565b60405180910390a1505050565b610b80610bfc565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610bf0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610be79061165e565b60405180910390fd5b610bf981610cf6565b50565b610c04610dbc565b73ffffffffffffffffffffffffffffffffffffffff16610c22610841565b73ffffffffffffffffffffffffffffffffffffffff1614610c78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6f906116be565b60405180910390fd5b565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610cec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce3906116de565b60405180910390fd5b610cf4610dc4565b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600060019054906101000a900460ff16610e13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0a906116de565b60405180910390fd5b610e23610e1e610dbc565b610cf6565b565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b828054610e6190611fa8565b90600052602060002090601f016020900481019282610e835760008555610eca565b82601f10610e9c57803560ff1916838001178555610eca565b82800160010185558215610eca579182015b82811115610ec9578235825591602001919060010190610eae565b5b509050610ed79190610edb565b5090565b5b80821115610ef4576000816000905550600101610edc565b5090565b6000610f0b610f06846118b4565b61188f565b905082815260208101848484011115610f2357600080fd5b610f2e848285611eda565b509392505050565b600081359050610f458161263d565b92915050565b60008083601f840112610f5d57600080fd5b8235905067ffffffffffffffff811115610f7657600080fd5b602083019150836001820283011115610f8e57600080fd5b9250929050565b600082601f830112610fa657600080fd5b8135610fb6848260208601610ef8565b91505092915050565b600060408284031215610fd157600080fd5b81905092915050565b600081359050610fe981612654565b92915050565b60006020828403121561100157600080fd5b600061100f84828501610f36565b91505092915050565b6000806020838503121561102b57600080fd5b600083013567ffffffffffffffff81111561104557600080fd5b61105185828601610f4b565b92509250509250929050565b60006020828403121561106f57600080fd5b600082013567ffffffffffffffff81111561108957600080fd5b61109584828501610f95565b91505092915050565b6000602082840312156110b057600080fd5b60006110be84828501610fda565b91505092915050565b6000806000604084860312156110dc57600080fd5b60006110ea86828701610fda565b935050602084013567ffffffffffffffff81111561110757600080fd5b61111386828701610f4b565b92509250509250925092565b6000806040838503121561113257600080fd5b600061114085828601610fda565b925050602083013567ffffffffffffffff81111561115d57600080fd5b61116985828601610fbf565b9150509250929050565b600061117f8383611523565b905092915050565b60006111938383611572565b905092915050565b6111a481611c2e565b82525050565b6111b381611c2e565b82525050565b60006111c58385611991565b9350836020840285016111d7846118fc565b8060005b8781101561121b5784840389526111f28284611b99565b6111fc8582611173565b945061120783611977565b925060208a019950506001810190506111db565b50829750879450505050509392505050565b60006112388261194b565b6112428185611991565b93508360208202850161125485611906565b8060005b8581101561129057848403895281516112718582611187565b945061127c83611984565b925060208a01995050600181019050611258565b50829750879550505050505092915050565b6112ab81611d1d565b82525050565b60006112bd83856119a2565b93506112ca838584611eda565b6112d38361227e565b840190509392505050565b60006112ea83856119b3565b93506112f7838584611eda565b6113008361227e565b840190509392505050565b600061131783856119c4565b9350611324838584611eda565b82840190509392505050565b600061133b8261196c565b61134581856119a2565b9350611355818560208601611ee9565b61135e8161227e565b840191505092915050565b60006113748261196c565b61137e81856119b3565b935061138e818560208601611ee9565b6113978161227e565b840191505092915050565b60006113af6015836119b3565b91506113ba8261230a565b602082019050919050565b60006113d26026836119b3565b91506113dd82612333565b604082019050919050565b60006113f56019836119b3565b915061140082612382565b602082019050919050565b6000611418602e836119b3565b9150611423826123ab565b604082019050919050565b600061143b6020836119b3565b9150611446826123fa565b602082019050919050565b600061145e602b836119b3565b915061146982612423565b604082019050919050565b60006114816019836119b3565b915061148c82612472565b602082019050919050565b6000604083016114aa6000840184611ad4565b6114b7600086018261119b565b506114c56020840184611aeb565b85830360208701526114d88382846111b9565b925050508091505092915050565b60006040830160008301516114fe600086018261119b565b5060208301518482036020860152611516828261122d565b9150508091505092915050565b6000604083016115366000840184611b42565b85830360008701526115498382846112b1565b9250505061155a6020840184611bbd565b61156760208601826115af565b508091505092915050565b6000604083016000830151848203600086015261158f8282611330565b91505060208301516115a460208601826115af565b508091505092915050565b6115b881611c60565b82525050565b6115c781611c60565b82525050565b60006115da82848661130b565b91508190509392505050565b60006020820190506115fb60008301846111aa565b92915050565b600060208201905061161660008301846112a2565b92915050565b600060208201905081810360008301526116368184611369565b905092915050565b60006020820190508181036000830152611657816113a2565b9050919050565b60006020820190508181036000830152611677816113c5565b9050919050565b60006020820190508181036000830152611697816113e8565b9050919050565b600060208201905081810360008301526116b78161140b565b9050919050565b600060208201905081810360008301526116d78161142e565b9050919050565b600060208201905081810360008301526116f781611451565b9050919050565b6000602082019050818103600083015261171781611474565b9050919050565b6000602082019050818103600083015261173881846114e6565b905092915050565b600060208201905061175560008301846115be565b92915050565b600060408201905061177060008301866115be565b81810360208301526117838184866112de565b9050949350505050565b60006040820190506117a260008301856115be565b81810360208301526117b48184611497565b90509392505050565b600080833560016020038436030381126117d657600080fd5b80840192508235915067ffffffffffffffff8211156117f457600080fd5b60208301925060208202360383131561180c57600080fd5b509250929050565b6000808335600160200384360303811261182d57600080fd5b80840192508235915067ffffffffffffffff82111561184b57600080fd5b60208301925060018202360383131561186357600080fd5b509250929050565b60008235600160400383360303811261188357600080fd5b80830191505092915050565b60006118996118aa565b90506118a58282611ff6565b919050565b6000604051905090565b600067ffffffffffffffff8211156118cf576118ce61211b565b5b6118d88261227e565b9050602081019050919050565b60008190506118f5826002611bd4565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6020841060008114611a2857601f8411600181146119f8576119f18685611fda565b8355611a22565b611a018361192b565b611a166020601f880104820160018301611c85565b611a20878561249b565b505b50611a71565b611a318261192b565b6020601f8701048101601f87168015611a5257611a51816001840361214a565b5b611a646020601f890104840183611c85565b6001886002021785555050505b5050505050565b6020831060008114611ac3576020851060008114611aa157611a9a8685611fda565b8355611abd565b8360ff1916935083611ab28461192b565b556001866002020183555b50611acd565b6001856002020182555b5050505050565b6000611ae36020840184610f36565b905092915050565b60008083356001602003843603038112611b0457600080fd5b83810192508235915060208301925067ffffffffffffffff821115611b2857600080fd5b602082023603841315611b3a57600080fd5b509250929050565b60008083356001602003843603038112611b5b57600080fd5b83810192508235915060208301925067ffffffffffffffff821115611b7f57600080fd5b600182023603841315611b9157600080fd5b509250929050565b600082356001604003833603038112611bb157600080fd5b82810191505092915050565b6000611bcc6020840184610fda565b905092915050565b6000611bdf82611c60565b9150611bea83611c60565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611c2357611c226120bd565b5b828202905092915050565b6000611c3982611c40565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b611c82600082612229565b50565b5b81811015611ca457611c996000826122f2565b600181019050611c86565b5050565b5b81811015611cc757611cbc6000826122d4565b600281019050611ca9565b5050565b81811015611ce957611cde6000826122f2565b600181019050611ccb565b5050565b611cfa60008083016122b6565b611d086000600183016122f2565b50565b6000611d1682611d2f565b9050919050565b6000611d2882611c6a565b9050919050565b6000611d3a82611d41565b9050919050565b6000611d4c82611c40565b9050919050565b6000611d5e82611c60565b9050919050565b611d6f8383611940565b611d7981836121c5565b611d82836118fc565b611d8b83611916565b6000805b84811015611dc457611da1848861186b565b611dac8184866125fa565b60208501945060028401935050600181019050611d8f565b5050505050505050565b611dd88383611961565b67ffffffffffffffff811115611df157611df061211b565b5b611dfb8254611fa8565b600080601f8411601f84111715611e1857611e158561192b565b90505b601f831115611e4b576020601f85010481016020851015611e37578190505b611e496020601f860104830182611c85565b505b601f841160018114611e785760008515611e66578388013590505b611e708682611fda565b875550611ed0565b601f1985168260005b82811015611ea657858a01358255600182019150602086019550602081019050611e81565b87831015611ec357858a0135611ebf601f8a1682612070565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b83811015611f07578082015181840152602081019050611eec565b83811115611f16576000848401525b50505050565b600081016000830180611f2e81612199565b9050611f3a8184612586565b5050506001810160208301611f4f81856117bd565b611f5a8183866125a9565b505050505050565b6000810160008301611f748185611814565b611f7f8183866125b9565b50505050600181016020830180611f95816121af565b9050611fa181846125d7565b5050505050565b60006002820490506001821680611fc057607f821691505b60208210811415611fd457611fd36120ec565b5b50919050565b6000611fe68383612070565b9150826002028217905092915050565b611fff8261227e565b810181811067ffffffffffffffff8211171561201e5761201d61211b565b5b80604052505050565b600061203282611c60565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612065576120646120bd565b5b600182019050919050565b6000612081600019846008026122a9565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61217a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff836020036008026122a9565b815481168255505050565b6000819050919050565b6000819050919050565b600081356121a68161263d565b80915050919050565b600081356121bc81612654565b80915050919050565b680100000000000000008211156121df576121de61211b565b5b6121e881611956565b82825580831015612224576121fc816118e5565b612205846118e5565b61220e84611916565b81810183820161221e8183611ca8565b50505050505b505050565b680100000000000000008211156122435761224261211b565b5b805461224e81611fa8565b808411156122635761226284828486611a78565b5b8084101561227857612277848284866119cf565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b600082146122c7576122c661208e565b5b6122d081611c77565b5050565b600082146122e5576122e461208e565b5b6122ee81611ced565b5050565b6122fa61266b565b612305818484612618565b505050565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f73747265616d20616c7265616479206861732061206450494400000000000000600082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b6124a48161192b565b6124af838254611fda565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff6124dc8461228f565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61251e8461228f565b9350801983169250808416831791505092915050565b6000600883026125647fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261229c565b61256e868361229c565b95508019841693508086168417925050509392505050565b61258f82611d0b565b6125a261259b82612185565b83546124bc565b8255505050565b6125b4838383611d65565b505050565b6125c4838383611dce565b505050565b6125d38282611f1c565b5050565b6125e082611d53565b6125f36125ec8261218f565b83546124f2565b8255505050565b81156126095761260861208e565b5b6126138382611f62565b505050565b61262183611d53565b61263561262d8261218f565b848454612534565b825550505050565b61264681611c2e565b811461265157600080fd5b50565b61265d81611c60565b811461266857600080fd5b50565b60009056fea2646970667358221220cb403f7adc2fb139c3c9359219d93f9c0d9a168b2bc26c7936cfd7429f94f50064736f6c63430008040033"; + "0x60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d3565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000127565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff161015620000ed5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e4919062000149565b60405180910390a15b565b6000620000fe60278362000166565b91506200010b8262000184565b604082019050919050565b620001218162000177565b82525050565b600060208201905081810360008301526200014281620000ef565b9050919050565b600060208201905062000160600083018462000116565b92915050565b600082825260208201905092915050565b600060ff82169050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b61281d80620001e36000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806382b7b500116100a2578063b9e2924111610071578063b9e29241146102cc578063cfb452b5146102ea578063ded8896b14610308578063f2fde38b14610324578063fe4b84df146103405761010b565b806382b7b500146102305780638da5cb5b14610260578063afc269111461027e578063b724de3a1461029c5761010b565b80635893253c116100de5780635893253c14610196578063715018a6146101c6578063788243d5146101d0578063810a9afa146102005761010b565b80630d70b3aa14610110578063144ae8551461011a5780634f896d4f14610136578063587a8cbf14610166575b600080fd5b61011861035c565b005b610134600480360381019061012f91906111f4565b610381565b005b610150600480360381019061014b9190611173565b61043f565b60405161015d919061173e565b60405180910390f35b610180600480360381019061017b9190611132565b6104e4565b60405161018d9190611882565b60405180910390f35b6101b060048036038101906101ab9190611173565b610512565b6040516101bd919061173e565b60405180910390f35b6101ce6105b2565b005b6101ea60048036038101906101e59190611173565b6105c6565b6040516101f791906116ed565b60405180910390f35b61021a60048036038101906102159190611173565b610604565b6040516102279190611860565b60405180910390f35b61024a600480360381019061024591906110ed565b610782565b6040516102579190611882565b60405180910390f35b6102686107ad565b60405161027591906116ed565b60405180910390f35b6102866107d7565b6040516102939190611882565b60405180910390f35b6102b660048036038101906102b191906110ed565b6107dd565b6040516102c39190611882565b60405180910390f35b6102d46108f2565b6040516102e19190611708565b60405180910390f35b6102f2610905565b6040516102ff9190611882565b60405180910390f35b610322600480360381019061031d919061119c565b61090b565b005b61033e600480360381019061033991906110c4565b610b00565b005b61035a60048036038101906103559190611173565b610b84565b005b610364610cd1565b6001606760006101000a81548160ff021916908315150217905550565b610389610cd1565b60001515606760009054906101000a900460ff161515146103df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103d6906117a0565b60405180910390fd5b80606a600084815260200190815260200160002081816103ff9190612740565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada82826040516104339291906118cf565b60405180910390a15050565b606060686000838152602001908152602001600020805461045f906120f6565b80601f016020809104026020016040519081016040528092919081815260200182805461048b906120f6565b80156104d85780601f106104ad576101008083540402835291602001916104d8565b820191906000526020600020905b8154815290600101906020018083116104bb57829003601f168201915b50505050509050919050565b6069818051602081018201805184825260208301602085012081835280955050505050506000915090505481565b60686020528060005260406000206000915090508054610531906120f6565b80601f016020809104026020016040519081016040528092919081815260200182805461055d906120f6565b80156105aa5780601f1061057f576101008083540402835291602001916105aa565b820191906000526020600020905b81548152906001019060200180831161058d57829003601f168201915b505050505081565b6105ba610cd1565b6105c46000610d4f565b565b606a6020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b61060c610efa565b606a60008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b8282101561077357838290600052602060002090600202016040518060400160405290816000820180546106d8906120f6565b80601f0160208091040260200160405190810160405280929190818152602001828054610704906120f6565b80156107515780601f1061072657610100808354040283529160200191610751565b820191906000526020600020905b81548152906001019060200180831161073457829003601f168201915b50505050508152602001600182015481525050815260200190600101906106a5565b50505050815250509050919050565b6000606983836040516107969291906116d4565b908152602001604051809103902054905092915050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60665481565b600082826000606983836040516107f59291906116d4565b90815260200160405180910390205414610844576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161083b906117c0565b60405180910390fd5b60006066549050858560686000848152602001908152602001600020919061086d929190610f2a565b5080606987876040516108819291906116d4565b9081526020016040518091039020819055507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d8187876040516108c69392919061189d565b60405180910390a1606660008154809291906108e190612175565b919050555080935050505092915050565b606760009054906101000a900460ff1681565b60655481565b81816000606983836040516109219291906116d4565b90815260200160405180910390205414610970576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610967906117c0565b60405180910390fd5b6000606860008781526020019081526020016000208054610990906120f6565b9050146109d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109c990611760565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16606a600087815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610a76576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6d90611840565b60405180910390fd5b8383606860008881526020019081526020016000209190610a98929190610f2a565b508460698585604051610aac9291906116d4565b9081526020016040518091039020819055507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c858585604051610af19392919061189d565b60405180910390a15050505050565b610b08610cd1565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610b78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b6f90611780565b60405180910390fd5b610b8181610d4f565b50565b60008060019054906101000a900460ff16159050808015610bb55750600160008054906101000a900460ff1660ff16105b80610be25750610bc430610e15565b158015610be15750600160008054906101000a900460ff1660ff16145b5b610c21576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c18906117e0565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015610c5e576001600060016101000a81548160ff0219169083151502179055505b610c66610e38565b81606581905550816066819055508015610ccd5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024986001604051610cc49190611723565b60405180910390a15b5050565b610cd9610e91565b73ffffffffffffffffffffffffffffffffffffffff16610cf76107ad565b73ffffffffffffffffffffffffffffffffffffffff1614610d4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d4490611800565b60405180910390fd5b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610e87576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e7e90611820565b60405180910390fd5b610e8f610e99565b565b600033905090565b600060019054906101000a900460ff16610ee8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610edf90611820565b60405180910390fd5b610ef8610ef3610e91565b610d4f565b565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b828054610f36906120f6565b90600052602060002090601f016020900481019282610f585760008555610f9f565b82601f10610f7157803560ff1916838001178555610f9f565b82800160010185558215610f9f579182015b82811115610f9e578235825591602001919060010190610f83565b5b509050610fac9190610fb0565b5090565b5b80821115610fc9576000816000905550600101610fb1565b5090565b6000610fe0610fdb846119f6565b6119d1565b905082815260208101848484011115610ff857600080fd5b611003848285612028565b509392505050565b60008135905061101a816127b4565b92915050565b60008083601f84011261103257600080fd5b8235905067ffffffffffffffff81111561104b57600080fd5b60208301915083600182028301111561106357600080fd5b9250929050565b600082601f83011261107b57600080fd5b813561108b848260208601610fcd565b91505092915050565b6000604082840312156110a657600080fd5b81905092915050565b6000813590506110be816127cb565b92915050565b6000602082840312156110d657600080fd5b60006110e48482850161100b565b91505092915050565b6000806020838503121561110057600080fd5b600083013567ffffffffffffffff81111561111a57600080fd5b61112685828601611020565b92509250509250929050565b60006020828403121561114457600080fd5b600082013567ffffffffffffffff81111561115e57600080fd5b61116a8482850161106a565b91505092915050565b60006020828403121561118557600080fd5b6000611193848285016110af565b91505092915050565b6000806000604084860312156111b157600080fd5b60006111bf868287016110af565b935050602084013567ffffffffffffffff8111156111dc57600080fd5b6111e886828701611020565b92509250509250925092565b6000806040838503121561120757600080fd5b6000611215858286016110af565b925050602083013567ffffffffffffffff81111561123257600080fd5b61123e85828601611094565b9150509250929050565b6000611254838361162a565b905092915050565b60006112688383611679565b905092915050565b61127981611d70565b82525050565b61128881611d70565b82525050565b600061129a8385611ad3565b9350836020840285016112ac84611a3e565b8060005b878110156112f05784840389526112c78284611cdb565b6112d18582611248565b94506112dc83611ab9565b925060208a019950506001810190506112b0565b50829750879450505050509392505050565b600061130d82611a8d565b6113178185611ad3565b93508360208202850161132985611a48565b8060005b858110156113655784840389528151611346858261125c565b945061135183611ac6565b925060208a0199505060018101905061132d565b50829750879550505050505092915050565b61138081611d82565b82525050565b61138f81611e6b565b82525050565b60006113a18385611ae4565b93506113ae838584612028565b6113b7836123cc565b840190509392505050565b60006113ce8385611af5565b93506113db838584612028565b6113e4836123cc565b840190509392505050565b60006113fb8385611b06565b9350611408838584612028565b82840190509392505050565b600061141f82611aae565b6114298185611ae4565b9350611439818560208601612037565b611442816123cc565b840191505092915050565b600061145882611aae565b6114628185611af5565b9350611472818560208601612037565b61147b816123cc565b840191505092915050565b6000611493601583611af5565b915061149e82612458565b602082019050919050565b60006114b6602683611af5565b91506114c182612481565b604082019050919050565b60006114d9601383611af5565b91506114e4826124d0565b602082019050919050565b60006114fc601983611af5565b9150611507826124f9565b602082019050919050565b600061151f602e83611af5565b915061152a82612522565b604082019050919050565b6000611542602083611af5565b915061154d82612571565b602082019050919050565b6000611565602b83611af5565b91506115708261259a565b604082019050919050565b6000611588601983611af5565b9150611593826125e9565b602082019050919050565b6000604083016115b16000840184611c16565b6115be6000860182611270565b506115cc6020840184611c2d565b85830360208701526115df83828461128e565b925050508091505092915050565b60006040830160008301516116056000860182611270565b506020830151848203602086015261161d8282611302565b9150508091505092915050565b60006040830161163d6000840184611c84565b8583036000870152611650838284611395565b925050506116616020840184611cff565b61166e60208601826116b6565b508091505092915050565b600060408301600083015184820360008601526116968282611414565b91505060208301516116ab60208601826116b6565b508091505092915050565b6116bf81611dae565b82525050565b6116ce81611dae565b82525050565b60006116e18284866113ef565b91508190509392505050565b6000602082019050611702600083018461127f565b92915050565b600060208201905061171d6000830184611377565b92915050565b60006020820190506117386000830184611386565b92915050565b60006020820190508181036000830152611758818461144d565b905092915050565b6000602082019050818103600083015261177981611486565b9050919050565b60006020820190508181036000830152611799816114a9565b9050919050565b600060208201905081810360008301526117b9816114cc565b9050919050565b600060208201905081810360008301526117d9816114ef565b9050919050565b600060208201905081810360008301526117f981611512565b9050919050565b6000602082019050818103600083015261181981611535565b9050919050565b6000602082019050818103600083015261183981611558565b9050919050565b600060208201905081810360008301526118598161157b565b9050919050565b6000602082019050818103600083015261187a81846115ed565b905092915050565b600060208201905061189760008301846116c5565b92915050565b60006040820190506118b260008301866116c5565b81810360208301526118c58184866113c2565b9050949350505050565b60006040820190506118e460008301856116c5565b81810360208301526118f6818461159e565b90509392505050565b6000808335600160200384360303811261191857600080fd5b80840192508235915067ffffffffffffffff82111561193657600080fd5b60208301925060208202360383131561194e57600080fd5b509250929050565b6000808335600160200384360303811261196f57600080fd5b80840192508235915067ffffffffffffffff82111561198d57600080fd5b6020830192506001820236038313156119a557600080fd5b509250929050565b6000823560016040038336030381126119c557600080fd5b80830191505092915050565b60006119db6119ec565b90506119e78282612144565b919050565b6000604051905090565b600067ffffffffffffffff821115611a1157611a10612269565b5b611a1a826123cc565b9050602081019050919050565b6000819050611a37826002611d16565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6020841060008114611b6a57601f841160018114611b3a57611b338685612128565b8355611b64565b611b4383611a6d565b611b586020601f880104820160018301611dd3565b611b628785612612565b505b50611bb3565b611b7382611a6d565b6020601f8701048101601f87168015611b9457611b938160018403612298565b5b611ba66020601f890104840183611dd3565b6001886002021785555050505b5050505050565b6020831060008114611c05576020851060008114611be357611bdc8685612128565b8355611bff565b8360ff1916935083611bf484611a6d565b556001866002020183555b50611c0f565b6001856002020182555b5050505050565b6000611c25602084018461100b565b905092915050565b60008083356001602003843603038112611c4657600080fd5b83810192508235915060208301925067ffffffffffffffff821115611c6a57600080fd5b602082023603841315611c7c57600080fd5b509250929050565b60008083356001602003843603038112611c9d57600080fd5b83810192508235915060208301925067ffffffffffffffff821115611cc157600080fd5b600182023603841315611cd357600080fd5b509250929050565b600082356001604003833603038112611cf357600080fd5b82810191505092915050565b6000611d0e60208401846110af565b905092915050565b6000611d2182611dae565b9150611d2c83611dae565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611d6557611d6461220b565b5b828202905092915050565b6000611d7b82611d8e565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b611dd0600082612377565b50565b5b81811015611df257611de7600082612440565b600181019050611dd4565b5050565b5b81811015611e1557611e0a600082612422565b600281019050611df7565b5050565b81811015611e3757611e2c600082612440565b600181019050611e19565b5050565b611e486000808301612404565b611e56600060018301612440565b50565b6000611e6482611e7d565b9050919050565b6000611e7682611db8565b9050919050565b6000611e8882611e8f565b9050919050565b6000611e9a82611d8e565b9050919050565b6000611eac82611dae565b9050919050565b611ebd8383611a82565b611ec78183612313565b611ed083611a3e565b611ed983611a58565b6000805b84811015611f1257611eef84886119ad565b611efa818486612771565b60208501945060028401935050600181019050611edd565b5050505050505050565b611f268383611aa3565b67ffffffffffffffff811115611f3f57611f3e612269565b5b611f4982546120f6565b600080601f8411601f84111715611f6657611f6385611a6d565b90505b601f831115611f99576020601f85010481016020851015611f85578190505b611f976020601f860104830182611dd3565b505b601f841160018114611fc65760008515611fb4578388013590505b611fbe8682612128565b87555061201e565b601f1985168260005b82811015611ff457858a01358255600182019150602086019550602081019050611fcf565b8783101561201157858a013561200d601f8a16826121be565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b8381101561205557808201518184015260208101905061203a565b83811115612064576000848401525b50505050565b60008101600083018061207c816122e7565b905061208881846126fd565b505050600181016020830161209d81856118ff565b6120a8818386612720565b505050505050565b60008101600083016120c28185611956565b6120cd818386612730565b505050506001810160208301806120e3816122fd565b90506120ef818461274e565b5050505050565b6000600282049050600182168061210e57607f821691505b602082108114156121225761212161223a565b5b50919050565b600061213483836121be565b9150826002028217905092915050565b61214d826123cc565b810181811067ffffffffffffffff8211171561216c5761216b612269565b5b80604052505050565b600061218082611dae565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156121b3576121b261220b565b5b600182019050919050565b60006121cf600019846008026123f7565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6122c87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff836020036008026123f7565b815481168255505050565b6000819050919050565b6000819050919050565b600081356122f4816127b4565b80915050919050565b6000813561230a816127cb565b80915050919050565b6801000000000000000082111561232d5761232c612269565b5b61233681611a98565b828255808310156123725761234a81611a27565b61235384611a27565b61235c84611a58565b81810183820161236c8183611df6565b50505050505b505050565b6801000000000000000082111561239157612390612269565b5b805461239c816120f6565b808411156123b1576123b084828486611bba565b5b808410156123c6576123c584828486611b11565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b60008214612415576124146121dc565b5b61241e81611dc5565b5050565b60008214612433576124326121dc565b5b61243c81611e3b565b5050565b6124486127e2565b61245381848461278f565b505050565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f6d6967726174696f6e2069732066726f7a656e00000000000000000000000000600082015250565b7f73747265616d20616c7265616479206861732061206450494400000000000000600082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b61261b81611a6d565b612626838254612128565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff612653846123dd565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612695846123dd565b9350801983169250808416831791505092915050565b6000600883026126db7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826123ea565b6126e586836123ea565b95508019841693508086168417925050509392505050565b61270682611e59565b612719612712826122d3565b8354612633565b8255505050565b61272b838383611eb3565b505050565b61273b838383611f1c565b505050565b61274a828261206a565b5050565b61275782611ea1565b61276a612763826122dd565b8354612669565b8255505050565b81156127805761277f6121dc565b5b61278a83826120b0565b505050565b61279883611ea1565b6127ac6127a4826122dd565b8484546126ab565b825550505050565b6127bd81611d70565b81146127c857600080fd5b50565b6127d481611dae565b81146127df57600080fd5b50565b60009056fea26469706673582212203cd9493558aa831bec9e62a003cae25d442665c9c02edcb7c1725ad3e5bb65db64736f6c63430008040033"; type DpidAliasRegistryConstructorParams = | [signer?: Signer] From 6d81cfdf20028cfc343396f4a638d96cc173a17e Mon Sep 17 00:00:00 2001 From: m0ar Date: Fri, 31 May 2024 12:03:34 +0200 Subject: [PATCH 121/278] server: add createDpid route and controller --- desci-server/.gitignore | 2 +- desci-server/package.json | 3 +- .../src/controllers/nodes/createDpid.ts | 99 +++++++++++++++++++ desci-server/src/routes/v1/nodes.ts | 2 + desci-server/yarn.lock | 36 ++----- 5 files changed, 112 insertions(+), 30 deletions(-) create mode 100644 desci-server/src/controllers/nodes/createDpid.ts diff --git a/desci-server/.gitignore b/desci-server/.gitignore index cff213f0..e9b57f85 100755 --- a/desci-server/.gitignore +++ b/desci-server/.gitignore @@ -15,4 +15,4 @@ server.log repo-tmp -queries.sql \ No newline at end of file +queries.sql diff --git a/desci-server/package.json b/desci-server/package.json index bf462d4f..d346ff25 100755 --- a/desci-server/package.json +++ b/desci-server/package.json @@ -56,6 +56,7 @@ "@automerge/automerge-repo-network-websocket": "^1.0.19", "@aws-sdk/client-s3": "^3.537.0", "@desci-labs/desci-models": "0.2.7-rc3", + "@desci-labs/desci-contracts": "0.2.5-rc3", "@honeycombio/opentelemetry-node": "^0.3.2", "@ipld/dag-pb": "^4.0.0", "@opentelemetry/api": "^1.8.0", @@ -174,4 +175,4 @@ "prisma": { "seed": "node --no-warnings=ExperimentalWarning --loader ts-node/esm prisma/seed.ts" } -} \ No newline at end of file +} diff --git a/desci-server/src/controllers/nodes/createDpid.ts b/desci-server/src/controllers/nodes/createDpid.ts new file mode 100644 index 00000000..84c82808 --- /dev/null +++ b/desci-server/src/controllers/nodes/createDpid.ts @@ -0,0 +1,99 @@ +import { Response } from "express"; +import { ethers } from "ethers"; +import { logger as parentLogger } from '../../logger.js'; +import { RequestWithNode } from "../../middleware/authorisation.js"; +import { contracts, typechain as tc } from "@desci-labs/desci-contracts"; +import { DpidMintedEvent } from "@desci-labs/desci-contracts/dist/typechain-types/DpidAliasRegistry.js"; + +type DpidResponse = DpidSuccessResponse | DpidErrorResponse; +export type DpidSuccessResponse = { + dpid: number; +}; + +export type DpidErrorResponse = { + error: string; +}; + +/** Not secret: pre-seeded ganache account for local dev */ +const GANACHE_PKEY = "59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d"; + +let aliasRegistryAddress: string; +const url = process.env.SERVER_URL; + +if (url.includes("localhost")) { + aliasRegistryAddress = contracts.localDpidAliasInfo.proxies.at(0).address; +} else if (url.includes("dev") || url.includes("staging")) { + aliasRegistryAddress = contracts.devDpidAliasInfo.proxies.at(0).address; +} else if (process.env.NODE_ENV === "production") { + aliasRegistryAddress = contracts.prodDpidAliasInfo.proxies.at(0).address; +}; + +export const createDpid = async (req: RequestWithNode, res: Response) => { + const owner = req.user; + const node = req.node; + const { uuid } = req.body; + + const logger = parentLogger.child({ + module: "NODE::createDpidController", + body: req.body, + uuid, + user: owner, + ceramicStream: node.ceramicStream, + }); + + if (!uuid) { + return res.status(400).json({ error: "UUID is required" }); + }; + + if (!process.env.HOT_WALLET_KEY) { + logger.error("hot wallet not configured"); + return res.status(500).json({ error: "dpid registration not available" }); + }; + + if (!process.env.ETHEREUM_RPC_URL) { + logger.error("ethereum RPC endpoint not configured"); + return res.status(500).json({ error: "dpid registration not available" }); + }; + + try { + debugger; + const provider = new ethers.providers.JsonRpcProvider( + process.env.ETHEREUM_RPC_URL + ); + + await provider.ready; + const wallet = new ethers.Wallet( + url.includes("localhost") ? GANACHE_PKEY : process.env.HOT_WALLET_KEY, + provider, + ); + + const dpidAliasRegistry = tc.DpidAliasRegistry__factory.connect( + aliasRegistryAddress, + wallet, + ); + + const derp = await dpidAliasRegistry.owner(); + console.log("owner:", derp); + const hasDpid = await dpidAliasRegistry.find(node.ceramicStream); + + if (ethers.BigNumber.from(hasDpid).toNumber() !== 0) { + return res.status(400).json({ + error: `stream already has dPID: ${node.ceramicStream}`, + }); + }; + + const tx = await dpidAliasRegistry.mintDpid(node.ceramicStream); + const receipt = await tx.wait(); + const { args: [dpidBn, streamID] }= receipt.events[0] as DpidMintedEvent; + const dpid = ethers.BigNumber.from(dpidBn).toNumber(); + + logger.info( + `Created dPID alias ${dpid} for stream ${streamID}`, + ); + + return res.status(200).send({ dpid }); + } catch (err) { + logger.error({ err }, "node-create-dpid-err"); + return res.status(400).send({ error: err.message }); + }; +}; diff --git a/desci-server/src/routes/v1/nodes.ts b/desci-server/src/routes/v1/nodes.ts index 57268d9d..85d487eb 100755 --- a/desci-server/src/routes/v1/nodes.ts +++ b/desci-server/src/routes/v1/nodes.ts @@ -41,11 +41,13 @@ import { versionDetails } from '../../controllers/nodes/versionDetails.js'; import { asyncHander, attachUser, validate } from '../../internal.js'; import { ensureNodeAccess, ensureWriteNodeAccess } from '../../middleware/authorisation.js'; import { ensureUser } from '../../middleware/permissions.js'; +import { createDpid } from '../../controllers/nodes/createDpid.js'; const router = Router(); router.post('/prepublish', [ensureUser, ensureNodeAccess], prepublish); router.post('/publish', [ensureUser], publish); +router.post('/createDpid', [ensureUser, ensureWriteNodeAccess], createDpid); router.post('/createDraft', [ensureUser], draftCreate); // is this api deprecated? router.post('/addComponentToDraft', [ensureUser], draftAddComponent); diff --git a/desci-server/yarn.lock b/desci-server/yarn.lock index 7357a32d..68750092 100644 --- a/desci-server/yarn.lock +++ b/desci-server/yarn.lock @@ -1635,6 +1635,11 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" +"@desci-labs/desci-contracts@0.2.5-rc3": + version "0.2.5-rc3" + resolved "https://registry.yarnpkg.com/@desci-labs/desci-contracts/-/desci-contracts-0.2.5-rc3.tgz#bd9f0b221bf4df295855a50853f35161ce6d066e" + integrity sha512-+b0TTZCZjceCw5DuVqCxu9LlkHBMvF5PHw2Q/5N+cuveb2YMtPcj+TlVAEfsi+HcgAiagqaUKWI9903Kf8X1IA== + "@desci-labs/desci-models@0.2.7-rc3": version "0.2.7-rc3" resolved "https://registry.yarnpkg.com/@desci-labs/desci-models/-/desci-models-0.2.7-rc3.tgz#b033073e6b77edde85491731d5c03469f443aaa1" @@ -12850,16 +12855,7 @@ string-template@~0.2.1: resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" integrity sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw== -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -12932,7 +12928,7 @@ stringify-object@3.3.0: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -12946,13 +12942,6 @@ strip-ansi@^3.0.0: dependencies: ansi-regex "^2.0.0" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^7.0.1: version "7.1.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" @@ -13832,7 +13821,7 @@ workerpool@6.2.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -13850,15 +13839,6 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" From a64002dde2460c2829c6217751a27333d6380384 Mon Sep 17 00:00:00 2001 From: m0ar Date: Fri, 31 May 2024 15:37:20 +0200 Subject: [PATCH 122/278] contracts: make alias registry pausable, redesign contract setup steps --- desci-contracts/.gitignore | 1 + .../PausableUpgradeable.json | 63 +++++++++ .../DpidAliasRegistry.json | 91 +++++++++--- .../contracts/DpidAliasRegistry.sol | 46 ++++-- .../scripts/deployDpidAliasRegistry.js | 10 +- desci-contracts/test/DpidAliasRegistry.ts | 45 ++++-- .../typechain-types/DpidAliasRegistry.ts | 133 +++++++++++++++--- .../typechain-types/PausableUpgradeable.ts | 105 ++++++++++++++ .../factories/DpidAliasRegistry__factory.ts | 89 +++++++++--- .../factories/PausableUpgradeable__factory.ts | 78 ++++++++++ desci-contracts/typechain-types/hardhat.d.ts | 9 ++ desci-contracts/typechain-types/index.ts | 2 + 12 files changed, 580 insertions(+), 92 deletions(-) create mode 100644 desci-contracts/artifacts/@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol/PausableUpgradeable.json create mode 100644 desci-contracts/typechain-types/PausableUpgradeable.ts create mode 100644 desci-contracts/typechain-types/factories/PausableUpgradeable__factory.ts diff --git a/desci-contracts/.gitignore b/desci-contracts/.gitignore index d3767f7d..7b4e3512 100644 --- a/desci-contracts/.gitignore +++ b/desci-contracts/.gitignore @@ -12,3 +12,4 @@ build *.dbg.json flat.sol dist +.vscode \ No newline at end of file diff --git a/desci-contracts/artifacts/@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol/PausableUpgradeable.json b/desci-contracts/artifacts/@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol/PausableUpgradeable.json new file mode 100644 index 00000000..4bc1f5ee --- /dev/null +++ b/desci-contracts/artifacts/@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol/PausableUpgradeable.json @@ -0,0 +1,63 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "PausableUpgradeable", + "sourceName": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x", + "deployedBytecode": "0x", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/desci-contracts/artifacts/contracts/DpidAliasRegistry.sol/DpidAliasRegistry.json b/desci-contracts/artifacts/contracts/DpidAliasRegistry.sol/DpidAliasRegistry.json index 9aed9232..842f1f8f 100644 --- a/desci-contracts/artifacts/contracts/DpidAliasRegistry.sol/DpidAliasRegistry.json +++ b/desci-contracts/artifacts/contracts/DpidAliasRegistry.sol/DpidAliasRegistry.json @@ -102,6 +102,32 @@ "name": "OwnershipTransferred", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -140,19 +166,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [], - "name": "firstDpid", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [], "name": "freezeMigration", @@ -203,13 +216,7 @@ "type": "function" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "_firstDpid", - "type": "uint256" - } - ], + "inputs": [], "name": "initialize", "outputs": [], "stateMutability": "nonpayable", @@ -335,6 +342,26 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -399,6 +426,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_nextDpid", + "type": "uint256" + } + ], + "name": "setNextDpid", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -412,6 +452,13 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -431,8 +478,8 @@ "type": "function" } ], - "bytecode": "0x60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d3565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000127565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff161015620000ed5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e4919062000149565b60405180910390a15b565b6000620000fe60278362000166565b91506200010b8262000184565b604082019050919050565b620001218162000177565b82525050565b600060208201905081810360008301526200014281620000ef565b9050919050565b600060208201905062000160600083018462000116565b92915050565b600082825260208201905092915050565b600060ff82169050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b61281d80620001e36000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806382b7b500116100a2578063b9e2924111610071578063b9e29241146102cc578063cfb452b5146102ea578063ded8896b14610308578063f2fde38b14610324578063fe4b84df146103405761010b565b806382b7b500146102305780638da5cb5b14610260578063afc269111461027e578063b724de3a1461029c5761010b565b80635893253c116100de5780635893253c14610196578063715018a6146101c6578063788243d5146101d0578063810a9afa146102005761010b565b80630d70b3aa14610110578063144ae8551461011a5780634f896d4f14610136578063587a8cbf14610166575b600080fd5b61011861035c565b005b610134600480360381019061012f91906111f4565b610381565b005b610150600480360381019061014b9190611173565b61043f565b60405161015d919061173e565b60405180910390f35b610180600480360381019061017b9190611132565b6104e4565b60405161018d9190611882565b60405180910390f35b6101b060048036038101906101ab9190611173565b610512565b6040516101bd919061173e565b60405180910390f35b6101ce6105b2565b005b6101ea60048036038101906101e59190611173565b6105c6565b6040516101f791906116ed565b60405180910390f35b61021a60048036038101906102159190611173565b610604565b6040516102279190611860565b60405180910390f35b61024a600480360381019061024591906110ed565b610782565b6040516102579190611882565b60405180910390f35b6102686107ad565b60405161027591906116ed565b60405180910390f35b6102866107d7565b6040516102939190611882565b60405180910390f35b6102b660048036038101906102b191906110ed565b6107dd565b6040516102c39190611882565b60405180910390f35b6102d46108f2565b6040516102e19190611708565b60405180910390f35b6102f2610905565b6040516102ff9190611882565b60405180910390f35b610322600480360381019061031d919061119c565b61090b565b005b61033e600480360381019061033991906110c4565b610b00565b005b61035a60048036038101906103559190611173565b610b84565b005b610364610cd1565b6001606760006101000a81548160ff021916908315150217905550565b610389610cd1565b60001515606760009054906101000a900460ff161515146103df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103d6906117a0565b60405180910390fd5b80606a600084815260200190815260200160002081816103ff9190612740565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada82826040516104339291906118cf565b60405180910390a15050565b606060686000838152602001908152602001600020805461045f906120f6565b80601f016020809104026020016040519081016040528092919081815260200182805461048b906120f6565b80156104d85780601f106104ad576101008083540402835291602001916104d8565b820191906000526020600020905b8154815290600101906020018083116104bb57829003601f168201915b50505050509050919050565b6069818051602081018201805184825260208301602085012081835280955050505050506000915090505481565b60686020528060005260406000206000915090508054610531906120f6565b80601f016020809104026020016040519081016040528092919081815260200182805461055d906120f6565b80156105aa5780601f1061057f576101008083540402835291602001916105aa565b820191906000526020600020905b81548152906001019060200180831161058d57829003601f168201915b505050505081565b6105ba610cd1565b6105c46000610d4f565b565b606a6020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b61060c610efa565b606a60008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b8282101561077357838290600052602060002090600202016040518060400160405290816000820180546106d8906120f6565b80601f0160208091040260200160405190810160405280929190818152602001828054610704906120f6565b80156107515780601f1061072657610100808354040283529160200191610751565b820191906000526020600020905b81548152906001019060200180831161073457829003601f168201915b50505050508152602001600182015481525050815260200190600101906106a5565b50505050815250509050919050565b6000606983836040516107969291906116d4565b908152602001604051809103902054905092915050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60665481565b600082826000606983836040516107f59291906116d4565b90815260200160405180910390205414610844576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161083b906117c0565b60405180910390fd5b60006066549050858560686000848152602001908152602001600020919061086d929190610f2a565b5080606987876040516108819291906116d4565b9081526020016040518091039020819055507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d8187876040516108c69392919061189d565b60405180910390a1606660008154809291906108e190612175565b919050555080935050505092915050565b606760009054906101000a900460ff1681565b60655481565b81816000606983836040516109219291906116d4565b90815260200160405180910390205414610970576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610967906117c0565b60405180910390fd5b6000606860008781526020019081526020016000208054610990906120f6565b9050146109d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109c990611760565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16606a600087815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610a76576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6d90611840565b60405180910390fd5b8383606860008881526020019081526020016000209190610a98929190610f2a565b508460698585604051610aac9291906116d4565b9081526020016040518091039020819055507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c858585604051610af19392919061189d565b60405180910390a15050505050565b610b08610cd1565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610b78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b6f90611780565b60405180910390fd5b610b8181610d4f565b50565b60008060019054906101000a900460ff16159050808015610bb55750600160008054906101000a900460ff1660ff16105b80610be25750610bc430610e15565b158015610be15750600160008054906101000a900460ff1660ff16145b5b610c21576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c18906117e0565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015610c5e576001600060016101000a81548160ff0219169083151502179055505b610c66610e38565b81606581905550816066819055508015610ccd5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024986001604051610cc49190611723565b60405180910390a15b5050565b610cd9610e91565b73ffffffffffffffffffffffffffffffffffffffff16610cf76107ad565b73ffffffffffffffffffffffffffffffffffffffff1614610d4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d4490611800565b60405180910390fd5b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610e87576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e7e90611820565b60405180910390fd5b610e8f610e99565b565b600033905090565b600060019054906101000a900460ff16610ee8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610edf90611820565b60405180910390fd5b610ef8610ef3610e91565b610d4f565b565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b828054610f36906120f6565b90600052602060002090601f016020900481019282610f585760008555610f9f565b82601f10610f7157803560ff1916838001178555610f9f565b82800160010185558215610f9f579182015b82811115610f9e578235825591602001919060010190610f83565b5b509050610fac9190610fb0565b5090565b5b80821115610fc9576000816000905550600101610fb1565b5090565b6000610fe0610fdb846119f6565b6119d1565b905082815260208101848484011115610ff857600080fd5b611003848285612028565b509392505050565b60008135905061101a816127b4565b92915050565b60008083601f84011261103257600080fd5b8235905067ffffffffffffffff81111561104b57600080fd5b60208301915083600182028301111561106357600080fd5b9250929050565b600082601f83011261107b57600080fd5b813561108b848260208601610fcd565b91505092915050565b6000604082840312156110a657600080fd5b81905092915050565b6000813590506110be816127cb565b92915050565b6000602082840312156110d657600080fd5b60006110e48482850161100b565b91505092915050565b6000806020838503121561110057600080fd5b600083013567ffffffffffffffff81111561111a57600080fd5b61112685828601611020565b92509250509250929050565b60006020828403121561114457600080fd5b600082013567ffffffffffffffff81111561115e57600080fd5b61116a8482850161106a565b91505092915050565b60006020828403121561118557600080fd5b6000611193848285016110af565b91505092915050565b6000806000604084860312156111b157600080fd5b60006111bf868287016110af565b935050602084013567ffffffffffffffff8111156111dc57600080fd5b6111e886828701611020565b92509250509250925092565b6000806040838503121561120757600080fd5b6000611215858286016110af565b925050602083013567ffffffffffffffff81111561123257600080fd5b61123e85828601611094565b9150509250929050565b6000611254838361162a565b905092915050565b60006112688383611679565b905092915050565b61127981611d70565b82525050565b61128881611d70565b82525050565b600061129a8385611ad3565b9350836020840285016112ac84611a3e565b8060005b878110156112f05784840389526112c78284611cdb565b6112d18582611248565b94506112dc83611ab9565b925060208a019950506001810190506112b0565b50829750879450505050509392505050565b600061130d82611a8d565b6113178185611ad3565b93508360208202850161132985611a48565b8060005b858110156113655784840389528151611346858261125c565b945061135183611ac6565b925060208a0199505060018101905061132d565b50829750879550505050505092915050565b61138081611d82565b82525050565b61138f81611e6b565b82525050565b60006113a18385611ae4565b93506113ae838584612028565b6113b7836123cc565b840190509392505050565b60006113ce8385611af5565b93506113db838584612028565b6113e4836123cc565b840190509392505050565b60006113fb8385611b06565b9350611408838584612028565b82840190509392505050565b600061141f82611aae565b6114298185611ae4565b9350611439818560208601612037565b611442816123cc565b840191505092915050565b600061145882611aae565b6114628185611af5565b9350611472818560208601612037565b61147b816123cc565b840191505092915050565b6000611493601583611af5565b915061149e82612458565b602082019050919050565b60006114b6602683611af5565b91506114c182612481565b604082019050919050565b60006114d9601383611af5565b91506114e4826124d0565b602082019050919050565b60006114fc601983611af5565b9150611507826124f9565b602082019050919050565b600061151f602e83611af5565b915061152a82612522565b604082019050919050565b6000611542602083611af5565b915061154d82612571565b602082019050919050565b6000611565602b83611af5565b91506115708261259a565b604082019050919050565b6000611588601983611af5565b9150611593826125e9565b602082019050919050565b6000604083016115b16000840184611c16565b6115be6000860182611270565b506115cc6020840184611c2d565b85830360208701526115df83828461128e565b925050508091505092915050565b60006040830160008301516116056000860182611270565b506020830151848203602086015261161d8282611302565b9150508091505092915050565b60006040830161163d6000840184611c84565b8583036000870152611650838284611395565b925050506116616020840184611cff565b61166e60208601826116b6565b508091505092915050565b600060408301600083015184820360008601526116968282611414565b91505060208301516116ab60208601826116b6565b508091505092915050565b6116bf81611dae565b82525050565b6116ce81611dae565b82525050565b60006116e18284866113ef565b91508190509392505050565b6000602082019050611702600083018461127f565b92915050565b600060208201905061171d6000830184611377565b92915050565b60006020820190506117386000830184611386565b92915050565b60006020820190508181036000830152611758818461144d565b905092915050565b6000602082019050818103600083015261177981611486565b9050919050565b60006020820190508181036000830152611799816114a9565b9050919050565b600060208201905081810360008301526117b9816114cc565b9050919050565b600060208201905081810360008301526117d9816114ef565b9050919050565b600060208201905081810360008301526117f981611512565b9050919050565b6000602082019050818103600083015261181981611535565b9050919050565b6000602082019050818103600083015261183981611558565b9050919050565b600060208201905081810360008301526118598161157b565b9050919050565b6000602082019050818103600083015261187a81846115ed565b905092915050565b600060208201905061189760008301846116c5565b92915050565b60006040820190506118b260008301866116c5565b81810360208301526118c58184866113c2565b9050949350505050565b60006040820190506118e460008301856116c5565b81810360208301526118f6818461159e565b90509392505050565b6000808335600160200384360303811261191857600080fd5b80840192508235915067ffffffffffffffff82111561193657600080fd5b60208301925060208202360383131561194e57600080fd5b509250929050565b6000808335600160200384360303811261196f57600080fd5b80840192508235915067ffffffffffffffff82111561198d57600080fd5b6020830192506001820236038313156119a557600080fd5b509250929050565b6000823560016040038336030381126119c557600080fd5b80830191505092915050565b60006119db6119ec565b90506119e78282612144565b919050565b6000604051905090565b600067ffffffffffffffff821115611a1157611a10612269565b5b611a1a826123cc565b9050602081019050919050565b6000819050611a37826002611d16565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6020841060008114611b6a57601f841160018114611b3a57611b338685612128565b8355611b64565b611b4383611a6d565b611b586020601f880104820160018301611dd3565b611b628785612612565b505b50611bb3565b611b7382611a6d565b6020601f8701048101601f87168015611b9457611b938160018403612298565b5b611ba66020601f890104840183611dd3565b6001886002021785555050505b5050505050565b6020831060008114611c05576020851060008114611be357611bdc8685612128565b8355611bff565b8360ff1916935083611bf484611a6d565b556001866002020183555b50611c0f565b6001856002020182555b5050505050565b6000611c25602084018461100b565b905092915050565b60008083356001602003843603038112611c4657600080fd5b83810192508235915060208301925067ffffffffffffffff821115611c6a57600080fd5b602082023603841315611c7c57600080fd5b509250929050565b60008083356001602003843603038112611c9d57600080fd5b83810192508235915060208301925067ffffffffffffffff821115611cc157600080fd5b600182023603841315611cd357600080fd5b509250929050565b600082356001604003833603038112611cf357600080fd5b82810191505092915050565b6000611d0e60208401846110af565b905092915050565b6000611d2182611dae565b9150611d2c83611dae565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611d6557611d6461220b565b5b828202905092915050565b6000611d7b82611d8e565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b611dd0600082612377565b50565b5b81811015611df257611de7600082612440565b600181019050611dd4565b5050565b5b81811015611e1557611e0a600082612422565b600281019050611df7565b5050565b81811015611e3757611e2c600082612440565b600181019050611e19565b5050565b611e486000808301612404565b611e56600060018301612440565b50565b6000611e6482611e7d565b9050919050565b6000611e7682611db8565b9050919050565b6000611e8882611e8f565b9050919050565b6000611e9a82611d8e565b9050919050565b6000611eac82611dae565b9050919050565b611ebd8383611a82565b611ec78183612313565b611ed083611a3e565b611ed983611a58565b6000805b84811015611f1257611eef84886119ad565b611efa818486612771565b60208501945060028401935050600181019050611edd565b5050505050505050565b611f268383611aa3565b67ffffffffffffffff811115611f3f57611f3e612269565b5b611f4982546120f6565b600080601f8411601f84111715611f6657611f6385611a6d565b90505b601f831115611f99576020601f85010481016020851015611f85578190505b611f976020601f860104830182611dd3565b505b601f841160018114611fc65760008515611fb4578388013590505b611fbe8682612128565b87555061201e565b601f1985168260005b82811015611ff457858a01358255600182019150602086019550602081019050611fcf565b8783101561201157858a013561200d601f8a16826121be565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b8381101561205557808201518184015260208101905061203a565b83811115612064576000848401525b50505050565b60008101600083018061207c816122e7565b905061208881846126fd565b505050600181016020830161209d81856118ff565b6120a8818386612720565b505050505050565b60008101600083016120c28185611956565b6120cd818386612730565b505050506001810160208301806120e3816122fd565b90506120ef818461274e565b5050505050565b6000600282049050600182168061210e57607f821691505b602082108114156121225761212161223a565b5b50919050565b600061213483836121be565b9150826002028217905092915050565b61214d826123cc565b810181811067ffffffffffffffff8211171561216c5761216b612269565b5b80604052505050565b600061218082611dae565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156121b3576121b261220b565b5b600182019050919050565b60006121cf600019846008026123f7565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6122c87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff836020036008026123f7565b815481168255505050565b6000819050919050565b6000819050919050565b600081356122f4816127b4565b80915050919050565b6000813561230a816127cb565b80915050919050565b6801000000000000000082111561232d5761232c612269565b5b61233681611a98565b828255808310156123725761234a81611a27565b61235384611a27565b61235c84611a58565b81810183820161236c8183611df6565b50505050505b505050565b6801000000000000000082111561239157612390612269565b5b805461239c816120f6565b808411156123b1576123b084828486611bba565b5b808410156123c6576123c584828486611b11565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b60008214612415576124146121dc565b5b61241e81611dc5565b5050565b60008214612433576124326121dc565b5b61243c81611e3b565b5050565b6124486127e2565b61245381848461278f565b505050565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f6d6967726174696f6e2069732066726f7a656e00000000000000000000000000600082015250565b7f73747265616d20616c7265616479206861732061206450494400000000000000600082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b61261b81611a6d565b612626838254612128565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff612653846123dd565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612695846123dd565b9350801983169250808416831791505092915050565b6000600883026126db7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826123ea565b6126e586836123ea565b95508019841693508086168417925050509392505050565b61270682611e59565b612719612712826122d3565b8354612633565b8255505050565b61272b838383611eb3565b505050565b61273b838383611f1c565b505050565b61274a828261206a565b5050565b61275782611ea1565b61276a612763826122dd565b8354612669565b8255505050565b81156127805761277f6121dc565b5b61278a83826120b0565b505050565b61279883611ea1565b6127ac6127a4826122dd565b8484546126ab565b825550505050565b6127bd81611d70565b81146127c857600080fd5b50565b6127d481611dae565b81146127df57600080fd5b50565b60009056fea26469706673582212203cd9493558aa831bec9e62a003cae25d442665c9c02edcb7c1725ad3e5bb65db64736f6c63430008040033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061010b5760003560e01c806382b7b500116100a2578063b9e2924111610071578063b9e29241146102cc578063cfb452b5146102ea578063ded8896b14610308578063f2fde38b14610324578063fe4b84df146103405761010b565b806382b7b500146102305780638da5cb5b14610260578063afc269111461027e578063b724de3a1461029c5761010b565b80635893253c116100de5780635893253c14610196578063715018a6146101c6578063788243d5146101d0578063810a9afa146102005761010b565b80630d70b3aa14610110578063144ae8551461011a5780634f896d4f14610136578063587a8cbf14610166575b600080fd5b61011861035c565b005b610134600480360381019061012f91906111f4565b610381565b005b610150600480360381019061014b9190611173565b61043f565b60405161015d919061173e565b60405180910390f35b610180600480360381019061017b9190611132565b6104e4565b60405161018d9190611882565b60405180910390f35b6101b060048036038101906101ab9190611173565b610512565b6040516101bd919061173e565b60405180910390f35b6101ce6105b2565b005b6101ea60048036038101906101e59190611173565b6105c6565b6040516101f791906116ed565b60405180910390f35b61021a60048036038101906102159190611173565b610604565b6040516102279190611860565b60405180910390f35b61024a600480360381019061024591906110ed565b610782565b6040516102579190611882565b60405180910390f35b6102686107ad565b60405161027591906116ed565b60405180910390f35b6102866107d7565b6040516102939190611882565b60405180910390f35b6102b660048036038101906102b191906110ed565b6107dd565b6040516102c39190611882565b60405180910390f35b6102d46108f2565b6040516102e19190611708565b60405180910390f35b6102f2610905565b6040516102ff9190611882565b60405180910390f35b610322600480360381019061031d919061119c565b61090b565b005b61033e600480360381019061033991906110c4565b610b00565b005b61035a60048036038101906103559190611173565b610b84565b005b610364610cd1565b6001606760006101000a81548160ff021916908315150217905550565b610389610cd1565b60001515606760009054906101000a900460ff161515146103df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103d6906117a0565b60405180910390fd5b80606a600084815260200190815260200160002081816103ff9190612740565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada82826040516104339291906118cf565b60405180910390a15050565b606060686000838152602001908152602001600020805461045f906120f6565b80601f016020809104026020016040519081016040528092919081815260200182805461048b906120f6565b80156104d85780601f106104ad576101008083540402835291602001916104d8565b820191906000526020600020905b8154815290600101906020018083116104bb57829003601f168201915b50505050509050919050565b6069818051602081018201805184825260208301602085012081835280955050505050506000915090505481565b60686020528060005260406000206000915090508054610531906120f6565b80601f016020809104026020016040519081016040528092919081815260200182805461055d906120f6565b80156105aa5780601f1061057f576101008083540402835291602001916105aa565b820191906000526020600020905b81548152906001019060200180831161058d57829003601f168201915b505050505081565b6105ba610cd1565b6105c46000610d4f565b565b606a6020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b61060c610efa565b606a60008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b8282101561077357838290600052602060002090600202016040518060400160405290816000820180546106d8906120f6565b80601f0160208091040260200160405190810160405280929190818152602001828054610704906120f6565b80156107515780601f1061072657610100808354040283529160200191610751565b820191906000526020600020905b81548152906001019060200180831161073457829003601f168201915b50505050508152602001600182015481525050815260200190600101906106a5565b50505050815250509050919050565b6000606983836040516107969291906116d4565b908152602001604051809103902054905092915050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60665481565b600082826000606983836040516107f59291906116d4565b90815260200160405180910390205414610844576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161083b906117c0565b60405180910390fd5b60006066549050858560686000848152602001908152602001600020919061086d929190610f2a565b5080606987876040516108819291906116d4565b9081526020016040518091039020819055507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d8187876040516108c69392919061189d565b60405180910390a1606660008154809291906108e190612175565b919050555080935050505092915050565b606760009054906101000a900460ff1681565b60655481565b81816000606983836040516109219291906116d4565b90815260200160405180910390205414610970576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610967906117c0565b60405180910390fd5b6000606860008781526020019081526020016000208054610990906120f6565b9050146109d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109c990611760565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16606a600087815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610a76576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6d90611840565b60405180910390fd5b8383606860008881526020019081526020016000209190610a98929190610f2a565b508460698585604051610aac9291906116d4565b9081526020016040518091039020819055507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c858585604051610af19392919061189d565b60405180910390a15050505050565b610b08610cd1565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610b78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b6f90611780565b60405180910390fd5b610b8181610d4f565b50565b60008060019054906101000a900460ff16159050808015610bb55750600160008054906101000a900460ff1660ff16105b80610be25750610bc430610e15565b158015610be15750600160008054906101000a900460ff1660ff16145b5b610c21576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c18906117e0565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015610c5e576001600060016101000a81548160ff0219169083151502179055505b610c66610e38565b81606581905550816066819055508015610ccd5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024986001604051610cc49190611723565b60405180910390a15b5050565b610cd9610e91565b73ffffffffffffffffffffffffffffffffffffffff16610cf76107ad565b73ffffffffffffffffffffffffffffffffffffffff1614610d4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d4490611800565b60405180910390fd5b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610e87576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e7e90611820565b60405180910390fd5b610e8f610e99565b565b600033905090565b600060019054906101000a900460ff16610ee8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610edf90611820565b60405180910390fd5b610ef8610ef3610e91565b610d4f565b565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b828054610f36906120f6565b90600052602060002090601f016020900481019282610f585760008555610f9f565b82601f10610f7157803560ff1916838001178555610f9f565b82800160010185558215610f9f579182015b82811115610f9e578235825591602001919060010190610f83565b5b509050610fac9190610fb0565b5090565b5b80821115610fc9576000816000905550600101610fb1565b5090565b6000610fe0610fdb846119f6565b6119d1565b905082815260208101848484011115610ff857600080fd5b611003848285612028565b509392505050565b60008135905061101a816127b4565b92915050565b60008083601f84011261103257600080fd5b8235905067ffffffffffffffff81111561104b57600080fd5b60208301915083600182028301111561106357600080fd5b9250929050565b600082601f83011261107b57600080fd5b813561108b848260208601610fcd565b91505092915050565b6000604082840312156110a657600080fd5b81905092915050565b6000813590506110be816127cb565b92915050565b6000602082840312156110d657600080fd5b60006110e48482850161100b565b91505092915050565b6000806020838503121561110057600080fd5b600083013567ffffffffffffffff81111561111a57600080fd5b61112685828601611020565b92509250509250929050565b60006020828403121561114457600080fd5b600082013567ffffffffffffffff81111561115e57600080fd5b61116a8482850161106a565b91505092915050565b60006020828403121561118557600080fd5b6000611193848285016110af565b91505092915050565b6000806000604084860312156111b157600080fd5b60006111bf868287016110af565b935050602084013567ffffffffffffffff8111156111dc57600080fd5b6111e886828701611020565b92509250509250925092565b6000806040838503121561120757600080fd5b6000611215858286016110af565b925050602083013567ffffffffffffffff81111561123257600080fd5b61123e85828601611094565b9150509250929050565b6000611254838361162a565b905092915050565b60006112688383611679565b905092915050565b61127981611d70565b82525050565b61128881611d70565b82525050565b600061129a8385611ad3565b9350836020840285016112ac84611a3e565b8060005b878110156112f05784840389526112c78284611cdb565b6112d18582611248565b94506112dc83611ab9565b925060208a019950506001810190506112b0565b50829750879450505050509392505050565b600061130d82611a8d565b6113178185611ad3565b93508360208202850161132985611a48565b8060005b858110156113655784840389528151611346858261125c565b945061135183611ac6565b925060208a0199505060018101905061132d565b50829750879550505050505092915050565b61138081611d82565b82525050565b61138f81611e6b565b82525050565b60006113a18385611ae4565b93506113ae838584612028565b6113b7836123cc565b840190509392505050565b60006113ce8385611af5565b93506113db838584612028565b6113e4836123cc565b840190509392505050565b60006113fb8385611b06565b9350611408838584612028565b82840190509392505050565b600061141f82611aae565b6114298185611ae4565b9350611439818560208601612037565b611442816123cc565b840191505092915050565b600061145882611aae565b6114628185611af5565b9350611472818560208601612037565b61147b816123cc565b840191505092915050565b6000611493601583611af5565b915061149e82612458565b602082019050919050565b60006114b6602683611af5565b91506114c182612481565b604082019050919050565b60006114d9601383611af5565b91506114e4826124d0565b602082019050919050565b60006114fc601983611af5565b9150611507826124f9565b602082019050919050565b600061151f602e83611af5565b915061152a82612522565b604082019050919050565b6000611542602083611af5565b915061154d82612571565b602082019050919050565b6000611565602b83611af5565b91506115708261259a565b604082019050919050565b6000611588601983611af5565b9150611593826125e9565b602082019050919050565b6000604083016115b16000840184611c16565b6115be6000860182611270565b506115cc6020840184611c2d565b85830360208701526115df83828461128e565b925050508091505092915050565b60006040830160008301516116056000860182611270565b506020830151848203602086015261161d8282611302565b9150508091505092915050565b60006040830161163d6000840184611c84565b8583036000870152611650838284611395565b925050506116616020840184611cff565b61166e60208601826116b6565b508091505092915050565b600060408301600083015184820360008601526116968282611414565b91505060208301516116ab60208601826116b6565b508091505092915050565b6116bf81611dae565b82525050565b6116ce81611dae565b82525050565b60006116e18284866113ef565b91508190509392505050565b6000602082019050611702600083018461127f565b92915050565b600060208201905061171d6000830184611377565b92915050565b60006020820190506117386000830184611386565b92915050565b60006020820190508181036000830152611758818461144d565b905092915050565b6000602082019050818103600083015261177981611486565b9050919050565b60006020820190508181036000830152611799816114a9565b9050919050565b600060208201905081810360008301526117b9816114cc565b9050919050565b600060208201905081810360008301526117d9816114ef565b9050919050565b600060208201905081810360008301526117f981611512565b9050919050565b6000602082019050818103600083015261181981611535565b9050919050565b6000602082019050818103600083015261183981611558565b9050919050565b600060208201905081810360008301526118598161157b565b9050919050565b6000602082019050818103600083015261187a81846115ed565b905092915050565b600060208201905061189760008301846116c5565b92915050565b60006040820190506118b260008301866116c5565b81810360208301526118c58184866113c2565b9050949350505050565b60006040820190506118e460008301856116c5565b81810360208301526118f6818461159e565b90509392505050565b6000808335600160200384360303811261191857600080fd5b80840192508235915067ffffffffffffffff82111561193657600080fd5b60208301925060208202360383131561194e57600080fd5b509250929050565b6000808335600160200384360303811261196f57600080fd5b80840192508235915067ffffffffffffffff82111561198d57600080fd5b6020830192506001820236038313156119a557600080fd5b509250929050565b6000823560016040038336030381126119c557600080fd5b80830191505092915050565b60006119db6119ec565b90506119e78282612144565b919050565b6000604051905090565b600067ffffffffffffffff821115611a1157611a10612269565b5b611a1a826123cc565b9050602081019050919050565b6000819050611a37826002611d16565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6020841060008114611b6a57601f841160018114611b3a57611b338685612128565b8355611b64565b611b4383611a6d565b611b586020601f880104820160018301611dd3565b611b628785612612565b505b50611bb3565b611b7382611a6d565b6020601f8701048101601f87168015611b9457611b938160018403612298565b5b611ba66020601f890104840183611dd3565b6001886002021785555050505b5050505050565b6020831060008114611c05576020851060008114611be357611bdc8685612128565b8355611bff565b8360ff1916935083611bf484611a6d565b556001866002020183555b50611c0f565b6001856002020182555b5050505050565b6000611c25602084018461100b565b905092915050565b60008083356001602003843603038112611c4657600080fd5b83810192508235915060208301925067ffffffffffffffff821115611c6a57600080fd5b602082023603841315611c7c57600080fd5b509250929050565b60008083356001602003843603038112611c9d57600080fd5b83810192508235915060208301925067ffffffffffffffff821115611cc157600080fd5b600182023603841315611cd357600080fd5b509250929050565b600082356001604003833603038112611cf357600080fd5b82810191505092915050565b6000611d0e60208401846110af565b905092915050565b6000611d2182611dae565b9150611d2c83611dae565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611d6557611d6461220b565b5b828202905092915050565b6000611d7b82611d8e565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b611dd0600082612377565b50565b5b81811015611df257611de7600082612440565b600181019050611dd4565b5050565b5b81811015611e1557611e0a600082612422565b600281019050611df7565b5050565b81811015611e3757611e2c600082612440565b600181019050611e19565b5050565b611e486000808301612404565b611e56600060018301612440565b50565b6000611e6482611e7d565b9050919050565b6000611e7682611db8565b9050919050565b6000611e8882611e8f565b9050919050565b6000611e9a82611d8e565b9050919050565b6000611eac82611dae565b9050919050565b611ebd8383611a82565b611ec78183612313565b611ed083611a3e565b611ed983611a58565b6000805b84811015611f1257611eef84886119ad565b611efa818486612771565b60208501945060028401935050600181019050611edd565b5050505050505050565b611f268383611aa3565b67ffffffffffffffff811115611f3f57611f3e612269565b5b611f4982546120f6565b600080601f8411601f84111715611f6657611f6385611a6d565b90505b601f831115611f99576020601f85010481016020851015611f85578190505b611f976020601f860104830182611dd3565b505b601f841160018114611fc65760008515611fb4578388013590505b611fbe8682612128565b87555061201e565b601f1985168260005b82811015611ff457858a01358255600182019150602086019550602081019050611fcf565b8783101561201157858a013561200d601f8a16826121be565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b8381101561205557808201518184015260208101905061203a565b83811115612064576000848401525b50505050565b60008101600083018061207c816122e7565b905061208881846126fd565b505050600181016020830161209d81856118ff565b6120a8818386612720565b505050505050565b60008101600083016120c28185611956565b6120cd818386612730565b505050506001810160208301806120e3816122fd565b90506120ef818461274e565b5050505050565b6000600282049050600182168061210e57607f821691505b602082108114156121225761212161223a565b5b50919050565b600061213483836121be565b9150826002028217905092915050565b61214d826123cc565b810181811067ffffffffffffffff8211171561216c5761216b612269565b5b80604052505050565b600061218082611dae565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156121b3576121b261220b565b5b600182019050919050565b60006121cf600019846008026123f7565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6122c87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff836020036008026123f7565b815481168255505050565b6000819050919050565b6000819050919050565b600081356122f4816127b4565b80915050919050565b6000813561230a816127cb565b80915050919050565b6801000000000000000082111561232d5761232c612269565b5b61233681611a98565b828255808310156123725761234a81611a27565b61235384611a27565b61235c84611a58565b81810183820161236c8183611df6565b50505050505b505050565b6801000000000000000082111561239157612390612269565b5b805461239c816120f6565b808411156123b1576123b084828486611bba565b5b808410156123c6576123c584828486611b11565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b60008214612415576124146121dc565b5b61241e81611dc5565b5050565b60008214612433576124326121dc565b5b61243c81611e3b565b5050565b6124486127e2565b61245381848461278f565b505050565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f6d6967726174696f6e2069732066726f7a656e00000000000000000000000000600082015250565b7f73747265616d20616c7265616479206861732061206450494400000000000000600082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b61261b81611a6d565b612626838254612128565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff612653846123dd565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612695846123dd565b9350801983169250808416831791505092915050565b6000600883026126db7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826123ea565b6126e586836123ea565b95508019841693508086168417925050509392505050565b61270682611e59565b612719612712826122d3565b8354612633565b8255505050565b61272b838383611eb3565b505050565b61273b838383611f1c565b505050565b61274a828261206a565b5050565b61275782611ea1565b61276a612763826122dd565b8354612669565b8255505050565b81156127805761277f6121dc565b5b61278a83826120b0565b505050565b61279883611ea1565b6127ac6127a4826122dd565b8484546126ab565b825550505050565b6127bd81611d70565b81146127c857600080fd5b50565b6127d481611dae565b81146127df57600080fd5b50565b60009056fea26469706673582212203cd9493558aa831bec9e62a003cae25d442665c9c02edcb7c1725ad3e5bb65db64736f6c63430008040033", + "bytecode": "0x60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d3565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000127565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff161015620000ed5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e4919062000149565b60405180910390a15b565b6000620000fe60278362000166565b91506200010b8262000184565b604082019050919050565b620001218162000177565b82525050565b600060208201905081810360008301526200014281620000ef565b9050919050565b600060208201905062000160600083018462000116565b92915050565b600082825260208201905092915050565b600060ff82169050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b612bc280620001e36000396000f3fe608060405234801561001057600080fd5b506004361061012c5760003560e01c80638129fc1c116100ad578063afc2691111610071578063afc26911146102f7578063b724de3a14610315578063b9e2924114610345578063ded8896b14610363578063f2fde38b1461037f5761012c565b80638129fc1c1461027957806382b7b500146102835780638456cb59146102b35780638da5cb5b146102bd578063a5ad8ac6146102db5761012c565b80635893253c116100f45780635893253c146101c15780635c975abb146101f1578063715018a61461020f578063788243d514610219578063810a9afa146102495761012c565b80630d70b3aa14610131578063144ae8551461013b5780633f4ba83a146101575780634f896d4f14610161578063587a8cbf14610191575b600080fd5b61013961039b565b005b610155600480360381019061015091906114c1565b6103c0565b005b61015f61047e565b005b61017b60048036038101906101769190611440565b610498565b6040516101889190611a51565b60405180910390f35b6101ab60048036038101906101a691906113ff565b61053d565b6040516101b89190611bd5565b60405180910390f35b6101db60048036038101906101d69190611440565b61056b565b6040516101e89190611a51565b60405180910390f35b6101f961060b565b6040516102069190611a1b565b60405180910390f35b610217610622565b005b610233600480360381019061022e9190611440565b610636565b6040516102409190611a00565b60405180910390f35b610263600480360381019061025e9190611440565b610674565b6040516102709190611bb3565b60405180910390f35b6102816107f2565b005b61029d600480360381019061029891906113ba565b610940565b6040516102aa9190611bd5565b60405180910390f35b6102bb61096b565b005b6102c5610985565b6040516102d29190611a00565b60405180910390f35b6102f560048036038101906102f09190611440565b6109af565b005b6102ff6109c9565b60405161030c9190611bd5565b60405180910390f35b61032f600480360381019061032a91906113ba565b6109cf565b60405161033c9190611bd5565b60405180910390f35b61034d610aec565b60405161035a9190611a1b565b60405180910390f35b61037d60048036038101906103789190611469565b610aff565b005b61039960048036038101906103949190611391565b610cfc565b005b6103a3610d80565b6001609860006101000a81548160ff021916908315150217905550565b6103c8610d80565b60001515609860009054906101000a900460ff1615151461041e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041590611ad3565b60405180910390fd5b80609b6000848152602001908152602001600020818161043e9190612ae5565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada8282604051610472929190611c22565b60405180910390a15050565b610486610d80565b61048e610dfe565b610496610e47565b565b60606099600083815260200190815260200160002080546104b890612449565b80601f01602080910402602001604051908101604052809291908181526020018280546104e490612449565b80156105315780601f1061050657610100808354040283529160200191610531565b820191906000526020600020905b81548152906001019060200180831161051457829003601f168201915b50505050509050919050565b609a818051602081018201805184825260208301602085012081835280955050505050506000915090505481565b6099602052806000526040600020600091509050805461058a90612449565b80601f01602080910402602001604051908101604052809291908181526020018280546105b690612449565b80156106035780601f106105d857610100808354040283529160200191610603565b820191906000526020600020905b8154815290600101906020018083116105e657829003601f168201915b505050505081565b6000606560009054906101000a900460ff16905090565b61062a610d80565b6106346000610eaa565b565b609b6020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b61067c6111c7565b609b60008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b828210156107e3578382906000526020600020906002020160405180604001604052908160008201805461074890612449565b80601f016020809104026020016040519081016040528092919081815260200182805461077490612449565b80156107c15780601f10610796576101008083540402835291602001916107c1565b820191906000526020600020905b8154815290600101906020018083116107a457829003601f168201915b5050505050815260200160018201548152505081526020019060010190610715565b50505050815250509050919050565b60008060019054906101000a900460ff161590508080156108235750600160008054906101000a900460ff1660ff16105b80610850575061083230610f70565b15801561084f5750600160008054906101000a900460ff1660ff16145b5b61088f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161088690611b33565b60405180910390fd5b60016000806101000a81548160ff021916908360ff16021790555080156108cc576001600060016101000a81548160ff0219169083151502179055505b6108d4610f93565b6108dc610fec565b6108e4611045565b801561093d5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516109349190611a36565b60405180910390a15b50565b6000609a83836040516109549291906119e7565b908152602001604051809103902054905092915050565b610973610d80565b61097b6110a8565b610983611045565b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6109b7610d80565b6109bf610dfe565b8060978190555050565b60975481565b600082826000609a83836040516109e79291906119e7565b90815260200160405180910390205414610a36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a2d90611b13565b60405180910390fd5b610a3e6110a8565b600060975490508585609960008481526020019081526020016000209190610a679291906111f7565b5080609a8787604051610a7b9291906119e7565b9081526020016040518091039020819055507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d818787604051610ac093929190611bf0565b60405180910390a160976000815480929190610adb906124c8565b919050555080935050505092915050565b609860009054906101000a900460ff1681565b81816000609a8383604051610b159291906119e7565b90815260200160405180910390205414610b64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b5b90611b13565b60405180910390fd5b610b6c6110a8565b6000609960008781526020019081526020016000208054610b8c90612449565b905014610bce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bc590611a93565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16609b600087815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610c72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6990611b93565b60405180910390fd5b8383609960008881526020019081526020016000209190610c949291906111f7565b5084609a8585604051610ca89291906119e7565b9081526020016040518091039020819055507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c858585604051610ced93929190611bf0565b60405180910390a15050505050565b610d04610d80565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610d74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6b90611ab3565b60405180910390fd5b610d7d81610eaa565b50565b610d886110f2565b73ffffffffffffffffffffffffffffffffffffffff16610da6610985565b73ffffffffffffffffffffffffffffffffffffffff1614610dfc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610df390611b53565b60405180910390fd5b565b610e0661060b565b610e45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e3c90611a73565b60405180910390fd5b565b610e4f610dfe565b6000606560006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610e936110f2565b604051610ea09190611a00565b60405180910390a1565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610fe2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fd990611b73565b60405180910390fd5b610fea6110fa565b565b600060019054906101000a900460ff1661103b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103290611b73565b60405180910390fd5b61104361115b565b565b61104d6110a8565b6001606560006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586110916110f2565b60405161109e9190611a00565b60405180910390a1565b6110b061060b565b156110f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110e790611af3565b60405180910390fd5b565b600033905090565b600060019054906101000a900460ff16611149576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161114090611b73565b60405180910390fd5b6111596111546110f2565b610eaa565b565b600060019054906101000a900460ff166111aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111a190611b73565b60405180910390fd5b6000606560006101000a81548160ff021916908315150217905550565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b82805461120390612449565b90600052602060002090601f016020900481019282611225576000855561126c565b82601f1061123e57803560ff191683800117855561126c565b8280016001018555821561126c579182015b8281111561126b578235825591602001919060010190611250565b5b509050611279919061127d565b5090565b5b8082111561129657600081600090555060010161127e565b5090565b60006112ad6112a884611d49565b611d24565b9050828152602081018484840111156112c557600080fd5b6112d084828561237b565b509392505050565b6000813590506112e781612b59565b92915050565b60008083601f8401126112ff57600080fd5b8235905067ffffffffffffffff81111561131857600080fd5b60208301915083600182028301111561133057600080fd5b9250929050565b600082601f83011261134857600080fd5b813561135884826020860161129a565b91505092915050565b60006040828403121561137357600080fd5b81905092915050565b60008135905061138b81612b70565b92915050565b6000602082840312156113a357600080fd5b60006113b1848285016112d8565b91505092915050565b600080602083850312156113cd57600080fd5b600083013567ffffffffffffffff8111156113e757600080fd5b6113f3858286016112ed565b92509250509250929050565b60006020828403121561141157600080fd5b600082013567ffffffffffffffff81111561142b57600080fd5b61143784828501611337565b91505092915050565b60006020828403121561145257600080fd5b60006114608482850161137c565b91505092915050565b60008060006040848603121561147e57600080fd5b600061148c8682870161137c565b935050602084013567ffffffffffffffff8111156114a957600080fd5b6114b5868287016112ed565b92509250509250925092565b600080604083850312156114d457600080fd5b60006114e28582860161137c565b925050602083013567ffffffffffffffff8111156114ff57600080fd5b61150b85828601611361565b9150509250929050565b6000611521838361193d565b905092915050565b6000611535838361198c565b905092915050565b611546816120c3565b82525050565b611555816120c3565b82525050565b60006115678385611e26565b93508360208402850161157984611d91565b8060005b878110156115bd578484038952611594828461202e565b61159e8582611515565b94506115a983611e0c565b925060208a0199505060018101905061157d565b50829750879450505050509392505050565b60006115da82611de0565b6115e48185611e26565b9350836020820285016115f685611d9b565b8060005b8581101561163257848403895281516116138582611529565b945061161e83611e19565b925060208a019950506001810190506115fa565b50829750879550505050505092915050565b61164d816120d5565b82525050565b61165c816121be565b82525050565b600061166e8385611e37565b935061167b83858461237b565b6116848361271f565b840190509392505050565b600061169b8385611e48565b93506116a883858461237b565b6116b18361271f565b840190509392505050565b60006116c88385611e59565b93506116d583858461237b565b82840190509392505050565b60006116ec82611e01565b6116f68185611e37565b935061170681856020860161238a565b61170f8161271f565b840191505092915050565b600061172582611e01565b61172f8185611e48565b935061173f81856020860161238a565b6117488161271f565b840191505092915050565b6000611760601483611e48565b915061176b826127ab565b602082019050919050565b6000611783601583611e48565b915061178e826127d4565b602082019050919050565b60006117a6602683611e48565b91506117b1826127fd565b604082019050919050565b60006117c9601383611e48565b91506117d48261284c565b602082019050919050565b60006117ec601083611e48565b91506117f782612875565b602082019050919050565b600061180f601983611e48565b915061181a8261289e565b602082019050919050565b6000611832602e83611e48565b915061183d826128c7565b604082019050919050565b6000611855602083611e48565b915061186082612916565b602082019050919050565b6000611878602b83611e48565b91506118838261293f565b604082019050919050565b600061189b601983611e48565b91506118a68261298e565b602082019050919050565b6000604083016118c46000840184611f69565b6118d1600086018261153d565b506118df6020840184611f80565b85830360208701526118f283828461155b565b925050508091505092915050565b6000604083016000830151611918600086018261153d565b506020830151848203602086015261193082826115cf565b9150508091505092915050565b6000604083016119506000840184611fd7565b8583036000870152611963838284611662565b925050506119746020840184612052565b61198160208601826119c9565b508091505092915050565b600060408301600083015184820360008601526119a982826116e1565b91505060208301516119be60208601826119c9565b508091505092915050565b6119d281612101565b82525050565b6119e181612101565b82525050565b60006119f48284866116bc565b91508190509392505050565b6000602082019050611a15600083018461154c565b92915050565b6000602082019050611a306000830184611644565b92915050565b6000602082019050611a4b6000830184611653565b92915050565b60006020820190508181036000830152611a6b818461171a565b905092915050565b60006020820190508181036000830152611a8c81611753565b9050919050565b60006020820190508181036000830152611aac81611776565b9050919050565b60006020820190508181036000830152611acc81611799565b9050919050565b60006020820190508181036000830152611aec816117bc565b9050919050565b60006020820190508181036000830152611b0c816117df565b9050919050565b60006020820190508181036000830152611b2c81611802565b9050919050565b60006020820190508181036000830152611b4c81611825565b9050919050565b60006020820190508181036000830152611b6c81611848565b9050919050565b60006020820190508181036000830152611b8c8161186b565b9050919050565b60006020820190508181036000830152611bac8161188e565b9050919050565b60006020820190508181036000830152611bcd8184611900565b905092915050565b6000602082019050611bea60008301846119d8565b92915050565b6000604082019050611c0560008301866119d8565b8181036020830152611c1881848661168f565b9050949350505050565b6000604082019050611c3760008301856119d8565b8181036020830152611c4981846118b1565b90509392505050565b60008083356001602003843603038112611c6b57600080fd5b80840192508235915067ffffffffffffffff821115611c8957600080fd5b602083019250602082023603831315611ca157600080fd5b509250929050565b60008083356001602003843603038112611cc257600080fd5b80840192508235915067ffffffffffffffff821115611ce057600080fd5b602083019250600182023603831315611cf857600080fd5b509250929050565b600082356001604003833603038112611d1857600080fd5b80830191505092915050565b6000611d2e611d3f565b9050611d3a8282612497565b919050565b6000604051905090565b600067ffffffffffffffff821115611d6457611d636125bc565b5b611d6d8261271f565b9050602081019050919050565b6000819050611d8a826002612069565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6020841060008114611ebd57601f841160018114611e8d57611e86868561247b565b8355611eb7565b611e9683611dc0565b611eab6020601f880104820160018301612126565b611eb587856129b7565b505b50611f06565b611ec682611dc0565b6020601f8701048101601f87168015611ee757611ee681600184036125eb565b5b611ef96020601f890104840183612126565b6001886002021785555050505b5050505050565b6020831060008114611f58576020851060008114611f3657611f2f868561247b565b8355611f52565b8360ff1916935083611f4784611dc0565b556001866002020183555b50611f62565b6001856002020182555b5050505050565b6000611f7860208401846112d8565b905092915050565b60008083356001602003843603038112611f9957600080fd5b83810192508235915060208301925067ffffffffffffffff821115611fbd57600080fd5b602082023603841315611fcf57600080fd5b509250929050565b60008083356001602003843603038112611ff057600080fd5b83810192508235915060208301925067ffffffffffffffff82111561201457600080fd5b60018202360384131561202657600080fd5b509250929050565b60008235600160400383360303811261204657600080fd5b82810191505092915050565b6000612061602084018461137c565b905092915050565b600061207482612101565b915061207f83612101565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156120b8576120b761255e565b5b828202905092915050565b60006120ce826120e1565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b6121236000826126ca565b50565b5b818110156121455761213a600082612793565b600181019050612127565b5050565b5b818110156121685761215d600082612775565b60028101905061214a565b5050565b8181101561218a5761217f600082612793565b60018101905061216c565b5050565b61219b6000808301612757565b6121a9600060018301612793565b50565b60006121b7826121d0565b9050919050565b60006121c98261210b565b9050919050565b60006121db826121e2565b9050919050565b60006121ed826120e1565b9050919050565b60006121ff82612101565b9050919050565b6122108383611dd5565b61221a8183612666565b61222383611d91565b61222c83611dab565b6000805b84811015612265576122428488611d00565b61224d818486612b16565b60208501945060028401935050600181019050612230565b5050505050505050565b6122798383611df6565b67ffffffffffffffff811115612292576122916125bc565b5b61229c8254612449565b600080601f8411601f841117156122b9576122b685611dc0565b90505b601f8311156122ec576020601f850104810160208510156122d8578190505b6122ea6020601f860104830182612126565b505b601f8411600181146123195760008515612307578388013590505b612311868261247b565b875550612371565b601f1985168260005b8281101561234757858a01358255600182019150602086019550602081019050612322565b8783101561236457858a0135612360601f8a1682612511565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b838110156123a857808201518184015260208101905061238d565b838111156123b7576000848401525b50505050565b6000810160008301806123cf8161263a565b90506123db8184612aa2565b50505060018101602083016123f08185611c52565b6123fb818386612ac5565b505050505050565b60008101600083016124158185611ca9565b612420818386612ad5565b5050505060018101602083018061243681612650565b90506124428184612af3565b5050505050565b6000600282049050600182168061246157607f821691505b602082108114156124755761247461258d565b5b50919050565b60006124878383612511565b9150826002028217905092915050565b6124a08261271f565b810181811067ffffffffffffffff821117156124bf576124be6125bc565b5b80604052505050565b60006124d382612101565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156125065761250561255e565b5b600182019050919050565b60006125226000198460080261274a565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61261b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8360200360080261274a565b815481168255505050565b6000819050919050565b6000819050919050565b6000813561264781612b59565b80915050919050565b6000813561265d81612b70565b80915050919050565b680100000000000000008211156126805761267f6125bc565b5b61268981611deb565b828255808310156126c55761269d81611d7a565b6126a684611d7a565b6126af84611dab565b8181018382016126bf8183612149565b50505050505b505050565b680100000000000000008211156126e4576126e36125bc565b5b80546126ef81612449565b808411156127045761270384828486611f0d565b5b808410156127195761271884828486611e64565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b600082146127685761276761252f565b5b61277181612118565b5050565b600082146127865761278561252f565b5b61278f8161218e565b5050565b61279b612b87565b6127a6818484612b34565b505050565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f6d6967726174696f6e2069732066726f7a656e00000000000000000000000000600082015250565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b7f73747265616d20616c7265616479206861732061206450494400000000000000600082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b6129c081611dc0565b6129cb83825461247b565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff6129f884612730565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612a3a84612730565b9350801983169250808416831791505092915050565b600060088302612a807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261273d565b612a8a868361273d565b95508019841693508086168417925050509392505050565b612aab826121ac565b612abe612ab782612626565b83546129d8565b8255505050565b612ad0838383612206565b505050565b612ae083838361226f565b505050565b612aef82826123bd565b5050565b612afc826121f4565b612b0f612b0882612630565b8354612a0e565b8255505050565b8115612b2557612b2461252f565b5b612b2f8382612403565b505050565b612b3d836121f4565b612b51612b4982612630565b848454612a50565b825550505050565b612b62816120c3565b8114612b6d57600080fd5b50565b612b7981612101565b8114612b8457600080fd5b50565b60009056fea264697066735822122025321e8b3f610ad6d87a9b3497059176ff710a769edbe017d76013391f10763b64736f6c63430008040033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061012c5760003560e01c80638129fc1c116100ad578063afc2691111610071578063afc26911146102f7578063b724de3a14610315578063b9e2924114610345578063ded8896b14610363578063f2fde38b1461037f5761012c565b80638129fc1c1461027957806382b7b500146102835780638456cb59146102b35780638da5cb5b146102bd578063a5ad8ac6146102db5761012c565b80635893253c116100f45780635893253c146101c15780635c975abb146101f1578063715018a61461020f578063788243d514610219578063810a9afa146102495761012c565b80630d70b3aa14610131578063144ae8551461013b5780633f4ba83a146101575780634f896d4f14610161578063587a8cbf14610191575b600080fd5b61013961039b565b005b610155600480360381019061015091906114c1565b6103c0565b005b61015f61047e565b005b61017b60048036038101906101769190611440565b610498565b6040516101889190611a51565b60405180910390f35b6101ab60048036038101906101a691906113ff565b61053d565b6040516101b89190611bd5565b60405180910390f35b6101db60048036038101906101d69190611440565b61056b565b6040516101e89190611a51565b60405180910390f35b6101f961060b565b6040516102069190611a1b565b60405180910390f35b610217610622565b005b610233600480360381019061022e9190611440565b610636565b6040516102409190611a00565b60405180910390f35b610263600480360381019061025e9190611440565b610674565b6040516102709190611bb3565b60405180910390f35b6102816107f2565b005b61029d600480360381019061029891906113ba565b610940565b6040516102aa9190611bd5565b60405180910390f35b6102bb61096b565b005b6102c5610985565b6040516102d29190611a00565b60405180910390f35b6102f560048036038101906102f09190611440565b6109af565b005b6102ff6109c9565b60405161030c9190611bd5565b60405180910390f35b61032f600480360381019061032a91906113ba565b6109cf565b60405161033c9190611bd5565b60405180910390f35b61034d610aec565b60405161035a9190611a1b565b60405180910390f35b61037d60048036038101906103789190611469565b610aff565b005b61039960048036038101906103949190611391565b610cfc565b005b6103a3610d80565b6001609860006101000a81548160ff021916908315150217905550565b6103c8610d80565b60001515609860009054906101000a900460ff1615151461041e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041590611ad3565b60405180910390fd5b80609b6000848152602001908152602001600020818161043e9190612ae5565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada8282604051610472929190611c22565b60405180910390a15050565b610486610d80565b61048e610dfe565b610496610e47565b565b60606099600083815260200190815260200160002080546104b890612449565b80601f01602080910402602001604051908101604052809291908181526020018280546104e490612449565b80156105315780601f1061050657610100808354040283529160200191610531565b820191906000526020600020905b81548152906001019060200180831161051457829003601f168201915b50505050509050919050565b609a818051602081018201805184825260208301602085012081835280955050505050506000915090505481565b6099602052806000526040600020600091509050805461058a90612449565b80601f01602080910402602001604051908101604052809291908181526020018280546105b690612449565b80156106035780601f106105d857610100808354040283529160200191610603565b820191906000526020600020905b8154815290600101906020018083116105e657829003601f168201915b505050505081565b6000606560009054906101000a900460ff16905090565b61062a610d80565b6106346000610eaa565b565b609b6020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b61067c6111c7565b609b60008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b828210156107e3578382906000526020600020906002020160405180604001604052908160008201805461074890612449565b80601f016020809104026020016040519081016040528092919081815260200182805461077490612449565b80156107c15780601f10610796576101008083540402835291602001916107c1565b820191906000526020600020905b8154815290600101906020018083116107a457829003601f168201915b5050505050815260200160018201548152505081526020019060010190610715565b50505050815250509050919050565b60008060019054906101000a900460ff161590508080156108235750600160008054906101000a900460ff1660ff16105b80610850575061083230610f70565b15801561084f5750600160008054906101000a900460ff1660ff16145b5b61088f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161088690611b33565b60405180910390fd5b60016000806101000a81548160ff021916908360ff16021790555080156108cc576001600060016101000a81548160ff0219169083151502179055505b6108d4610f93565b6108dc610fec565b6108e4611045565b801561093d5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516109349190611a36565b60405180910390a15b50565b6000609a83836040516109549291906119e7565b908152602001604051809103902054905092915050565b610973610d80565b61097b6110a8565b610983611045565b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6109b7610d80565b6109bf610dfe565b8060978190555050565b60975481565b600082826000609a83836040516109e79291906119e7565b90815260200160405180910390205414610a36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a2d90611b13565b60405180910390fd5b610a3e6110a8565b600060975490508585609960008481526020019081526020016000209190610a679291906111f7565b5080609a8787604051610a7b9291906119e7565b9081526020016040518091039020819055507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d818787604051610ac093929190611bf0565b60405180910390a160976000815480929190610adb906124c8565b919050555080935050505092915050565b609860009054906101000a900460ff1681565b81816000609a8383604051610b159291906119e7565b90815260200160405180910390205414610b64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b5b90611b13565b60405180910390fd5b610b6c6110a8565b6000609960008781526020019081526020016000208054610b8c90612449565b905014610bce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bc590611a93565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16609b600087815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610c72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6990611b93565b60405180910390fd5b8383609960008881526020019081526020016000209190610c949291906111f7565b5084609a8585604051610ca89291906119e7565b9081526020016040518091039020819055507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c858585604051610ced93929190611bf0565b60405180910390a15050505050565b610d04610d80565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610d74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6b90611ab3565b60405180910390fd5b610d7d81610eaa565b50565b610d886110f2565b73ffffffffffffffffffffffffffffffffffffffff16610da6610985565b73ffffffffffffffffffffffffffffffffffffffff1614610dfc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610df390611b53565b60405180910390fd5b565b610e0661060b565b610e45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e3c90611a73565b60405180910390fd5b565b610e4f610dfe565b6000606560006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610e936110f2565b604051610ea09190611a00565b60405180910390a1565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610fe2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fd990611b73565b60405180910390fd5b610fea6110fa565b565b600060019054906101000a900460ff1661103b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103290611b73565b60405180910390fd5b61104361115b565b565b61104d6110a8565b6001606560006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586110916110f2565b60405161109e9190611a00565b60405180910390a1565b6110b061060b565b156110f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110e790611af3565b60405180910390fd5b565b600033905090565b600060019054906101000a900460ff16611149576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161114090611b73565b60405180910390fd5b6111596111546110f2565b610eaa565b565b600060019054906101000a900460ff166111aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111a190611b73565b60405180910390fd5b6000606560006101000a81548160ff021916908315150217905550565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b82805461120390612449565b90600052602060002090601f016020900481019282611225576000855561126c565b82601f1061123e57803560ff191683800117855561126c565b8280016001018555821561126c579182015b8281111561126b578235825591602001919060010190611250565b5b509050611279919061127d565b5090565b5b8082111561129657600081600090555060010161127e565b5090565b60006112ad6112a884611d49565b611d24565b9050828152602081018484840111156112c557600080fd5b6112d084828561237b565b509392505050565b6000813590506112e781612b59565b92915050565b60008083601f8401126112ff57600080fd5b8235905067ffffffffffffffff81111561131857600080fd5b60208301915083600182028301111561133057600080fd5b9250929050565b600082601f83011261134857600080fd5b813561135884826020860161129a565b91505092915050565b60006040828403121561137357600080fd5b81905092915050565b60008135905061138b81612b70565b92915050565b6000602082840312156113a357600080fd5b60006113b1848285016112d8565b91505092915050565b600080602083850312156113cd57600080fd5b600083013567ffffffffffffffff8111156113e757600080fd5b6113f3858286016112ed565b92509250509250929050565b60006020828403121561141157600080fd5b600082013567ffffffffffffffff81111561142b57600080fd5b61143784828501611337565b91505092915050565b60006020828403121561145257600080fd5b60006114608482850161137c565b91505092915050565b60008060006040848603121561147e57600080fd5b600061148c8682870161137c565b935050602084013567ffffffffffffffff8111156114a957600080fd5b6114b5868287016112ed565b92509250509250925092565b600080604083850312156114d457600080fd5b60006114e28582860161137c565b925050602083013567ffffffffffffffff8111156114ff57600080fd5b61150b85828601611361565b9150509250929050565b6000611521838361193d565b905092915050565b6000611535838361198c565b905092915050565b611546816120c3565b82525050565b611555816120c3565b82525050565b60006115678385611e26565b93508360208402850161157984611d91565b8060005b878110156115bd578484038952611594828461202e565b61159e8582611515565b94506115a983611e0c565b925060208a0199505060018101905061157d565b50829750879450505050509392505050565b60006115da82611de0565b6115e48185611e26565b9350836020820285016115f685611d9b565b8060005b8581101561163257848403895281516116138582611529565b945061161e83611e19565b925060208a019950506001810190506115fa565b50829750879550505050505092915050565b61164d816120d5565b82525050565b61165c816121be565b82525050565b600061166e8385611e37565b935061167b83858461237b565b6116848361271f565b840190509392505050565b600061169b8385611e48565b93506116a883858461237b565b6116b18361271f565b840190509392505050565b60006116c88385611e59565b93506116d583858461237b565b82840190509392505050565b60006116ec82611e01565b6116f68185611e37565b935061170681856020860161238a565b61170f8161271f565b840191505092915050565b600061172582611e01565b61172f8185611e48565b935061173f81856020860161238a565b6117488161271f565b840191505092915050565b6000611760601483611e48565b915061176b826127ab565b602082019050919050565b6000611783601583611e48565b915061178e826127d4565b602082019050919050565b60006117a6602683611e48565b91506117b1826127fd565b604082019050919050565b60006117c9601383611e48565b91506117d48261284c565b602082019050919050565b60006117ec601083611e48565b91506117f782612875565b602082019050919050565b600061180f601983611e48565b915061181a8261289e565b602082019050919050565b6000611832602e83611e48565b915061183d826128c7565b604082019050919050565b6000611855602083611e48565b915061186082612916565b602082019050919050565b6000611878602b83611e48565b91506118838261293f565b604082019050919050565b600061189b601983611e48565b91506118a68261298e565b602082019050919050565b6000604083016118c46000840184611f69565b6118d1600086018261153d565b506118df6020840184611f80565b85830360208701526118f283828461155b565b925050508091505092915050565b6000604083016000830151611918600086018261153d565b506020830151848203602086015261193082826115cf565b9150508091505092915050565b6000604083016119506000840184611fd7565b8583036000870152611963838284611662565b925050506119746020840184612052565b61198160208601826119c9565b508091505092915050565b600060408301600083015184820360008601526119a982826116e1565b91505060208301516119be60208601826119c9565b508091505092915050565b6119d281612101565b82525050565b6119e181612101565b82525050565b60006119f48284866116bc565b91508190509392505050565b6000602082019050611a15600083018461154c565b92915050565b6000602082019050611a306000830184611644565b92915050565b6000602082019050611a4b6000830184611653565b92915050565b60006020820190508181036000830152611a6b818461171a565b905092915050565b60006020820190508181036000830152611a8c81611753565b9050919050565b60006020820190508181036000830152611aac81611776565b9050919050565b60006020820190508181036000830152611acc81611799565b9050919050565b60006020820190508181036000830152611aec816117bc565b9050919050565b60006020820190508181036000830152611b0c816117df565b9050919050565b60006020820190508181036000830152611b2c81611802565b9050919050565b60006020820190508181036000830152611b4c81611825565b9050919050565b60006020820190508181036000830152611b6c81611848565b9050919050565b60006020820190508181036000830152611b8c8161186b565b9050919050565b60006020820190508181036000830152611bac8161188e565b9050919050565b60006020820190508181036000830152611bcd8184611900565b905092915050565b6000602082019050611bea60008301846119d8565b92915050565b6000604082019050611c0560008301866119d8565b8181036020830152611c1881848661168f565b9050949350505050565b6000604082019050611c3760008301856119d8565b8181036020830152611c4981846118b1565b90509392505050565b60008083356001602003843603038112611c6b57600080fd5b80840192508235915067ffffffffffffffff821115611c8957600080fd5b602083019250602082023603831315611ca157600080fd5b509250929050565b60008083356001602003843603038112611cc257600080fd5b80840192508235915067ffffffffffffffff821115611ce057600080fd5b602083019250600182023603831315611cf857600080fd5b509250929050565b600082356001604003833603038112611d1857600080fd5b80830191505092915050565b6000611d2e611d3f565b9050611d3a8282612497565b919050565b6000604051905090565b600067ffffffffffffffff821115611d6457611d636125bc565b5b611d6d8261271f565b9050602081019050919050565b6000819050611d8a826002612069565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6020841060008114611ebd57601f841160018114611e8d57611e86868561247b565b8355611eb7565b611e9683611dc0565b611eab6020601f880104820160018301612126565b611eb587856129b7565b505b50611f06565b611ec682611dc0565b6020601f8701048101601f87168015611ee757611ee681600184036125eb565b5b611ef96020601f890104840183612126565b6001886002021785555050505b5050505050565b6020831060008114611f58576020851060008114611f3657611f2f868561247b565b8355611f52565b8360ff1916935083611f4784611dc0565b556001866002020183555b50611f62565b6001856002020182555b5050505050565b6000611f7860208401846112d8565b905092915050565b60008083356001602003843603038112611f9957600080fd5b83810192508235915060208301925067ffffffffffffffff821115611fbd57600080fd5b602082023603841315611fcf57600080fd5b509250929050565b60008083356001602003843603038112611ff057600080fd5b83810192508235915060208301925067ffffffffffffffff82111561201457600080fd5b60018202360384131561202657600080fd5b509250929050565b60008235600160400383360303811261204657600080fd5b82810191505092915050565b6000612061602084018461137c565b905092915050565b600061207482612101565b915061207f83612101565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156120b8576120b761255e565b5b828202905092915050565b60006120ce826120e1565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b6121236000826126ca565b50565b5b818110156121455761213a600082612793565b600181019050612127565b5050565b5b818110156121685761215d600082612775565b60028101905061214a565b5050565b8181101561218a5761217f600082612793565b60018101905061216c565b5050565b61219b6000808301612757565b6121a9600060018301612793565b50565b60006121b7826121d0565b9050919050565b60006121c98261210b565b9050919050565b60006121db826121e2565b9050919050565b60006121ed826120e1565b9050919050565b60006121ff82612101565b9050919050565b6122108383611dd5565b61221a8183612666565b61222383611d91565b61222c83611dab565b6000805b84811015612265576122428488611d00565b61224d818486612b16565b60208501945060028401935050600181019050612230565b5050505050505050565b6122798383611df6565b67ffffffffffffffff811115612292576122916125bc565b5b61229c8254612449565b600080601f8411601f841117156122b9576122b685611dc0565b90505b601f8311156122ec576020601f850104810160208510156122d8578190505b6122ea6020601f860104830182612126565b505b601f8411600181146123195760008515612307578388013590505b612311868261247b565b875550612371565b601f1985168260005b8281101561234757858a01358255600182019150602086019550602081019050612322565b8783101561236457858a0135612360601f8a1682612511565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b838110156123a857808201518184015260208101905061238d565b838111156123b7576000848401525b50505050565b6000810160008301806123cf8161263a565b90506123db8184612aa2565b50505060018101602083016123f08185611c52565b6123fb818386612ac5565b505050505050565b60008101600083016124158185611ca9565b612420818386612ad5565b5050505060018101602083018061243681612650565b90506124428184612af3565b5050505050565b6000600282049050600182168061246157607f821691505b602082108114156124755761247461258d565b5b50919050565b60006124878383612511565b9150826002028217905092915050565b6124a08261271f565b810181811067ffffffffffffffff821117156124bf576124be6125bc565b5b80604052505050565b60006124d382612101565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156125065761250561255e565b5b600182019050919050565b60006125226000198460080261274a565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61261b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8360200360080261274a565b815481168255505050565b6000819050919050565b6000819050919050565b6000813561264781612b59565b80915050919050565b6000813561265d81612b70565b80915050919050565b680100000000000000008211156126805761267f6125bc565b5b61268981611deb565b828255808310156126c55761269d81611d7a565b6126a684611d7a565b6126af84611dab565b8181018382016126bf8183612149565b50505050505b505050565b680100000000000000008211156126e4576126e36125bc565b5b80546126ef81612449565b808411156127045761270384828486611f0d565b5b808410156127195761271884828486611e64565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b600082146127685761276761252f565b5b61277181612118565b5050565b600082146127865761278561252f565b5b61278f8161218e565b5050565b61279b612b87565b6127a6818484612b34565b505050565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f6d6967726174696f6e2069732066726f7a656e00000000000000000000000000600082015250565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b7f73747265616d20616c7265616479206861732061206450494400000000000000600082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b6129c081611dc0565b6129cb83825461247b565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff6129f884612730565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612a3a84612730565b9350801983169250808416831791505092915050565b600060088302612a807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261273d565b612a8a868361273d565b95508019841693508086168417925050509392505050565b612aab826121ac565b612abe612ab782612626565b83546129d8565b8255505050565b612ad0838383612206565b505050565b612ae083838361226f565b505050565b612aef82826123bd565b5050565b612afc826121f4565b612b0f612b0882612630565b8354612a0e565b8255505050565b8115612b2557612b2461252f565b5b612b2f8382612403565b505050565b612b3d836121f4565b612b51612b4982612630565b848454612a50565b825550505050565b612b62816120c3565b8114612b6d57600080fd5b50565b612b7981612101565b8114612b8457600080fd5b50565b60009056fea264697066735822122025321e8b3f610ad6d87a9b3497059176ff710a769edbe017d76013391f10763b64736f6c63430008040033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/desci-contracts/contracts/DpidAliasRegistry.sol b/desci-contracts/contracts/DpidAliasRegistry.sol index ba8b4809..fc9aa2ff 100644 --- a/desci-contracts/contracts/DpidAliasRegistry.sol +++ b/desci-contracts/contracts/DpidAliasRegistry.sol @@ -1,12 +1,11 @@ //SPDX-License-Identifier: MIT pragma solidity ^0.8.0; +import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; -contract DpidAliasRegistry is OwnableUpgradeable { - // Starting point of new aliases (set at initialization) - uint256 public firstDpid; - +contract DpidAliasRegistry is Initializable, OwnableUpgradeable, PausableUpgradeable { // Incremented on each dPID mint uint256 public nextDpid; @@ -24,10 +23,12 @@ contract DpidAliasRegistry is OwnableUpgradeable { _disableInitializers(); } - function initialize(uint256 _firstDpid) public initializer { + function initialize() public initializer { OwnableUpgradeable.__Ownable_init(); - firstDpid = _firstDpid; - nextDpid = _firstDpid; + PausableUpgradeable.__Pausable_init(); + + // Pause to allow owner to set nextDpid before activating minting + _pause(); } /** @@ -75,7 +76,7 @@ contract DpidAliasRegistry is OwnableUpgradeable { */ function mintDpid( string calldata streamId - ) public onlyUnaliasedStream(streamId) returns(uint256) { + ) public onlyUnaliasedStream(streamId) whenNotPaused returns(uint256) { uint256 thisDpid = nextDpid; // map this dPID to the passed stream ID @@ -167,7 +168,7 @@ contract DpidAliasRegistry is OwnableUpgradeable { function upgradeDpid( uint256 dpid, string calldata streamId - ) public onlyUnaliasedStream(streamId) { + ) public onlyUnaliasedStream(streamId) whenNotPaused { // Assert that this dPID has not been set in the main registry require(bytes(registry[dpid]).length == 0, "dpid already upgraded"); @@ -201,6 +202,8 @@ contract DpidAliasRegistry is OwnableUpgradeable { * the registry. This allows overwriting to correct migration errors, * but can be locked for further imports. * + * Note: this can be called when the contract is paused + * * @param dpid the dPID to import * @param entry the historical and ownership information */ @@ -216,8 +219,33 @@ contract DpidAliasRegistry is OwnableUpgradeable { /** * This permanently blocks importing/overwriting legacy dPID entries, * effectively freezing history. + * + * Note: this is irreversible */ function freezeMigration() public onlyOwner { migrationFrozen = true; } + + /** + * When the contract is paused, the owner can correct the next dPID. + * This is useful for making a seamless switch between new and old + * contracts. + */ + function setNextDpid(uint256 _nextDpid) public onlyOwner whenPaused { + nextDpid = _nextDpid; + } + + /** + * Pause minting new dPID's + */ + function pause() public onlyOwner whenNotPaused { + _pause(); + } + + /** + * Resume minting of new dPID's + */ + function unpause() public onlyOwner whenPaused { + _unpause(); + } } diff --git a/desci-contracts/scripts/deployDpidAliasRegistry.js b/desci-contracts/scripts/deployDpidAliasRegistry.js index e5f7740b..5e821a43 100644 --- a/desci-contracts/scripts/deployDpidAliasRegistry.js +++ b/desci-contracts/scripts/deployDpidAliasRegistry.js @@ -14,14 +14,18 @@ async function main() { console.log("[deployDpidAliasRegistry] Deploying DpidAliasRegistry..."); const proxy = await upgrades.deployProxy( DpidAliasRegistry, - [ - FIRST_DPID // firstDpid - ], + [], { initializer: "initialize" } ); await proxy.deployed(); + + let tx = await proxy.setNextDpid(FIRST_DPID); + await tx.wait(); + tx = await proxy.unpause(); + await tx.wait(); + console.log("[deployDpidRegistry] DpidAliasRegistry deployed to:", proxy.address); fs.renameSync( diff --git a/desci-contracts/test/DpidAliasRegistry.ts b/desci-contracts/test/DpidAliasRegistry.ts index 44151dfa..a8cb2ef3 100644 --- a/desci-contracts/test/DpidAliasRegistry.ts +++ b/desci-contracts/test/DpidAliasRegistry.ts @@ -8,12 +8,9 @@ import { } from "../typechain-types"; import { TransactionReceipt } from "@ethersproject/abstract-provider"; import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; -import { receiveMessageOnPort } from "worker_threads"; use(chaiAsPromised); -const FIRST_DPID = hhe.BigNumber.from(100); - describe("dPID", () => { let _accounts: SignerWithAddress[]; let owner: SignerWithAddress; @@ -34,24 +31,18 @@ describe("dPID", () => { dpidAliasRegistry = await upgrades.deployProxy( DpidAliasRegistryFactory, - [ - FIRST_DPID // firstDpid - ], + [], { initializer: "initialize", } ) as DpidAliasRegistry; await dpidAliasRegistry.deployed(); - - // Default instance to non-owner user - dpidAliasRegistry = dpidAliasRegistry.connect(user1); }); describe("deployment", () => { let reciept: TransactionReceipt; let proxyAddress: string; let implAddress: string; - let proxyAdmin: string; before(async () => { reciept = await dpidAliasRegistry.deployTransaction.wait(); @@ -81,20 +72,46 @@ describe("dPID", () => { expect(registryOwner).to.equal(owner.address); }); - it("respects initializer dpid offset", async () => { - const nextDpid = await dpidAliasRegistry.nextDpid(); - expect(nextDpid).to.equal(FIRST_DPID); - }) + it("deploys contract in paused state", async () => { + const isPaused = await dpidAliasRegistry.paused(); + expect(isPaused).to.equal(true); + }); }); describe("alias registry", () => { const STREAM_A = "kjzl6kcym7w8y7i5ugaq9a3vlm7hhuaf4bpl5o5qykeh4qtsa12c6rb5ekw6aaa"; + describe("admin", () => { + it("can set nextDpid when paused", async () => { + const tx = await dpidAliasRegistry.setNextDpid(100); + await tx.wait(); + const nextDpid = await dpidAliasRegistry.nextDpid(); + expect(nextDpid).to.equal(100); + }); + + it("can unpause contract", async () => { + const tx = await dpidAliasRegistry.unpause(); + await tx.wait(); + const isPaused = await dpidAliasRegistry.paused(); + expect(isPaused).to.equal(false); + }); + + it("can NOT set nextDpid when unpaused", async () => { + const liveResetNextDpid = async () => { + const tx = await dpidAliasRegistry.setNextDpid(500); + await tx.wait(); + }; + await expect(liveResetNextDpid()).to.be.rejectedWith("Pausable: not paused"); + }); + }); + describe("entry", () => { let tx: ContractTransaction; let res: ContractReceipt; before(async () => { + // Default instance to non-owner user + dpidAliasRegistry = dpidAliasRegistry.connect(user1); tx = await dpidAliasRegistry.mintDpid(STREAM_A); res = await tx.wait(); }); diff --git a/desci-contracts/typechain-types/DpidAliasRegistry.ts b/desci-contracts/typechain-types/DpidAliasRegistry.ts index efc29a83..7c100924 100644 --- a/desci-contracts/typechain-types/DpidAliasRegistry.ts +++ b/desci-contracts/typechain-types/DpidAliasRegistry.ts @@ -43,26 +43,28 @@ export interface DpidAliasRegistryInterface extends utils.Interface { contractName: "DpidAliasRegistry"; functions: { "find(string)": FunctionFragment; - "firstDpid()": FunctionFragment; "freezeMigration()": FunctionFragment; "importLegacyDpid(uint256,(address,(string,uint256)[]))": FunctionFragment; - "initialize(uint256)": FunctionFragment; + "initialize()": FunctionFragment; "legacy(uint256)": FunctionFragment; "legacyLookup(uint256)": FunctionFragment; "migrationFrozen()": FunctionFragment; "mintDpid(string)": FunctionFragment; "nextDpid()": FunctionFragment; "owner()": FunctionFragment; + "pause()": FunctionFragment; + "paused()": FunctionFragment; "registry(uint256)": FunctionFragment; "renounceOwnership()": FunctionFragment; "resolve(uint256)": FunctionFragment; "reverseRegistry(string)": FunctionFragment; + "setNextDpid(uint256)": FunctionFragment; "transferOwnership(address)": FunctionFragment; + "unpause()": FunctionFragment; "upgradeDpid(uint256,string)": FunctionFragment; }; encodeFunctionData(functionFragment: "find", values: [string]): string; - encodeFunctionData(functionFragment: "firstDpid", values?: undefined): string; encodeFunctionData( functionFragment: "freezeMigration", values?: undefined @@ -73,7 +75,7 @@ export interface DpidAliasRegistryInterface extends utils.Interface { ): string; encodeFunctionData( functionFragment: "initialize", - values: [BigNumberish] + values?: undefined ): string; encodeFunctionData( functionFragment: "legacy", @@ -90,6 +92,8 @@ export interface DpidAliasRegistryInterface extends utils.Interface { encodeFunctionData(functionFragment: "mintDpid", values: [string]): string; encodeFunctionData(functionFragment: "nextDpid", values?: undefined): string; encodeFunctionData(functionFragment: "owner", values?: undefined): string; + encodeFunctionData(functionFragment: "pause", values?: undefined): string; + encodeFunctionData(functionFragment: "paused", values?: undefined): string; encodeFunctionData( functionFragment: "registry", values: [BigNumberish] @@ -106,17 +110,21 @@ export interface DpidAliasRegistryInterface extends utils.Interface { functionFragment: "reverseRegistry", values: [string] ): string; + encodeFunctionData( + functionFragment: "setNextDpid", + values: [BigNumberish] + ): string; encodeFunctionData( functionFragment: "transferOwnership", values: [string] ): string; + encodeFunctionData(functionFragment: "unpause", values?: undefined): string; encodeFunctionData( functionFragment: "upgradeDpid", values: [BigNumberish, string] ): string; decodeFunctionResult(functionFragment: "find", data: BytesLike): Result; - decodeFunctionResult(functionFragment: "firstDpid", data: BytesLike): Result; decodeFunctionResult( functionFragment: "freezeMigration", data: BytesLike @@ -138,6 +146,8 @@ export interface DpidAliasRegistryInterface extends utils.Interface { decodeFunctionResult(functionFragment: "mintDpid", data: BytesLike): Result; decodeFunctionResult(functionFragment: "nextDpid", data: BytesLike): Result; decodeFunctionResult(functionFragment: "owner", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "pause", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "paused", data: BytesLike): Result; decodeFunctionResult(functionFragment: "registry", data: BytesLike): Result; decodeFunctionResult( functionFragment: "renounceOwnership", @@ -148,10 +158,15 @@ export interface DpidAliasRegistryInterface extends utils.Interface { functionFragment: "reverseRegistry", data: BytesLike ): Result; + decodeFunctionResult( + functionFragment: "setNextDpid", + data: BytesLike + ): Result; decodeFunctionResult( functionFragment: "transferOwnership", data: BytesLike ): Result; + decodeFunctionResult(functionFragment: "unpause", data: BytesLike): Result; decodeFunctionResult( functionFragment: "upgradeDpid", data: BytesLike @@ -162,6 +177,8 @@ export interface DpidAliasRegistryInterface extends utils.Interface { "ImportedDpid(uint256,tuple)": EventFragment; "Initialized(uint8)": EventFragment; "OwnershipTransferred(address,address)": EventFragment; + "Paused(address)": EventFragment; + "Unpaused(address)": EventFragment; "UpgradedDpid(uint256,string)": EventFragment; }; @@ -169,6 +186,8 @@ export interface DpidAliasRegistryInterface extends utils.Interface { getEvent(nameOrSignatureOrTopic: "ImportedDpid"): EventFragment; getEvent(nameOrSignatureOrTopic: "Initialized"): EventFragment; getEvent(nameOrSignatureOrTopic: "OwnershipTransferred"): EventFragment; + getEvent(nameOrSignatureOrTopic: "Paused"): EventFragment; + getEvent(nameOrSignatureOrTopic: "Unpaused"): EventFragment; getEvent(nameOrSignatureOrTopic: "UpgradedDpid"): EventFragment; } @@ -198,6 +217,14 @@ export type OwnershipTransferredEvent = TypedEvent< export type OwnershipTransferredEventFilter = TypedEventFilter; +export type PausedEvent = TypedEvent<[string], { account: string }>; + +export type PausedEventFilter = TypedEventFilter; + +export type UnpausedEvent = TypedEvent<[string], { account: string }>; + +export type UnpausedEventFilter = TypedEventFilter; + export type UpgradedDpidEvent = TypedEvent< [BigNumber, string], { dpid: BigNumber; streamId: string } @@ -235,8 +262,6 @@ export interface DpidAliasRegistry extends BaseContract { functions: { find(streamId: string, overrides?: CallOverrides): Promise<[BigNumber]>; - firstDpid(overrides?: CallOverrides): Promise<[BigNumber]>; - freezeMigration( overrides?: Overrides & { from?: string | Promise } ): Promise; @@ -248,7 +273,6 @@ export interface DpidAliasRegistry extends BaseContract { ): Promise; initialize( - _firstDpid: BigNumberish, overrides?: Overrides & { from?: string | Promise } ): Promise; @@ -273,6 +297,12 @@ export interface DpidAliasRegistry extends BaseContract { owner(overrides?: CallOverrides): Promise<[string]>; + pause( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + paused(overrides?: CallOverrides): Promise<[boolean]>; + registry(arg0: BigNumberish, overrides?: CallOverrides): Promise<[string]>; renounceOwnership( @@ -286,11 +316,20 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: CallOverrides ): Promise<[BigNumber]>; + setNextDpid( + _nextDpid: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + transferOwnership( newOwner: string, overrides?: Overrides & { from?: string | Promise } ): Promise; + unpause( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + upgradeDpid( dpid: BigNumberish, streamId: string, @@ -300,8 +339,6 @@ export interface DpidAliasRegistry extends BaseContract { find(streamId: string, overrides?: CallOverrides): Promise; - firstDpid(overrides?: CallOverrides): Promise; - freezeMigration( overrides?: Overrides & { from?: string | Promise } ): Promise; @@ -313,7 +350,6 @@ export interface DpidAliasRegistry extends BaseContract { ): Promise; initialize( - _firstDpid: BigNumberish, overrides?: Overrides & { from?: string | Promise } ): Promise; @@ -335,6 +371,12 @@ export interface DpidAliasRegistry extends BaseContract { owner(overrides?: CallOverrides): Promise; + pause( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + paused(overrides?: CallOverrides): Promise; + registry(arg0: BigNumberish, overrides?: CallOverrides): Promise; renounceOwnership( @@ -345,11 +387,20 @@ export interface DpidAliasRegistry extends BaseContract { reverseRegistry(arg0: string, overrides?: CallOverrides): Promise; + setNextDpid( + _nextDpid: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + transferOwnership( newOwner: string, overrides?: Overrides & { from?: string | Promise } ): Promise; + unpause( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + upgradeDpid( dpid: BigNumberish, streamId: string, @@ -359,8 +410,6 @@ export interface DpidAliasRegistry extends BaseContract { callStatic: { find(streamId: string, overrides?: CallOverrides): Promise; - firstDpid(overrides?: CallOverrides): Promise; - freezeMigration(overrides?: CallOverrides): Promise; importLegacyDpid( @@ -369,10 +418,7 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: CallOverrides ): Promise; - initialize( - _firstDpid: BigNumberish, - overrides?: CallOverrides - ): Promise; + initialize(overrides?: CallOverrides): Promise; legacy(arg0: BigNumberish, overrides?: CallOverrides): Promise; @@ -389,6 +435,10 @@ export interface DpidAliasRegistry extends BaseContract { owner(overrides?: CallOverrides): Promise; + pause(overrides?: CallOverrides): Promise; + + paused(overrides?: CallOverrides): Promise; + registry(arg0: BigNumberish, overrides?: CallOverrides): Promise; renounceOwnership(overrides?: CallOverrides): Promise; @@ -400,11 +450,18 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: CallOverrides ): Promise; + setNextDpid( + _nextDpid: BigNumberish, + overrides?: CallOverrides + ): Promise; + transferOwnership( newOwner: string, overrides?: CallOverrides ): Promise; + unpause(overrides?: CallOverrides): Promise; + upgradeDpid( dpid: BigNumberish, streamId: string, @@ -437,6 +494,12 @@ export interface DpidAliasRegistry extends BaseContract { newOwner?: string | null ): OwnershipTransferredEventFilter; + "Paused(address)"(account?: null): PausedEventFilter; + Paused(account?: null): PausedEventFilter; + + "Unpaused(address)"(account?: null): UnpausedEventFilter; + Unpaused(account?: null): UnpausedEventFilter; + "UpgradedDpid(uint256,string)"( dpid?: null, streamId?: null @@ -447,8 +510,6 @@ export interface DpidAliasRegistry extends BaseContract { estimateGas: { find(streamId: string, overrides?: CallOverrides): Promise; - firstDpid(overrides?: CallOverrides): Promise; - freezeMigration( overrides?: Overrides & { from?: string | Promise } ): Promise; @@ -460,7 +521,6 @@ export interface DpidAliasRegistry extends BaseContract { ): Promise; initialize( - _firstDpid: BigNumberish, overrides?: Overrides & { from?: string | Promise } ): Promise; @@ -482,6 +542,12 @@ export interface DpidAliasRegistry extends BaseContract { owner(overrides?: CallOverrides): Promise; + pause( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + paused(overrides?: CallOverrides): Promise; + registry(arg0: BigNumberish, overrides?: CallOverrides): Promise; renounceOwnership( @@ -495,11 +561,20 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: CallOverrides ): Promise; + setNextDpid( + _nextDpid: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + transferOwnership( newOwner: string, overrides?: Overrides & { from?: string | Promise } ): Promise; + unpause( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + upgradeDpid( dpid: BigNumberish, streamId: string, @@ -513,8 +588,6 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: CallOverrides ): Promise; - firstDpid(overrides?: CallOverrides): Promise; - freezeMigration( overrides?: Overrides & { from?: string | Promise } ): Promise; @@ -526,7 +599,6 @@ export interface DpidAliasRegistry extends BaseContract { ): Promise; initialize( - _firstDpid: BigNumberish, overrides?: Overrides & { from?: string | Promise } ): Promise; @@ -551,6 +623,12 @@ export interface DpidAliasRegistry extends BaseContract { owner(overrides?: CallOverrides): Promise; + pause( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + + paused(overrides?: CallOverrides): Promise; + registry( arg0: BigNumberish, overrides?: CallOverrides @@ -570,11 +648,20 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: CallOverrides ): Promise; + setNextDpid( + _nextDpid: BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise; + transferOwnership( newOwner: string, overrides?: Overrides & { from?: string | Promise } ): Promise; + unpause( + overrides?: Overrides & { from?: string | Promise } + ): Promise; + upgradeDpid( dpid: BigNumberish, streamId: string, diff --git a/desci-contracts/typechain-types/PausableUpgradeable.ts b/desci-contracts/typechain-types/PausableUpgradeable.ts new file mode 100644 index 00000000..fd8f44da --- /dev/null +++ b/desci-contracts/typechain-types/PausableUpgradeable.ts @@ -0,0 +1,105 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import { + BaseContract, + BigNumber, + BytesLike, + CallOverrides, + PopulatedTransaction, + Signer, + utils, +} from "ethers"; +import { FunctionFragment, Result, EventFragment } from "@ethersproject/abi"; +import { Listener, Provider } from "@ethersproject/providers"; +import { TypedEventFilter, TypedEvent, TypedListener, OnEvent } from "./common"; + +export interface PausableUpgradeableInterface extends utils.Interface { + contractName: "PausableUpgradeable"; + functions: { + "paused()": FunctionFragment; + }; + + encodeFunctionData(functionFragment: "paused", values?: undefined): string; + + decodeFunctionResult(functionFragment: "paused", data: BytesLike): Result; + + events: { + "Initialized(uint8)": EventFragment; + "Paused(address)": EventFragment; + "Unpaused(address)": EventFragment; + }; + + getEvent(nameOrSignatureOrTopic: "Initialized"): EventFragment; + getEvent(nameOrSignatureOrTopic: "Paused"): EventFragment; + getEvent(nameOrSignatureOrTopic: "Unpaused"): EventFragment; +} + +export type InitializedEvent = TypedEvent<[number], { version: number }>; + +export type InitializedEventFilter = TypedEventFilter; + +export type PausedEvent = TypedEvent<[string], { account: string }>; + +export type PausedEventFilter = TypedEventFilter; + +export type UnpausedEvent = TypedEvent<[string], { account: string }>; + +export type UnpausedEventFilter = TypedEventFilter; + +export interface PausableUpgradeable extends BaseContract { + contractName: "PausableUpgradeable"; + connect(signerOrProvider: Signer | Provider | string): this; + attach(addressOrName: string): this; + deployed(): Promise; + + interface: PausableUpgradeableInterface; + + queryFilter( + event: TypedEventFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>; + + listeners( + eventFilter?: TypedEventFilter + ): Array>; + listeners(eventName?: string): Array; + removeAllListeners( + eventFilter: TypedEventFilter + ): this; + removeAllListeners(eventName?: string): this; + off: OnEvent; + on: OnEvent; + once: OnEvent; + removeListener: OnEvent; + + functions: { + paused(overrides?: CallOverrides): Promise<[boolean]>; + }; + + paused(overrides?: CallOverrides): Promise; + + callStatic: { + paused(overrides?: CallOverrides): Promise; + }; + + filters: { + "Initialized(uint8)"(version?: null): InitializedEventFilter; + Initialized(version?: null): InitializedEventFilter; + + "Paused(address)"(account?: null): PausedEventFilter; + Paused(account?: null): PausedEventFilter; + + "Unpaused(address)"(account?: null): UnpausedEventFilter; + Unpaused(account?: null): UnpausedEventFilter; + }; + + estimateGas: { + paused(overrides?: CallOverrides): Promise; + }; + + populateTransaction: { + paused(overrides?: CallOverrides): Promise; + }; +} diff --git a/desci-contracts/typechain-types/factories/DpidAliasRegistry__factory.ts b/desci-contracts/typechain-types/factories/DpidAliasRegistry__factory.ts index 5339dc20..a3f5dca0 100644 --- a/desci-contracts/typechain-types/factories/DpidAliasRegistry__factory.ts +++ b/desci-contracts/typechain-types/factories/DpidAliasRegistry__factory.ts @@ -108,6 +108,32 @@ const _abi = [ name: "OwnershipTransferred", type: "event", }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "account", + type: "address", + }, + ], + name: "Paused", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "account", + type: "address", + }, + ], + name: "Unpaused", + type: "event", + }, { anonymous: false, inputs: [ @@ -146,19 +172,6 @@ const _abi = [ stateMutability: "view", type: "function", }, - { - inputs: [], - name: "firstDpid", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - stateMutability: "view", - type: "function", - }, { inputs: [], name: "freezeMigration", @@ -209,13 +222,7 @@ const _abi = [ type: "function", }, { - inputs: [ - { - internalType: "uint256", - name: "_firstDpid", - type: "uint256", - }, - ], + inputs: [], name: "initialize", outputs: [], stateMutability: "nonpayable", @@ -341,6 +348,26 @@ const _abi = [ stateMutability: "view", type: "function", }, + { + inputs: [], + name: "pause", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "paused", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, { inputs: [ { @@ -405,6 +432,19 @@ const _abi = [ stateMutability: "view", type: "function", }, + { + inputs: [ + { + internalType: "uint256", + name: "_nextDpid", + type: "uint256", + }, + ], + name: "setNextDpid", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, { inputs: [ { @@ -418,6 +458,13 @@ const _abi = [ stateMutability: "nonpayable", type: "function", }, + { + inputs: [], + name: "unpause", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, { inputs: [ { @@ -439,7 +486,7 @@ const _abi = [ ]; const _bytecode = - "0x60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d3565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000127565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff161015620000ed5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e4919062000149565b60405180910390a15b565b6000620000fe60278362000166565b91506200010b8262000184565b604082019050919050565b620001218162000177565b82525050565b600060208201905081810360008301526200014281620000ef565b9050919050565b600060208201905062000160600083018462000116565b92915050565b600082825260208201905092915050565b600060ff82169050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b61281d80620001e36000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806382b7b500116100a2578063b9e2924111610071578063b9e29241146102cc578063cfb452b5146102ea578063ded8896b14610308578063f2fde38b14610324578063fe4b84df146103405761010b565b806382b7b500146102305780638da5cb5b14610260578063afc269111461027e578063b724de3a1461029c5761010b565b80635893253c116100de5780635893253c14610196578063715018a6146101c6578063788243d5146101d0578063810a9afa146102005761010b565b80630d70b3aa14610110578063144ae8551461011a5780634f896d4f14610136578063587a8cbf14610166575b600080fd5b61011861035c565b005b610134600480360381019061012f91906111f4565b610381565b005b610150600480360381019061014b9190611173565b61043f565b60405161015d919061173e565b60405180910390f35b610180600480360381019061017b9190611132565b6104e4565b60405161018d9190611882565b60405180910390f35b6101b060048036038101906101ab9190611173565b610512565b6040516101bd919061173e565b60405180910390f35b6101ce6105b2565b005b6101ea60048036038101906101e59190611173565b6105c6565b6040516101f791906116ed565b60405180910390f35b61021a60048036038101906102159190611173565b610604565b6040516102279190611860565b60405180910390f35b61024a600480360381019061024591906110ed565b610782565b6040516102579190611882565b60405180910390f35b6102686107ad565b60405161027591906116ed565b60405180910390f35b6102866107d7565b6040516102939190611882565b60405180910390f35b6102b660048036038101906102b191906110ed565b6107dd565b6040516102c39190611882565b60405180910390f35b6102d46108f2565b6040516102e19190611708565b60405180910390f35b6102f2610905565b6040516102ff9190611882565b60405180910390f35b610322600480360381019061031d919061119c565b61090b565b005b61033e600480360381019061033991906110c4565b610b00565b005b61035a60048036038101906103559190611173565b610b84565b005b610364610cd1565b6001606760006101000a81548160ff021916908315150217905550565b610389610cd1565b60001515606760009054906101000a900460ff161515146103df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103d6906117a0565b60405180910390fd5b80606a600084815260200190815260200160002081816103ff9190612740565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada82826040516104339291906118cf565b60405180910390a15050565b606060686000838152602001908152602001600020805461045f906120f6565b80601f016020809104026020016040519081016040528092919081815260200182805461048b906120f6565b80156104d85780601f106104ad576101008083540402835291602001916104d8565b820191906000526020600020905b8154815290600101906020018083116104bb57829003601f168201915b50505050509050919050565b6069818051602081018201805184825260208301602085012081835280955050505050506000915090505481565b60686020528060005260406000206000915090508054610531906120f6565b80601f016020809104026020016040519081016040528092919081815260200182805461055d906120f6565b80156105aa5780601f1061057f576101008083540402835291602001916105aa565b820191906000526020600020905b81548152906001019060200180831161058d57829003601f168201915b505050505081565b6105ba610cd1565b6105c46000610d4f565b565b606a6020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b61060c610efa565b606a60008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b8282101561077357838290600052602060002090600202016040518060400160405290816000820180546106d8906120f6565b80601f0160208091040260200160405190810160405280929190818152602001828054610704906120f6565b80156107515780601f1061072657610100808354040283529160200191610751565b820191906000526020600020905b81548152906001019060200180831161073457829003601f168201915b50505050508152602001600182015481525050815260200190600101906106a5565b50505050815250509050919050565b6000606983836040516107969291906116d4565b908152602001604051809103902054905092915050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60665481565b600082826000606983836040516107f59291906116d4565b90815260200160405180910390205414610844576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161083b906117c0565b60405180910390fd5b60006066549050858560686000848152602001908152602001600020919061086d929190610f2a565b5080606987876040516108819291906116d4565b9081526020016040518091039020819055507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d8187876040516108c69392919061189d565b60405180910390a1606660008154809291906108e190612175565b919050555080935050505092915050565b606760009054906101000a900460ff1681565b60655481565b81816000606983836040516109219291906116d4565b90815260200160405180910390205414610970576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610967906117c0565b60405180910390fd5b6000606860008781526020019081526020016000208054610990906120f6565b9050146109d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109c990611760565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16606a600087815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610a76576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6d90611840565b60405180910390fd5b8383606860008881526020019081526020016000209190610a98929190610f2a565b508460698585604051610aac9291906116d4565b9081526020016040518091039020819055507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c858585604051610af19392919061189d565b60405180910390a15050505050565b610b08610cd1565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610b78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b6f90611780565b60405180910390fd5b610b8181610d4f565b50565b60008060019054906101000a900460ff16159050808015610bb55750600160008054906101000a900460ff1660ff16105b80610be25750610bc430610e15565b158015610be15750600160008054906101000a900460ff1660ff16145b5b610c21576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c18906117e0565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015610c5e576001600060016101000a81548160ff0219169083151502179055505b610c66610e38565b81606581905550816066819055508015610ccd5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024986001604051610cc49190611723565b60405180910390a15b5050565b610cd9610e91565b73ffffffffffffffffffffffffffffffffffffffff16610cf76107ad565b73ffffffffffffffffffffffffffffffffffffffff1614610d4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d4490611800565b60405180910390fd5b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610e87576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e7e90611820565b60405180910390fd5b610e8f610e99565b565b600033905090565b600060019054906101000a900460ff16610ee8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610edf90611820565b60405180910390fd5b610ef8610ef3610e91565b610d4f565b565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b828054610f36906120f6565b90600052602060002090601f016020900481019282610f585760008555610f9f565b82601f10610f7157803560ff1916838001178555610f9f565b82800160010185558215610f9f579182015b82811115610f9e578235825591602001919060010190610f83565b5b509050610fac9190610fb0565b5090565b5b80821115610fc9576000816000905550600101610fb1565b5090565b6000610fe0610fdb846119f6565b6119d1565b905082815260208101848484011115610ff857600080fd5b611003848285612028565b509392505050565b60008135905061101a816127b4565b92915050565b60008083601f84011261103257600080fd5b8235905067ffffffffffffffff81111561104b57600080fd5b60208301915083600182028301111561106357600080fd5b9250929050565b600082601f83011261107b57600080fd5b813561108b848260208601610fcd565b91505092915050565b6000604082840312156110a657600080fd5b81905092915050565b6000813590506110be816127cb565b92915050565b6000602082840312156110d657600080fd5b60006110e48482850161100b565b91505092915050565b6000806020838503121561110057600080fd5b600083013567ffffffffffffffff81111561111a57600080fd5b61112685828601611020565b92509250509250929050565b60006020828403121561114457600080fd5b600082013567ffffffffffffffff81111561115e57600080fd5b61116a8482850161106a565b91505092915050565b60006020828403121561118557600080fd5b6000611193848285016110af565b91505092915050565b6000806000604084860312156111b157600080fd5b60006111bf868287016110af565b935050602084013567ffffffffffffffff8111156111dc57600080fd5b6111e886828701611020565b92509250509250925092565b6000806040838503121561120757600080fd5b6000611215858286016110af565b925050602083013567ffffffffffffffff81111561123257600080fd5b61123e85828601611094565b9150509250929050565b6000611254838361162a565b905092915050565b60006112688383611679565b905092915050565b61127981611d70565b82525050565b61128881611d70565b82525050565b600061129a8385611ad3565b9350836020840285016112ac84611a3e565b8060005b878110156112f05784840389526112c78284611cdb565b6112d18582611248565b94506112dc83611ab9565b925060208a019950506001810190506112b0565b50829750879450505050509392505050565b600061130d82611a8d565b6113178185611ad3565b93508360208202850161132985611a48565b8060005b858110156113655784840389528151611346858261125c565b945061135183611ac6565b925060208a0199505060018101905061132d565b50829750879550505050505092915050565b61138081611d82565b82525050565b61138f81611e6b565b82525050565b60006113a18385611ae4565b93506113ae838584612028565b6113b7836123cc565b840190509392505050565b60006113ce8385611af5565b93506113db838584612028565b6113e4836123cc565b840190509392505050565b60006113fb8385611b06565b9350611408838584612028565b82840190509392505050565b600061141f82611aae565b6114298185611ae4565b9350611439818560208601612037565b611442816123cc565b840191505092915050565b600061145882611aae565b6114628185611af5565b9350611472818560208601612037565b61147b816123cc565b840191505092915050565b6000611493601583611af5565b915061149e82612458565b602082019050919050565b60006114b6602683611af5565b91506114c182612481565b604082019050919050565b60006114d9601383611af5565b91506114e4826124d0565b602082019050919050565b60006114fc601983611af5565b9150611507826124f9565b602082019050919050565b600061151f602e83611af5565b915061152a82612522565b604082019050919050565b6000611542602083611af5565b915061154d82612571565b602082019050919050565b6000611565602b83611af5565b91506115708261259a565b604082019050919050565b6000611588601983611af5565b9150611593826125e9565b602082019050919050565b6000604083016115b16000840184611c16565b6115be6000860182611270565b506115cc6020840184611c2d565b85830360208701526115df83828461128e565b925050508091505092915050565b60006040830160008301516116056000860182611270565b506020830151848203602086015261161d8282611302565b9150508091505092915050565b60006040830161163d6000840184611c84565b8583036000870152611650838284611395565b925050506116616020840184611cff565b61166e60208601826116b6565b508091505092915050565b600060408301600083015184820360008601526116968282611414565b91505060208301516116ab60208601826116b6565b508091505092915050565b6116bf81611dae565b82525050565b6116ce81611dae565b82525050565b60006116e18284866113ef565b91508190509392505050565b6000602082019050611702600083018461127f565b92915050565b600060208201905061171d6000830184611377565b92915050565b60006020820190506117386000830184611386565b92915050565b60006020820190508181036000830152611758818461144d565b905092915050565b6000602082019050818103600083015261177981611486565b9050919050565b60006020820190508181036000830152611799816114a9565b9050919050565b600060208201905081810360008301526117b9816114cc565b9050919050565b600060208201905081810360008301526117d9816114ef565b9050919050565b600060208201905081810360008301526117f981611512565b9050919050565b6000602082019050818103600083015261181981611535565b9050919050565b6000602082019050818103600083015261183981611558565b9050919050565b600060208201905081810360008301526118598161157b565b9050919050565b6000602082019050818103600083015261187a81846115ed565b905092915050565b600060208201905061189760008301846116c5565b92915050565b60006040820190506118b260008301866116c5565b81810360208301526118c58184866113c2565b9050949350505050565b60006040820190506118e460008301856116c5565b81810360208301526118f6818461159e565b90509392505050565b6000808335600160200384360303811261191857600080fd5b80840192508235915067ffffffffffffffff82111561193657600080fd5b60208301925060208202360383131561194e57600080fd5b509250929050565b6000808335600160200384360303811261196f57600080fd5b80840192508235915067ffffffffffffffff82111561198d57600080fd5b6020830192506001820236038313156119a557600080fd5b509250929050565b6000823560016040038336030381126119c557600080fd5b80830191505092915050565b60006119db6119ec565b90506119e78282612144565b919050565b6000604051905090565b600067ffffffffffffffff821115611a1157611a10612269565b5b611a1a826123cc565b9050602081019050919050565b6000819050611a37826002611d16565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6020841060008114611b6a57601f841160018114611b3a57611b338685612128565b8355611b64565b611b4383611a6d565b611b586020601f880104820160018301611dd3565b611b628785612612565b505b50611bb3565b611b7382611a6d565b6020601f8701048101601f87168015611b9457611b938160018403612298565b5b611ba66020601f890104840183611dd3565b6001886002021785555050505b5050505050565b6020831060008114611c05576020851060008114611be357611bdc8685612128565b8355611bff565b8360ff1916935083611bf484611a6d565b556001866002020183555b50611c0f565b6001856002020182555b5050505050565b6000611c25602084018461100b565b905092915050565b60008083356001602003843603038112611c4657600080fd5b83810192508235915060208301925067ffffffffffffffff821115611c6a57600080fd5b602082023603841315611c7c57600080fd5b509250929050565b60008083356001602003843603038112611c9d57600080fd5b83810192508235915060208301925067ffffffffffffffff821115611cc157600080fd5b600182023603841315611cd357600080fd5b509250929050565b600082356001604003833603038112611cf357600080fd5b82810191505092915050565b6000611d0e60208401846110af565b905092915050565b6000611d2182611dae565b9150611d2c83611dae565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611d6557611d6461220b565b5b828202905092915050565b6000611d7b82611d8e565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b611dd0600082612377565b50565b5b81811015611df257611de7600082612440565b600181019050611dd4565b5050565b5b81811015611e1557611e0a600082612422565b600281019050611df7565b5050565b81811015611e3757611e2c600082612440565b600181019050611e19565b5050565b611e486000808301612404565b611e56600060018301612440565b50565b6000611e6482611e7d565b9050919050565b6000611e7682611db8565b9050919050565b6000611e8882611e8f565b9050919050565b6000611e9a82611d8e565b9050919050565b6000611eac82611dae565b9050919050565b611ebd8383611a82565b611ec78183612313565b611ed083611a3e565b611ed983611a58565b6000805b84811015611f1257611eef84886119ad565b611efa818486612771565b60208501945060028401935050600181019050611edd565b5050505050505050565b611f268383611aa3565b67ffffffffffffffff811115611f3f57611f3e612269565b5b611f4982546120f6565b600080601f8411601f84111715611f6657611f6385611a6d565b90505b601f831115611f99576020601f85010481016020851015611f85578190505b611f976020601f860104830182611dd3565b505b601f841160018114611fc65760008515611fb4578388013590505b611fbe8682612128565b87555061201e565b601f1985168260005b82811015611ff457858a01358255600182019150602086019550602081019050611fcf565b8783101561201157858a013561200d601f8a16826121be565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b8381101561205557808201518184015260208101905061203a565b83811115612064576000848401525b50505050565b60008101600083018061207c816122e7565b905061208881846126fd565b505050600181016020830161209d81856118ff565b6120a8818386612720565b505050505050565b60008101600083016120c28185611956565b6120cd818386612730565b505050506001810160208301806120e3816122fd565b90506120ef818461274e565b5050505050565b6000600282049050600182168061210e57607f821691505b602082108114156121225761212161223a565b5b50919050565b600061213483836121be565b9150826002028217905092915050565b61214d826123cc565b810181811067ffffffffffffffff8211171561216c5761216b612269565b5b80604052505050565b600061218082611dae565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156121b3576121b261220b565b5b600182019050919050565b60006121cf600019846008026123f7565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6122c87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff836020036008026123f7565b815481168255505050565b6000819050919050565b6000819050919050565b600081356122f4816127b4565b80915050919050565b6000813561230a816127cb565b80915050919050565b6801000000000000000082111561232d5761232c612269565b5b61233681611a98565b828255808310156123725761234a81611a27565b61235384611a27565b61235c84611a58565b81810183820161236c8183611df6565b50505050505b505050565b6801000000000000000082111561239157612390612269565b5b805461239c816120f6565b808411156123b1576123b084828486611bba565b5b808410156123c6576123c584828486611b11565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b60008214612415576124146121dc565b5b61241e81611dc5565b5050565b60008214612433576124326121dc565b5b61243c81611e3b565b5050565b6124486127e2565b61245381848461278f565b505050565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f6d6967726174696f6e2069732066726f7a656e00000000000000000000000000600082015250565b7f73747265616d20616c7265616479206861732061206450494400000000000000600082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b61261b81611a6d565b612626838254612128565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff612653846123dd565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612695846123dd565b9350801983169250808416831791505092915050565b6000600883026126db7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826123ea565b6126e586836123ea565b95508019841693508086168417925050509392505050565b61270682611e59565b612719612712826122d3565b8354612633565b8255505050565b61272b838383611eb3565b505050565b61273b838383611f1c565b505050565b61274a828261206a565b5050565b61275782611ea1565b61276a612763826122dd565b8354612669565b8255505050565b81156127805761277f6121dc565b5b61278a83826120b0565b505050565b61279883611ea1565b6127ac6127a4826122dd565b8484546126ab565b825550505050565b6127bd81611d70565b81146127c857600080fd5b50565b6127d481611dae565b81146127df57600080fd5b50565b60009056fea26469706673582212203cd9493558aa831bec9e62a003cae25d442665c9c02edcb7c1725ad3e5bb65db64736f6c63430008040033"; + "0x60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d3565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000127565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff161015620000ed5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e4919062000149565b60405180910390a15b565b6000620000fe60278362000166565b91506200010b8262000184565b604082019050919050565b620001218162000177565b82525050565b600060208201905081810360008301526200014281620000ef565b9050919050565b600060208201905062000160600083018462000116565b92915050565b600082825260208201905092915050565b600060ff82169050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b612bc280620001e36000396000f3fe608060405234801561001057600080fd5b506004361061012c5760003560e01c80638129fc1c116100ad578063afc2691111610071578063afc26911146102f7578063b724de3a14610315578063b9e2924114610345578063ded8896b14610363578063f2fde38b1461037f5761012c565b80638129fc1c1461027957806382b7b500146102835780638456cb59146102b35780638da5cb5b146102bd578063a5ad8ac6146102db5761012c565b80635893253c116100f45780635893253c146101c15780635c975abb146101f1578063715018a61461020f578063788243d514610219578063810a9afa146102495761012c565b80630d70b3aa14610131578063144ae8551461013b5780633f4ba83a146101575780634f896d4f14610161578063587a8cbf14610191575b600080fd5b61013961039b565b005b610155600480360381019061015091906114c1565b6103c0565b005b61015f61047e565b005b61017b60048036038101906101769190611440565b610498565b6040516101889190611a51565b60405180910390f35b6101ab60048036038101906101a691906113ff565b61053d565b6040516101b89190611bd5565b60405180910390f35b6101db60048036038101906101d69190611440565b61056b565b6040516101e89190611a51565b60405180910390f35b6101f961060b565b6040516102069190611a1b565b60405180910390f35b610217610622565b005b610233600480360381019061022e9190611440565b610636565b6040516102409190611a00565b60405180910390f35b610263600480360381019061025e9190611440565b610674565b6040516102709190611bb3565b60405180910390f35b6102816107f2565b005b61029d600480360381019061029891906113ba565b610940565b6040516102aa9190611bd5565b60405180910390f35b6102bb61096b565b005b6102c5610985565b6040516102d29190611a00565b60405180910390f35b6102f560048036038101906102f09190611440565b6109af565b005b6102ff6109c9565b60405161030c9190611bd5565b60405180910390f35b61032f600480360381019061032a91906113ba565b6109cf565b60405161033c9190611bd5565b60405180910390f35b61034d610aec565b60405161035a9190611a1b565b60405180910390f35b61037d60048036038101906103789190611469565b610aff565b005b61039960048036038101906103949190611391565b610cfc565b005b6103a3610d80565b6001609860006101000a81548160ff021916908315150217905550565b6103c8610d80565b60001515609860009054906101000a900460ff1615151461041e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041590611ad3565b60405180910390fd5b80609b6000848152602001908152602001600020818161043e9190612ae5565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada8282604051610472929190611c22565b60405180910390a15050565b610486610d80565b61048e610dfe565b610496610e47565b565b60606099600083815260200190815260200160002080546104b890612449565b80601f01602080910402602001604051908101604052809291908181526020018280546104e490612449565b80156105315780601f1061050657610100808354040283529160200191610531565b820191906000526020600020905b81548152906001019060200180831161051457829003601f168201915b50505050509050919050565b609a818051602081018201805184825260208301602085012081835280955050505050506000915090505481565b6099602052806000526040600020600091509050805461058a90612449565b80601f01602080910402602001604051908101604052809291908181526020018280546105b690612449565b80156106035780601f106105d857610100808354040283529160200191610603565b820191906000526020600020905b8154815290600101906020018083116105e657829003601f168201915b505050505081565b6000606560009054906101000a900460ff16905090565b61062a610d80565b6106346000610eaa565b565b609b6020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b61067c6111c7565b609b60008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b828210156107e3578382906000526020600020906002020160405180604001604052908160008201805461074890612449565b80601f016020809104026020016040519081016040528092919081815260200182805461077490612449565b80156107c15780601f10610796576101008083540402835291602001916107c1565b820191906000526020600020905b8154815290600101906020018083116107a457829003601f168201915b5050505050815260200160018201548152505081526020019060010190610715565b50505050815250509050919050565b60008060019054906101000a900460ff161590508080156108235750600160008054906101000a900460ff1660ff16105b80610850575061083230610f70565b15801561084f5750600160008054906101000a900460ff1660ff16145b5b61088f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161088690611b33565b60405180910390fd5b60016000806101000a81548160ff021916908360ff16021790555080156108cc576001600060016101000a81548160ff0219169083151502179055505b6108d4610f93565b6108dc610fec565b6108e4611045565b801561093d5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516109349190611a36565b60405180910390a15b50565b6000609a83836040516109549291906119e7565b908152602001604051809103902054905092915050565b610973610d80565b61097b6110a8565b610983611045565b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6109b7610d80565b6109bf610dfe565b8060978190555050565b60975481565b600082826000609a83836040516109e79291906119e7565b90815260200160405180910390205414610a36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a2d90611b13565b60405180910390fd5b610a3e6110a8565b600060975490508585609960008481526020019081526020016000209190610a679291906111f7565b5080609a8787604051610a7b9291906119e7565b9081526020016040518091039020819055507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d818787604051610ac093929190611bf0565b60405180910390a160976000815480929190610adb906124c8565b919050555080935050505092915050565b609860009054906101000a900460ff1681565b81816000609a8383604051610b159291906119e7565b90815260200160405180910390205414610b64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b5b90611b13565b60405180910390fd5b610b6c6110a8565b6000609960008781526020019081526020016000208054610b8c90612449565b905014610bce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bc590611a93565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16609b600087815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610c72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6990611b93565b60405180910390fd5b8383609960008881526020019081526020016000209190610c949291906111f7565b5084609a8585604051610ca89291906119e7565b9081526020016040518091039020819055507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c858585604051610ced93929190611bf0565b60405180910390a15050505050565b610d04610d80565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610d74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6b90611ab3565b60405180910390fd5b610d7d81610eaa565b50565b610d886110f2565b73ffffffffffffffffffffffffffffffffffffffff16610da6610985565b73ffffffffffffffffffffffffffffffffffffffff1614610dfc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610df390611b53565b60405180910390fd5b565b610e0661060b565b610e45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e3c90611a73565b60405180910390fd5b565b610e4f610dfe565b6000606560006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610e936110f2565b604051610ea09190611a00565b60405180910390a1565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610fe2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fd990611b73565b60405180910390fd5b610fea6110fa565b565b600060019054906101000a900460ff1661103b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103290611b73565b60405180910390fd5b61104361115b565b565b61104d6110a8565b6001606560006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586110916110f2565b60405161109e9190611a00565b60405180910390a1565b6110b061060b565b156110f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110e790611af3565b60405180910390fd5b565b600033905090565b600060019054906101000a900460ff16611149576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161114090611b73565b60405180910390fd5b6111596111546110f2565b610eaa565b565b600060019054906101000a900460ff166111aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111a190611b73565b60405180910390fd5b6000606560006101000a81548160ff021916908315150217905550565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b82805461120390612449565b90600052602060002090601f016020900481019282611225576000855561126c565b82601f1061123e57803560ff191683800117855561126c565b8280016001018555821561126c579182015b8281111561126b578235825591602001919060010190611250565b5b509050611279919061127d565b5090565b5b8082111561129657600081600090555060010161127e565b5090565b60006112ad6112a884611d49565b611d24565b9050828152602081018484840111156112c557600080fd5b6112d084828561237b565b509392505050565b6000813590506112e781612b59565b92915050565b60008083601f8401126112ff57600080fd5b8235905067ffffffffffffffff81111561131857600080fd5b60208301915083600182028301111561133057600080fd5b9250929050565b600082601f83011261134857600080fd5b813561135884826020860161129a565b91505092915050565b60006040828403121561137357600080fd5b81905092915050565b60008135905061138b81612b70565b92915050565b6000602082840312156113a357600080fd5b60006113b1848285016112d8565b91505092915050565b600080602083850312156113cd57600080fd5b600083013567ffffffffffffffff8111156113e757600080fd5b6113f3858286016112ed565b92509250509250929050565b60006020828403121561141157600080fd5b600082013567ffffffffffffffff81111561142b57600080fd5b61143784828501611337565b91505092915050565b60006020828403121561145257600080fd5b60006114608482850161137c565b91505092915050565b60008060006040848603121561147e57600080fd5b600061148c8682870161137c565b935050602084013567ffffffffffffffff8111156114a957600080fd5b6114b5868287016112ed565b92509250509250925092565b600080604083850312156114d457600080fd5b60006114e28582860161137c565b925050602083013567ffffffffffffffff8111156114ff57600080fd5b61150b85828601611361565b9150509250929050565b6000611521838361193d565b905092915050565b6000611535838361198c565b905092915050565b611546816120c3565b82525050565b611555816120c3565b82525050565b60006115678385611e26565b93508360208402850161157984611d91565b8060005b878110156115bd578484038952611594828461202e565b61159e8582611515565b94506115a983611e0c565b925060208a0199505060018101905061157d565b50829750879450505050509392505050565b60006115da82611de0565b6115e48185611e26565b9350836020820285016115f685611d9b565b8060005b8581101561163257848403895281516116138582611529565b945061161e83611e19565b925060208a019950506001810190506115fa565b50829750879550505050505092915050565b61164d816120d5565b82525050565b61165c816121be565b82525050565b600061166e8385611e37565b935061167b83858461237b565b6116848361271f565b840190509392505050565b600061169b8385611e48565b93506116a883858461237b565b6116b18361271f565b840190509392505050565b60006116c88385611e59565b93506116d583858461237b565b82840190509392505050565b60006116ec82611e01565b6116f68185611e37565b935061170681856020860161238a565b61170f8161271f565b840191505092915050565b600061172582611e01565b61172f8185611e48565b935061173f81856020860161238a565b6117488161271f565b840191505092915050565b6000611760601483611e48565b915061176b826127ab565b602082019050919050565b6000611783601583611e48565b915061178e826127d4565b602082019050919050565b60006117a6602683611e48565b91506117b1826127fd565b604082019050919050565b60006117c9601383611e48565b91506117d48261284c565b602082019050919050565b60006117ec601083611e48565b91506117f782612875565b602082019050919050565b600061180f601983611e48565b915061181a8261289e565b602082019050919050565b6000611832602e83611e48565b915061183d826128c7565b604082019050919050565b6000611855602083611e48565b915061186082612916565b602082019050919050565b6000611878602b83611e48565b91506118838261293f565b604082019050919050565b600061189b601983611e48565b91506118a68261298e565b602082019050919050565b6000604083016118c46000840184611f69565b6118d1600086018261153d565b506118df6020840184611f80565b85830360208701526118f283828461155b565b925050508091505092915050565b6000604083016000830151611918600086018261153d565b506020830151848203602086015261193082826115cf565b9150508091505092915050565b6000604083016119506000840184611fd7565b8583036000870152611963838284611662565b925050506119746020840184612052565b61198160208601826119c9565b508091505092915050565b600060408301600083015184820360008601526119a982826116e1565b91505060208301516119be60208601826119c9565b508091505092915050565b6119d281612101565b82525050565b6119e181612101565b82525050565b60006119f48284866116bc565b91508190509392505050565b6000602082019050611a15600083018461154c565b92915050565b6000602082019050611a306000830184611644565b92915050565b6000602082019050611a4b6000830184611653565b92915050565b60006020820190508181036000830152611a6b818461171a565b905092915050565b60006020820190508181036000830152611a8c81611753565b9050919050565b60006020820190508181036000830152611aac81611776565b9050919050565b60006020820190508181036000830152611acc81611799565b9050919050565b60006020820190508181036000830152611aec816117bc565b9050919050565b60006020820190508181036000830152611b0c816117df565b9050919050565b60006020820190508181036000830152611b2c81611802565b9050919050565b60006020820190508181036000830152611b4c81611825565b9050919050565b60006020820190508181036000830152611b6c81611848565b9050919050565b60006020820190508181036000830152611b8c8161186b565b9050919050565b60006020820190508181036000830152611bac8161188e565b9050919050565b60006020820190508181036000830152611bcd8184611900565b905092915050565b6000602082019050611bea60008301846119d8565b92915050565b6000604082019050611c0560008301866119d8565b8181036020830152611c1881848661168f565b9050949350505050565b6000604082019050611c3760008301856119d8565b8181036020830152611c4981846118b1565b90509392505050565b60008083356001602003843603038112611c6b57600080fd5b80840192508235915067ffffffffffffffff821115611c8957600080fd5b602083019250602082023603831315611ca157600080fd5b509250929050565b60008083356001602003843603038112611cc257600080fd5b80840192508235915067ffffffffffffffff821115611ce057600080fd5b602083019250600182023603831315611cf857600080fd5b509250929050565b600082356001604003833603038112611d1857600080fd5b80830191505092915050565b6000611d2e611d3f565b9050611d3a8282612497565b919050565b6000604051905090565b600067ffffffffffffffff821115611d6457611d636125bc565b5b611d6d8261271f565b9050602081019050919050565b6000819050611d8a826002612069565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6020841060008114611ebd57601f841160018114611e8d57611e86868561247b565b8355611eb7565b611e9683611dc0565b611eab6020601f880104820160018301612126565b611eb587856129b7565b505b50611f06565b611ec682611dc0565b6020601f8701048101601f87168015611ee757611ee681600184036125eb565b5b611ef96020601f890104840183612126565b6001886002021785555050505b5050505050565b6020831060008114611f58576020851060008114611f3657611f2f868561247b565b8355611f52565b8360ff1916935083611f4784611dc0565b556001866002020183555b50611f62565b6001856002020182555b5050505050565b6000611f7860208401846112d8565b905092915050565b60008083356001602003843603038112611f9957600080fd5b83810192508235915060208301925067ffffffffffffffff821115611fbd57600080fd5b602082023603841315611fcf57600080fd5b509250929050565b60008083356001602003843603038112611ff057600080fd5b83810192508235915060208301925067ffffffffffffffff82111561201457600080fd5b60018202360384131561202657600080fd5b509250929050565b60008235600160400383360303811261204657600080fd5b82810191505092915050565b6000612061602084018461137c565b905092915050565b600061207482612101565b915061207f83612101565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156120b8576120b761255e565b5b828202905092915050565b60006120ce826120e1565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b6121236000826126ca565b50565b5b818110156121455761213a600082612793565b600181019050612127565b5050565b5b818110156121685761215d600082612775565b60028101905061214a565b5050565b8181101561218a5761217f600082612793565b60018101905061216c565b5050565b61219b6000808301612757565b6121a9600060018301612793565b50565b60006121b7826121d0565b9050919050565b60006121c98261210b565b9050919050565b60006121db826121e2565b9050919050565b60006121ed826120e1565b9050919050565b60006121ff82612101565b9050919050565b6122108383611dd5565b61221a8183612666565b61222383611d91565b61222c83611dab565b6000805b84811015612265576122428488611d00565b61224d818486612b16565b60208501945060028401935050600181019050612230565b5050505050505050565b6122798383611df6565b67ffffffffffffffff811115612292576122916125bc565b5b61229c8254612449565b600080601f8411601f841117156122b9576122b685611dc0565b90505b601f8311156122ec576020601f850104810160208510156122d8578190505b6122ea6020601f860104830182612126565b505b601f8411600181146123195760008515612307578388013590505b612311868261247b565b875550612371565b601f1985168260005b8281101561234757858a01358255600182019150602086019550602081019050612322565b8783101561236457858a0135612360601f8a1682612511565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b838110156123a857808201518184015260208101905061238d565b838111156123b7576000848401525b50505050565b6000810160008301806123cf8161263a565b90506123db8184612aa2565b50505060018101602083016123f08185611c52565b6123fb818386612ac5565b505050505050565b60008101600083016124158185611ca9565b612420818386612ad5565b5050505060018101602083018061243681612650565b90506124428184612af3565b5050505050565b6000600282049050600182168061246157607f821691505b602082108114156124755761247461258d565b5b50919050565b60006124878383612511565b9150826002028217905092915050565b6124a08261271f565b810181811067ffffffffffffffff821117156124bf576124be6125bc565b5b80604052505050565b60006124d382612101565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156125065761250561255e565b5b600182019050919050565b60006125226000198460080261274a565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61261b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8360200360080261274a565b815481168255505050565b6000819050919050565b6000819050919050565b6000813561264781612b59565b80915050919050565b6000813561265d81612b70565b80915050919050565b680100000000000000008211156126805761267f6125bc565b5b61268981611deb565b828255808310156126c55761269d81611d7a565b6126a684611d7a565b6126af84611dab565b8181018382016126bf8183612149565b50505050505b505050565b680100000000000000008211156126e4576126e36125bc565b5b80546126ef81612449565b808411156127045761270384828486611f0d565b5b808410156127195761271884828486611e64565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b600082146127685761276761252f565b5b61277181612118565b5050565b600082146127865761278561252f565b5b61278f8161218e565b5050565b61279b612b87565b6127a6818484612b34565b505050565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f6d6967726174696f6e2069732066726f7a656e00000000000000000000000000600082015250565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b7f73747265616d20616c7265616479206861732061206450494400000000000000600082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b6129c081611dc0565b6129cb83825461247b565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff6129f884612730565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612a3a84612730565b9350801983169250808416831791505092915050565b600060088302612a807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261273d565b612a8a868361273d565b95508019841693508086168417925050509392505050565b612aab826121ac565b612abe612ab782612626565b83546129d8565b8255505050565b612ad0838383612206565b505050565b612ae083838361226f565b505050565b612aef82826123bd565b5050565b612afc826121f4565b612b0f612b0882612630565b8354612a0e565b8255505050565b8115612b2557612b2461252f565b5b612b2f8382612403565b505050565b612b3d836121f4565b612b51612b4982612630565b848454612a50565b825550505050565b612b62816120c3565b8114612b6d57600080fd5b50565b612b7981612101565b8114612b8457600080fd5b50565b60009056fea264697066735822122025321e8b3f610ad6d87a9b3497059176ff710a769edbe017d76013391f10763b64736f6c63430008040033"; type DpidAliasRegistryConstructorParams = | [signer?: Signer] diff --git a/desci-contracts/typechain-types/factories/PausableUpgradeable__factory.ts b/desci-contracts/typechain-types/factories/PausableUpgradeable__factory.ts new file mode 100644 index 00000000..8fd62b94 --- /dev/null +++ b/desci-contracts/typechain-types/factories/PausableUpgradeable__factory.ts @@ -0,0 +1,78 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +import { Contract, Signer, utils } from "ethers"; +import { Provider } from "@ethersproject/providers"; +import type { + PausableUpgradeable, + PausableUpgradeableInterface, +} from "../PausableUpgradeable"; + +const _abi = [ + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint8", + name: "version", + type: "uint8", + }, + ], + name: "Initialized", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "account", + type: "address", + }, + ], + name: "Paused", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "account", + type: "address", + }, + ], + name: "Unpaused", + type: "event", + }, + { + inputs: [], + name: "paused", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, +]; + +export class PausableUpgradeable__factory { + static readonly abi = _abi; + static createInterface(): PausableUpgradeableInterface { + return new utils.Interface(_abi) as PausableUpgradeableInterface; + } + static connect( + address: string, + signerOrProvider: Signer | Provider + ): PausableUpgradeable { + return new Contract(address, _abi, signerOrProvider) as PausableUpgradeable; + } +} diff --git a/desci-contracts/typechain-types/hardhat.d.ts b/desci-contracts/typechain-types/hardhat.d.ts index 116bf02c..b99c3c37 100644 --- a/desci-contracts/typechain-types/hardhat.d.ts +++ b/desci-contracts/typechain-types/hardhat.d.ts @@ -20,6 +20,10 @@ declare module "hardhat/types/runtime" { name: "Initializable", signerOrOptions?: ethers.Signer | FactoryOptions ): Promise; + getContractFactory( + name: "PausableUpgradeable", + signerOrOptions?: ethers.Signer | FactoryOptions + ): Promise; getContractFactory( name: "ERC721Upgradeable", signerOrOptions?: ethers.Signer | FactoryOptions @@ -119,6 +123,11 @@ declare module "hardhat/types/runtime" { address: string, signer?: ethers.Signer ): Promise; + getContractAt( + name: "PausableUpgradeable", + address: string, + signer?: ethers.Signer + ): Promise; getContractAt( name: "ERC721Upgradeable", address: string, diff --git a/desci-contracts/typechain-types/index.ts b/desci-contracts/typechain-types/index.ts index 5b992f0f..ce39e83c 100644 --- a/desci-contracts/typechain-types/index.ts +++ b/desci-contracts/typechain-types/index.ts @@ -3,6 +3,7 @@ /* eslint-disable */ export type { OwnableUpgradeable } from "./OwnableUpgradeable"; export type { Initializable } from "./Initializable"; +export type { PausableUpgradeable } from "./PausableUpgradeable"; export type { ERC721Upgradeable } from "./ERC721Upgradeable"; export type { IERC721MetadataUpgradeable } from "./IERC721MetadataUpgradeable"; export type { IERC721ReceiverUpgradeable } from "./IERC721ReceiverUpgradeable"; @@ -28,6 +29,7 @@ export type { VersionedERC721V2 } from "./VersionedERC721V2"; export { OwnableUpgradeable__factory } from "./factories/OwnableUpgradeable__factory"; export { Initializable__factory } from "./factories/Initializable__factory"; +export { PausableUpgradeable__factory } from "./factories/PausableUpgradeable__factory"; export { ERC721Upgradeable__factory } from "./factories/ERC721Upgradeable__factory"; export { IERC721MetadataUpgradeable__factory } from "./factories/IERC721MetadataUpgradeable__factory"; export { IERC721ReceiverUpgradeable__factory } from "./factories/IERC721ReceiverUpgradeable__factory"; From 4000971b891b6a5f40a854b4126019e30e29c821 Mon Sep 17 00:00:00 2001 From: m0ar Date: Sun, 2 Jun 2024 12:00:58 +0200 Subject: [PATCH 123/278] contracts: alias registry migration scripts, expand tests --- .../scripts/migrateToAliasRegistry.mjs | 42 +++++++++++------ .../scripts/syncAliasRegistryMigration.mjs | 46 ++++++++++++++++--- desci-contracts/test/DpidAliasRegistry.ts | 19 +++++--- 3 files changed, 81 insertions(+), 26 deletions(-) diff --git a/desci-contracts/scripts/migrateToAliasRegistry.mjs b/desci-contracts/scripts/migrateToAliasRegistry.mjs index 0ac02c1d..e650b446 100644 --- a/desci-contracts/scripts/migrateToAliasRegistry.mjs +++ b/desci-contracts/scripts/migrateToAliasRegistry.mjs @@ -1,13 +1,31 @@ +/** + * ALIAS REGISTRY MIGRATION + * + * Deploys a new dPID alias registry, through proxy. Imports existing dPID's as + * legacy entries, and validates the correctness of these imports afterward. + * If the imports are interrupted, it can be continued using the syncAliasRegistryMigration.mjs + * script. The registry is initialized in a paused state, meaning minting new dPID's + * is disabled, but imports and other administration like configuring the dPID + * counter can still be done. + * + * The script performs the following actions: + * - Deploys new instance of the registry + * - Imports legacy dPID's, validating correctness + * - Immediately pauses minting of new dPID's + * + * Steps required to fully activate: + * - Admin calls `setNextDpid` to whatever is the next when legacy contract is disabled + * - Admin calls `unpause` to allow minting new dPID's + * + * Required arguments (env variables): + * 1. PRIVATE_KEY - Owner/admin identity (see hardhat.config.ts) + * 2. ENV - Environment to sync legacy entires from ("dev" or "prod") + */ import hardhat from "hardhat"; const { ethers, hardhatArguments } = hardhat; import axios from "axios"; import { writeFileSync } from "fs"; -const FIRST_DPID = process.env.FIRST_DPID; -if (FIRST_DPID === undefined) { - throw new Error("FIRST_DPID unset"); -}; - const ENV = process.env.ENV; if (ENV === undefined) { throw new Error("ENV unset"); @@ -37,7 +55,7 @@ const toImportEntry = (dpid) => [ dpid.dpid, { owner: dpid.researchObject.owner, - versions: dpid.researchObject.versions.map(v => ({cid: v.cid, time: v.time})) + versions: dpid.researchObject.versions.map(v => ({cid: v.cid, time: v.time})), }, ]; @@ -47,11 +65,9 @@ const DpidAliasRegistryFactory = await ethers.getContractFactory("DpidAliasRegis const registry = await upgrades.deployProxy( DpidAliasRegistryFactory, - [ - FIRST_DPID - ], + [], { - initializer: "initialize" + initializer: "initialize", } ); @@ -76,7 +92,7 @@ for (const [ dpid, entry ] of importEntries) { const imported = { dpid, owner: fromContract[0], - versions: fromContract[1].map(([cid, time]) => ({cid, time: ethers.BigNumber.from(time).toNumber() })) + versions: fromContract[1].map(([cid, time]) => ({cid, time: ethers.BigNumber.from(time).toNumber() })), }; console.log(`🔎 Verifying dPID ${dpid}:`); @@ -116,10 +132,10 @@ for (let i = 0; i < importEntries.length; i++) { }; }; -console.log(`❓ dPID's missing from original set: ${JSON.stringify(missingNumbers)}`) +console.log(`❓ dPID's missing from original set: ${JSON.stringify(missingNumbers)}`); const duration = Math.ceil((Date.now() - startTime) / 1000); -console.log(`🏁 migration done in ${duration}s for a total of ${totalGas} gas`) +console.log(`🏁 migration done in ${duration}s for a total of ${totalGas} gas`); const dateString = new Date().toUTCString().replaceAll(" ", "_"); const logFilePath = `migration-data/aliasRegistry_${dateString}.json`; diff --git a/desci-contracts/scripts/syncAliasRegistryMigration.mjs b/desci-contracts/scripts/syncAliasRegistryMigration.mjs index 36631517..af523065 100644 --- a/desci-contracts/scripts/syncAliasRegistryMigration.mjs +++ b/desci-contracts/scripts/syncAliasRegistryMigration.mjs @@ -1,3 +1,22 @@ +/** + * ALIAS REGISTRY MIGRATION SYNC + * + * For an already deployed alias registry, import missing delta of legacy dPID + * entries from the dpid.org API. This script is idempotent, and can hance be + * run many times. Existing entries are just validated, not edited. + * + * The script performs the following actions: + * - If an entry is missing, it is imported. + * - All entries, old and new, are be validated against the dPID API. + * - Owner address and full version history is checked. + * - If an entry fails validate, a warning is printed. The issue is not fixed. + * - Manually running import of the failing dPID overwrites the erroneous entry. + * + * + * Required arguments (env variables): + * 1. REGISTRY_ADDRESS - Address of existing alias registry (proxy) contract + * 2. ENV - Environment to sync legacy entires from ("dev" or "prod") + */ import hardhat from "hardhat"; const { ethers, hardhatArguments } = hardhat; import axios from "axios"; @@ -8,9 +27,23 @@ if (REGISTRY_ADDRESS === undefined) { throw new Error("REGISTRY_ADDRESS unset"); }; +const ENV = process.env.ENV; +if (ENV === undefined) { + throw new Error("ENV unset"); +}; + +let dpidApi; +if (ENV === "dev") { + dpidApi = "dev-beta"; +} else if (ENV === "prod") { + dpidApi = "beta"; +} else { + throw new Error(`Env "${ENV} unknown (use "dev" or "prod")`); +}; + const getDpidPage = async (page) => { const { data } = await axios.get( - `https://dev-beta.dpid.org/api/v1/dpid?size=100&page=${page}` + `https://${dpidApi}.dpid.org/api/v1/dpid?size=100&page=${page}` ); return data; }; @@ -23,7 +56,7 @@ const toImportEntry = (dpid) => [ dpid.dpid, { owner: dpid.researchObject.owner, - versions: dpid.researchObject.versions.map(v => ({cid: v.cid, time: v.time})) + versions: dpid.researchObject.versions.map(v => ({cid: v.cid, time: v.time})), } ]; @@ -53,7 +86,7 @@ for (const [ dpid, entry ] of importEntries) { const imported = { dpid, owner: fromContract[0], - versions: fromContract[1].map(([cid, time]) => ({cid, time: ethers.BigNumber.from(time).toNumber() })) + versions: fromContract[1].map(([cid, time]) => ({cid, time: ethers.BigNumber.from(time).toNumber() })), }; console.log(`🔎 Verifying dPID ${dpid}:`); @@ -81,17 +114,16 @@ for (const [ dpid, entry ] of importEntries) { }; }; - results.push({ dpid, owner: imported.owner, versions: imported.versions, importError: validationError }); }; const failures = results.filter(r => r.validationError); -console.log(`🚦 dPIDs which failed validation (manually import to overwrite): ${JSON.stringify(failures)}`) +console.log(`🚦 dPIDs which failed validation (manually import to overwrite): ${JSON.stringify(failures)}`); const duration = Math.ceil((Date.now() - startTime) / 1000); -console.log(`🏁 migration done in ${duration}s for a total of ${totalGas} gas`) +console.log(`🏁 sync done in ${duration}s for a total of ${totalGas} gas`); const dateString = new Date().toUTCString().replaceAll(" ", "_"); -const logFilePath = `migration-data/aliasRegistry_${dateString}.json`; +const logFilePath = `migration-data/aliasRegistrySync_${dateString}.json`; writeFileSync(logFilePath, JSON.stringify(results, undefined, 2)); console.log(`📝 migration data written to ${logFilePath}`); diff --git a/desci-contracts/test/DpidAliasRegistry.ts b/desci-contracts/test/DpidAliasRegistry.ts index a8cb2ef3..737e7be9 100644 --- a/desci-contracts/test/DpidAliasRegistry.ts +++ b/desci-contracts/test/DpidAliasRegistry.ts @@ -13,7 +13,7 @@ use(chaiAsPromised); describe("dPID", () => { let _accounts: SignerWithAddress[]; - let owner: SignerWithAddress; + let deployerAddress: SignerWithAddress; let user1: SignerWithAddress; let user2: SignerWithAddress; let DpidAliasRegistryFactory: DpidAliasRegistry__factory; @@ -21,7 +21,7 @@ describe("dPID", () => { before( async () => { _accounts = await hhe.getSigners() - owner = _accounts[0]; + deployerAddress = _accounts[0]; user1 = _accounts[1]; user2 = _accounts[2]; @@ -53,7 +53,7 @@ describe("dPID", () => { implAddress, proxyAddress, implOwner: await dpidAliasRegistry.owner(), - }) + }); }); it("costs a reasonable amount of gas", async () => { @@ -67,9 +67,16 @@ describe("dPID", () => { expect(proxyAddress).not.to.equal(implAddress); }); + it("allows deployer to call ownership transfer of ProxyAdmin contract", async () => { + // re-set to self + const doTransfer = async () => + await upgrades.admin.transferProxyAdminOwnership(proxyAddress, deployerAddress); + await expect(doTransfer()).not.to.be.rejected; + }); + it("deploys implementation with proxy owner as owner", async () => { const registryOwner = await dpidAliasRegistry.owner(); - expect(registryOwner).to.equal(owner.address); + expect(registryOwner).to.equal(deployerAddress.address); }); it("deploys contract in paused state", async () => { @@ -164,7 +171,7 @@ describe("dPID", () => { it("can be done by contract owner", async () => { const tx = await dpidAliasRegistry - .connect(owner) + .connect(deployerAddress) .importLegacyDpid(0, migrationEntry); successReceipt = await tx.wait(); }); @@ -210,7 +217,7 @@ describe("dPID", () => { it("can NOT be done by contract owner", async () => { const doUpgrade = async () => await dpidAliasRegistry - .connect(owner) + .connect(deployerAddress) .upgradeDpid(0, STREAM_C); await expect(doUpgrade()).to.be.rejectedWith("unauthorized dpid upgrade"); From b28cf83a3b889ad7fd1e12ad2820378622fd2c96 Mon Sep 17 00:00:00 2001 From: m0ar Date: Mon, 3 Jun 2024 14:39:20 +0200 Subject: [PATCH 124/278] contracts: make dev deployment to OP Sepolia, save migration data, export address from package --- .../opSepoliaDev-dpid-alias-registry.json | 209 + desci-contracts/index.ts | 3 +- ...ry_dev__Mon,_03_Jun_2024_11:21:28_GMT.json | 4878 +++++++++++++++++ desci-contracts/package.json | 2 +- .../scripts/migrateToAliasRegistry.mjs | 4 +- .../scripts/syncAliasRegistryMigration.mjs | 35 +- 6 files changed, 5119 insertions(+), 12 deletions(-) create mode 100644 desci-contracts/.openzeppelin/opSepoliaDev-dpid-alias-registry.json create mode 100644 desci-contracts/migration-data/aliasRegistry_dev__Mon,_03_Jun_2024_11:21:28_GMT.json diff --git a/desci-contracts/.openzeppelin/opSepoliaDev-dpid-alias-registry.json b/desci-contracts/.openzeppelin/opSepoliaDev-dpid-alias-registry.json new file mode 100644 index 00000000..6af45131 --- /dev/null +++ b/desci-contracts/.openzeppelin/opSepoliaDev-dpid-alias-registry.json @@ -0,0 +1,209 @@ +{ + "manifestVersion": "3.2", + "admin": { + "address": "0x64f1dE5b953135c5cEC03DB2B99ffcA0fe11eF88", + "txHash": "0xa1134fbf6b5e3bdfc450beafff59cfb7c3e978014396d52775a304dca2bffb97" + }, + "proxies": [ + { + "address": "0x7906AC53C2F59d0Eb36dC126336322d25Da15B62", + "txHash": "0xf583111b6d255339f06748889e3adbf9fc313bcdad0480b22f4767b179c673d7", + "kind": "transparent" + } + ], + "impls": { + "e48cadec43394f09ce202bd07138068396bd5f4bf01fcb81e0856ebd63ce19bc": { + "address": "0x5f8ffCbAeAB5F7749bc3Cb333e634265C2D3DF22", + "txHash": "0x996f85a02d3bd579767511ed14a00ebe74ef6ba40319f09f049ad32797dc8d0f", + "layout": { + "solcVersion": "0.8.4", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ContextUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" + }, + { + "label": "_owner", + "offset": 0, + "slot": "51", + "type": "t_address", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" + }, + { + "label": "__gap", + "offset": 0, + "slot": "52", + "type": "t_array(t_uint256)49_storage", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" + }, + { + "label": "_paused", + "offset": 0, + "slot": "101", + "type": "t_bool", + "contract": "PausableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" + }, + { + "label": "__gap", + "offset": 0, + "slot": "102", + "type": "t_array(t_uint256)49_storage", + "contract": "PausableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" + }, + { + "label": "nextDpid", + "offset": 0, + "slot": "151", + "type": "t_uint256", + "contract": "DpidAliasRegistry", + "src": "contracts/DpidAliasRegistry.sol:10" + }, + { + "label": "migrationFrozen", + "offset": 0, + "slot": "152", + "type": "t_bool", + "contract": "DpidAliasRegistry", + "src": "contracts/DpidAliasRegistry.sol:13" + }, + { + "label": "registry", + "offset": 0, + "slot": "153", + "type": "t_mapping(t_uint256,t_string_storage)", + "contract": "DpidAliasRegistry", + "src": "contracts/DpidAliasRegistry.sol:16" + }, + { + "label": "reverseRegistry", + "offset": 0, + "slot": "154", + "type": "t_mapping(t_string_memory_ptr,t_uint256)", + "contract": "DpidAliasRegistry", + "src": "contracts/DpidAliasRegistry.sol:19" + }, + { + "label": "legacy", + "offset": 0, + "slot": "155", + "type": "t_mapping(t_uint256,t_struct(LegacyDpidEntry)845_storage)", + "contract": "DpidAliasRegistry", + "src": "contracts/DpidAliasRegistry.sol:128" + } + ], + "types": { + "t_address": { + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_struct(LegacyVersion)838_storage)dyn_storage": { + "label": "struct DpidAliasRegistry.LegacyVersion[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)49_storage": { + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "label": "bool", + "numberOfBytes": "1" + }, + "t_mapping(t_string_memory_ptr,t_uint256)": { + "label": "mapping(string => uint256)", + "numberOfBytes": "32" + }, + "t_mapping(t_uint256,t_string_storage)": { + "label": "mapping(uint256 => string)", + "numberOfBytes": "32" + }, + "t_mapping(t_uint256,t_struct(LegacyDpidEntry)845_storage)": { + "label": "mapping(uint256 => struct DpidAliasRegistry.LegacyDpidEntry)", + "numberOfBytes": "32" + }, + "t_string_memory_ptr": { + "label": "string", + "numberOfBytes": "32" + }, + "t_string_storage": { + "label": "string", + "numberOfBytes": "32" + }, + "t_struct(LegacyDpidEntry)845_storage": { + "label": "struct DpidAliasRegistry.LegacyDpidEntry", + "members": [ + { + "label": "owner", + "type": "t_address", + "offset": 0, + "slot": "0" + }, + { + "label": "versions", + "type": "t_array(t_struct(LegacyVersion)838_storage)dyn_storage", + "offset": 0, + "slot": "1" + } + ], + "numberOfBytes": "64" + }, + "t_struct(LegacyVersion)838_storage": { + "label": "struct DpidAliasRegistry.LegacyVersion", + "members": [ + { + "label": "cid", + "type": "t_string_storage", + "offset": 0, + "slot": "0" + }, + { + "label": "time", + "type": "t_uint256", + "offset": 0, + "slot": "1" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + }, + "namespaces": {} + } + } + } +} diff --git a/desci-contracts/index.ts b/desci-contracts/index.ts index 624df4a5..960d0e4d 100644 --- a/desci-contracts/index.ts +++ b/desci-contracts/index.ts @@ -6,6 +6,7 @@ import devDpidInfo from "./.openzeppelin/sepoliaDev-dpid.json"; import prodRoInfo from "./.openzeppelin/sepoliaProd-research-object.json"; import prodDpidInfo from "./.openzeppelin/sepoliaProd-dpid.json"; import localDpidAliasInfo from "./.openzeppelin/unknown-dpid-alias-registry.json"; +import devDpidAliasInfo from "./.openzeppelin/opSepoliaDev-dpid-alias-registry.json"; export const contracts = { localRoInfo, @@ -15,7 +16,7 @@ export const contracts = { prodRoInfo, prodDpidInfo, localDpidAliasInfo, + devDpidAliasInfo, // TODO update as soon as deployment is done - devDpidAliasInfo: localDpidAliasInfo, prodDpidAliasInfo: localDpidAliasInfo, }; diff --git a/desci-contracts/migration-data/aliasRegistry_dev__Mon,_03_Jun_2024_11:21:28_GMT.json b/desci-contracts/migration-data/aliasRegistry_dev__Mon,_03_Jun_2024_11:21:28_GMT.json new file mode 100644 index 00000000..bfec26fc --- /dev/null +++ b/desci-contracts/migration-data/aliasRegistry_dev__Mon,_03_Jun_2024_11:21:28_GMT.json @@ -0,0 +1,4878 @@ +{ + "address": "0x7906AC53C2F59d0Eb36dC126336322d25Da15B62", + "dpids": [ + { + "dpid": "0", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreie2idd2yuwibppujafgtfc6cczopht4q47y563q4paml2me2dsh6y", + "time": 1675737468 + }, + { + "cid": "bafkreie2idd2yuwibppujafgtfc6cczopht4q47y563q4paml2me2dsh6y", + "time": 1675737468 + } + ], + "validationError": false + }, + { + "dpid": "1", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigbp7bahnrxujbz5uu3j6hzmyimq7wijkucwyi4bc5tbvka5xw3wq", + "time": 1675781796 + }, + { + "cid": "bafkreigbp7bahnrxujbz5uu3j6hzmyimq7wijkucwyi4bc5tbvka5xw3wq", + "time": 1675781796 + }, + { + "cid": "bafkreigwzsizb76b62ln5xnhhqeypxhyqwwyp56zcprl52siut2q7h2lky", + "time": 1682818404 + }, + { + "cid": "bafkreigwzsizb76b62ln5xnhhqeypxhyqwwyp56zcprl52siut2q7h2lky", + "time": 1682818404 + }, + { + "cid": "bafkreigwzsizb76b62ln5xnhhqeypxhyqwwyp56zcprl52siut2q7h2lky", + "time": 1682818608 + }, + { + "cid": "bafkreigwzsizb76b62ln5xnhhqeypxhyqwwyp56zcprl52siut2q7h2lky", + "time": 1682818608 + } + ], + "validationError": false + }, + { + "dpid": "2", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihlsxjw3gzrikm2att6sd2yty4qx37z3fgmzokrm6fd3oony2qqby", + "time": 1676095440 + }, + { + "cid": "bafkreihlsxjw3gzrikm2att6sd2yty4qx37z3fgmzokrm6fd3oony2qqby", + "time": 1676095440 + }, + { + "cid": "bafkreigvalv7basyqxn57b5ittssieecsccy7qaypmy6s7egr2o5tcqnda", + "time": 1676096820 + }, + { + "cid": "bafkreigvalv7basyqxn57b5ittssieecsccy7qaypmy6s7egr2o5tcqnda", + "time": 1676096820 + } + ], + "validationError": false + }, + { + "dpid": "3", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiancsq3yywjzkoyevwhn4hxyzgcfbdb72jspegmwy6uacd2cztpra", + "time": 1676725008 + }, + { + "cid": "bafkreiancsq3yywjzkoyevwhn4hxyzgcfbdb72jspegmwy6uacd2cztpra", + "time": 1676725008 + } + ], + "validationError": false + }, + { + "dpid": "4", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreick32zk4ennjwwy7vqva7wpjo2w5d4fkwhg7hkrdjk63xq5r6gup4", + "time": 1676988612 + }, + { + "cid": "bafkreick32zk4ennjwwy7vqva7wpjo2w5d4fkwhg7hkrdjk63xq5r6gup4", + "time": 1676988612 + } + ], + "validationError": false + }, + { + "dpid": "5", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihra4e2ejsm7yqra4wmo2ww43j4ndvylfsrv5obobkl2k666baram", + "time": 1676996292 + }, + { + "cid": "bafkreihra4e2ejsm7yqra4wmo2ww43j4ndvylfsrv5obobkl2k666baram", + "time": 1676996292 + } + ], + "validationError": false + }, + { + "dpid": "6", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiee7atuqdvq7dtxf2msslelz2ubst2g64oigetxunn352ryqvuoti", + "time": 1677066240 + }, + { + "cid": "bafkreiee7atuqdvq7dtxf2msslelz2ubst2g64oigetxunn352ryqvuoti", + "time": 1677066240 + } + ], + "validationError": false + }, + { + "dpid": "7", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidi2idvbbbg5y6iuf3bnbdo7gkyzgoz3hik2hghr3rl3gd7nplnwe", + "time": 1677080820 + }, + { + "cid": "bafkreidi2idvbbbg5y6iuf3bnbdo7gkyzgoz3hik2hghr3rl3gd7nplnwe", + "time": 1677080820 + }, + { + "cid": "bafkreicyvzgk632l2zn55dkbscjrwrlrxlckrxjhpxn6kiv4roegwzprpi", + "time": 1677081012 + }, + { + "cid": "bafkreicyvzgk632l2zn55dkbscjrwrlrxlckrxjhpxn6kiv4roegwzprpi", + "time": 1677081012 + } + ], + "validationError": false + }, + { + "dpid": "8", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibnhuq4tliestyutqxrfco4wwr3gxyrp7dlydxvgkddo6euet5yyu", + "time": 1677144720 + }, + { + "cid": "bafkreibnhuq4tliestyutqxrfco4wwr3gxyrp7dlydxvgkddo6euet5yyu", + "time": 1677144720 + } + ], + "validationError": false + }, + { + "dpid": "9", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigjjlyedw3l7yfunjhaooe226hemiqz7pkeqb3arfmwvujknaa7pe", + "time": 1677230328 + }, + { + "cid": "bafkreigjjlyedw3l7yfunjhaooe226hemiqz7pkeqb3arfmwvujknaa7pe", + "time": 1677230328 + } + ], + "validationError": false + }, + { + "dpid": "10", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihbcdgctujsajvlhbbcghfkg766pprlgatvujzkw6utteryn737wi", + "time": 1677510672 + }, + { + "cid": "bafkreihbcdgctujsajvlhbbcghfkg766pprlgatvujzkw6utteryn737wi", + "time": 1677510672 + }, + { + "cid": "bafkreif6omh6d2nosj7exr4gybupz3i6owb7ig7mfha23bebzbbzgtj3ty", + "time": 1677511224 + }, + { + "cid": "bafkreif6omh6d2nosj7exr4gybupz3i6owb7ig7mfha23bebzbbzgtj3ty", + "time": 1677511224 + } + ], + "validationError": false + }, + { + "dpid": "11", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreig75cxpsu2zhnkej7nwqszduw6l32luo3opikzsqa5wpfchnl7sua", + "time": 1678309056 + }, + { + "cid": "bafkreig75cxpsu2zhnkej7nwqszduw6l32luo3opikzsqa5wpfchnl7sua", + "time": 1678309056 + } + ], + "validationError": false + }, + { + "dpid": "12", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigvec6jtxth3eessemov7x62wjhtfpfihdleanekwx5l47rkxclcu", + "time": 1678771692 + }, + { + "cid": "bafkreigvec6jtxth3eessemov7x62wjhtfpfihdleanekwx5l47rkxclcu", + "time": 1678771692 + } + ], + "validationError": false + }, + { + "dpid": "13", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreienztazc23yp5ejvwymgekqf2kmx6foasxul7yzt6w5crjwceqsea", + "time": 1678814328 + }, + { + "cid": "bafkreienztazc23yp5ejvwymgekqf2kmx6foasxul7yzt6w5crjwceqsea", + "time": 1678814328 + }, + { + "cid": "bafkreid4yx77dkhlbmx2gqwwki6y2rjmuybnqkxqmxnoyjtx7uhgdkdeu4", + "time": 1680117252 + }, + { + "cid": "bafkreid4yx77dkhlbmx2gqwwki6y2rjmuybnqkxqmxnoyjtx7uhgdkdeu4", + "time": 1680117252 + } + ], + "validationError": false + }, + { + "dpid": "14", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiasx7tcckutok7a7yk7ej2pv6bolo5naihlk2gny6tpykcfvzxqm4", + "time": 1679014104 + }, + { + "cid": "bafkreiasx7tcckutok7a7yk7ej2pv6bolo5naihlk2gny6tpykcfvzxqm4", + "time": 1679014104 + } + ], + "validationError": false + }, + { + "dpid": "15", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifjuqlmsnnr2vlhwxrjsgu5zczwgodqjuzmo4kzgpzzu5zn42ivby", + "time": 1679219244 + }, + { + "cid": "bafkreifjuqlmsnnr2vlhwxrjsgu5zczwgodqjuzmo4kzgpzzu5zn42ivby", + "time": 1679219244 + }, + { + "cid": "bafkreiar3d6vkcyvfnk7kfhu4yrvul6hsn4fnjrwgq7wbl27t4e3ehfhwq", + "time": 1679219328 + }, + { + "cid": "bafkreiar3d6vkcyvfnk7kfhu4yrvul6hsn4fnjrwgq7wbl27t4e3ehfhwq", + "time": 1679219328 + }, + { + "cid": "bafkreiar3d6vkcyvfnk7kfhu4yrvul6hsn4fnjrwgq7wbl27t4e3ehfhwq", + "time": 1679219484 + }, + { + "cid": "bafkreiar3d6vkcyvfnk7kfhu4yrvul6hsn4fnjrwgq7wbl27t4e3ehfhwq", + "time": 1679219484 + } + ], + "validationError": false + }, + { + "dpid": "16", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreig27rnst73rqnqgtesyo32xhrhaqtdxbvtdohwnjdzua7cyapghbu", + "time": 1679343324 + }, + { + "cid": "bafkreig27rnst73rqnqgtesyo32xhrhaqtdxbvtdohwnjdzua7cyapghbu", + "time": 1679343324 + } + ], + "validationError": false + }, + { + "dpid": "17", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigggibyev5x4w3tcydslfl3j5g2fl2sabfcxvdzqeajzfg3tqignq", + "time": 1679409324 + }, + { + "cid": "bafkreigggibyev5x4w3tcydslfl3j5g2fl2sabfcxvdzqeajzfg3tqignq", + "time": 1679409324 + } + ], + "validationError": false + }, + { + "dpid": "18", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigghoctitgbpsjl6elgjkdlpu26t6zon7gqfx7cuhprsyykcjgvee", + "time": 1679409744 + }, + { + "cid": "bafkreigghoctitgbpsjl6elgjkdlpu26t6zon7gqfx7cuhprsyykcjgvee", + "time": 1679409744 + } + ], + "validationError": false + }, + { + "dpid": "19", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicvdmmzw7tyaa7dkaikb7dcowjjbu3cv76rhvxqdbzm7gcg4inrfq", + "time": 1679539764 + }, + { + "cid": "bafkreicvdmmzw7tyaa7dkaikb7dcowjjbu3cv76rhvxqdbzm7gcg4inrfq", + "time": 1679539764 + } + ], + "validationError": false + }, + { + "dpid": "20", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreie6bxf7u3z45sn2amk7ocsjihloiecfncmwsgvqoamqjnczfwnexy", + "time": 1679540424 + }, + { + "cid": "bafkreie6bxf7u3z45sn2amk7ocsjihloiecfncmwsgvqoamqjnczfwnexy", + "time": 1679540424 + }, + { + "cid": "bafkreibnxznsx2xwdasyhjr2epkypjohuvz5qy35iu2elyoygjnfbk7im4", + "time": 1680554796 + }, + { + "cid": "bafkreibnxznsx2xwdasyhjr2epkypjohuvz5qy35iu2elyoygjnfbk7im4", + "time": 1680554796 + } + ], + "validationError": false + }, + { + "dpid": "21", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiecholb67ldemsvyr7js2x6dewjnsylvpk47ejyhrokkbnqbl4i4y", + "time": 1679637204 + }, + { + "cid": "bafkreiecholb67ldemsvyr7js2x6dewjnsylvpk47ejyhrokkbnqbl4i4y", + "time": 1679637204 + }, + { + "cid": "bafkreih6jpxxvs5ruwhfms7t4kg3qv27x6cf4qn7rzoffcjhgctjjcn7my", + "time": 1679637252 + }, + { + "cid": "bafkreih6jpxxvs5ruwhfms7t4kg3qv27x6cf4qn7rzoffcjhgctjjcn7my", + "time": 1679637252 + }, + { + "cid": "bafkreih6jpxxvs5ruwhfms7t4kg3qv27x6cf4qn7rzoffcjhgctjjcn7my", + "time": 1679637288 + }, + { + "cid": "bafkreih6jpxxvs5ruwhfms7t4kg3qv27x6cf4qn7rzoffcjhgctjjcn7my", + "time": 1679637288 + } + ], + "validationError": false + }, + { + "dpid": "22", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreid4d4543faobctzfxh53tfa7u2q7jwqll7g3o52b6ko2vxbq6gya4", + "time": 1679658768 + }, + { + "cid": "bafkreid4d4543faobctzfxh53tfa7u2q7jwqll7g3o52b6ko2vxbq6gya4", + "time": 1679658768 + } + ], + "validationError": false + }, + { + "dpid": "23", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifzp4vuudwvek33rcft2rd2szjrimey7yezcsbm2awkx2tjsunwwi", + "time": 1680567024 + }, + { + "cid": "bafkreifzp4vuudwvek33rcft2rd2szjrimey7yezcsbm2awkx2tjsunwwi", + "time": 1680567024 + } + ], + "validationError": false + }, + { + "dpid": "24", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicqcgfswelv7jvt3o5mirsrwbegst354jzl5znfhsysfi5kwa5oem", + "time": 1681191960 + }, + { + "cid": "bafkreicqcgfswelv7jvt3o5mirsrwbegst354jzl5znfhsysfi5kwa5oem", + "time": 1681191960 + } + ], + "validationError": false + }, + { + "dpid": "25", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiai7ekqchod7c7na6bsc5aeicugtqr2ai4jhdyjal4ukzzjdoxdoi", + "time": 1681495752 + }, + { + "cid": "bafkreiai7ekqchod7c7na6bsc5aeicugtqr2ai4jhdyjal4ukzzjdoxdoi", + "time": 1681495752 + } + ], + "validationError": false + }, + { + "dpid": "26", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiasg744hrz2h6tkkw4a2z55orh33v5rs2j62mx3arsuqxa5dppyzq", + "time": 1681497684 + }, + { + "cid": "bafkreiasg744hrz2h6tkkw4a2z55orh33v5rs2j62mx3arsuqxa5dppyzq", + "time": 1681497684 + }, + { + "cid": "bafkreicbh5ytfk7ohfa7tw44q5nmjkzmqseiesoskwcjntwc6apx7ifyyi", + "time": 1681497900 + }, + { + "cid": "bafkreicbh5ytfk7ohfa7tw44q5nmjkzmqseiesoskwcjntwc6apx7ifyyi", + "time": 1681497900 + } + ], + "validationError": false + }, + { + "dpid": "27", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiehj4xqrpk5m6sdemt5nv6ktb5uxp6ihmg3apdwiu6xhkjzlcmuka", + "time": 1681505184 + }, + { + "cid": "bafkreiehj4xqrpk5m6sdemt5nv6ktb5uxp6ihmg3apdwiu6xhkjzlcmuka", + "time": 1681505184 + } + ], + "validationError": false + }, + { + "dpid": "28", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihmuuks36pyt5quuvjbxkhyu6lhdf3sfbqvfii6j2gemwpu2uc67q", + "time": 1681506588 + }, + { + "cid": "bafkreihmuuks36pyt5quuvjbxkhyu6lhdf3sfbqvfii6j2gemwpu2uc67q", + "time": 1681506588 + } + ], + "validationError": false + }, + { + "dpid": "29", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigifwmh35byvn2yzg2vojm6r6qpjyoce6dfdsacmch336adgqmyee", + "time": 1681736556 + }, + { + "cid": "bafkreigifwmh35byvn2yzg2vojm6r6qpjyoce6dfdsacmch336adgqmyee", + "time": 1681736556 + }, + { + "cid": "bafkreicxifdkouaya7pzrj2upqft2c637t6awklqjsbd76dfog42hxvlqu", + "time": 1681736628 + }, + { + "cid": "bafkreicxifdkouaya7pzrj2upqft2c637t6awklqjsbd76dfog42hxvlqu", + "time": 1681736628 + } + ], + "validationError": false + }, + { + "dpid": "30", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidtjqvqyoq7ehafmy7vvhjlewgtxkxaqr7anwtwtgkzvlogmfwaey", + "time": 1681761420 + }, + { + "cid": "bafkreidtjqvqyoq7ehafmy7vvhjlewgtxkxaqr7anwtwtgkzvlogmfwaey", + "time": 1681761420 + }, + { + "cid": "bafkreif6imae7ikphst6f2opahy2bn4qnm3srzj4rmnpdhrqtykwr6c4yu", + "time": 1681762272 + }, + { + "cid": "bafkreif6imae7ikphst6f2opahy2bn4qnm3srzj4rmnpdhrqtykwr6c4yu", + "time": 1681762272 + } + ], + "validationError": false + }, + { + "dpid": "31", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiahcqh7zzoz27gzh2chwto2u5kabmf2vmca3xbmzrlmgoqucrmfky", + "time": 1681805808 + }, + { + "cid": "bafkreiahcqh7zzoz27gzh2chwto2u5kabmf2vmca3xbmzrlmgoqucrmfky", + "time": 1681805808 + } + ], + "validationError": false + }, + { + "dpid": "32", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiaakpmpc5jr4bp3puzzpdjv5nh3maunzbaug2p335ngmdfsfekkxe", + "time": 1681830960 + }, + { + "cid": "bafkreiaakpmpc5jr4bp3puzzpdjv5nh3maunzbaug2p335ngmdfsfekkxe", + "time": 1681830960 + } + ], + "validationError": false + }, + { + "dpid": "33", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreic2zkjdknqf5kfelzzstfovdwuc2dolbaej7eduedn6md7rpfo27y", + "time": 1682014560 + }, + { + "cid": "bafkreic2zkjdknqf5kfelzzstfovdwuc2dolbaej7eduedn6md7rpfo27y", + "time": 1682014560 + } + ], + "validationError": false + }, + { + "dpid": "34", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibkbhhedb3yazc6rze6772ouoymv3yy5vqmilmwi6eq7yuw3n6tue", + "time": 1682144088 + }, + { + "cid": "bafkreibkbhhedb3yazc6rze6772ouoymv3yy5vqmilmwi6eq7yuw3n6tue", + "time": 1682144088 + } + ], + "validationError": false + }, + { + "dpid": "35", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreih4kylr5z5oppj6wprw2luiyngsn3xq324kfbiku4ehi42dess4oi", + "time": 1682534976 + }, + { + "cid": "bafkreih4kylr5z5oppj6wprw2luiyngsn3xq324kfbiku4ehi42dess4oi", + "time": 1682534976 + }, + { + "cid": "bafkreidasu577tdw76nprafzy7oa42nlr6gcyk45agx3tawrw3zyxu7mva", + "time": 1682746284 + }, + { + "cid": "bafkreidasu577tdw76nprafzy7oa42nlr6gcyk45agx3tawrw3zyxu7mva", + "time": 1682746284 + }, + { + "cid": "bafkreieaozkgywz6vonai3kmhr6cct5jjpeau3lhy2zrb2ft3dsnudaxym", + "time": 1682813004 + }, + { + "cid": "bafkreieaozkgywz6vonai3kmhr6cct5jjpeau3lhy2zrb2ft3dsnudaxym", + "time": 1682813004 + } + ], + "validationError": false + }, + { + "dpid": "36", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifc4so5xny7vpkj62oejlxlnh2zp6w76idbvx3mi2t5nkhxpbenbe", + "time": 1682670864 + }, + { + "cid": "bafkreifc4so5xny7vpkj62oejlxlnh2zp6w76idbvx3mi2t5nkhxpbenbe", + "time": 1682670864 + } + ], + "validationError": false + }, + { + "dpid": "37", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiadoa3b3hvlzpfliappjvhzoacqst2tnu5x7cjvhwcdjhplqakmmy", + "time": 1682793228 + }, + { + "cid": "bafkreiadoa3b3hvlzpfliappjvhzoacqst2tnu5x7cjvhwcdjhplqakmmy", + "time": 1682793228 + }, + { + "cid": "bafkreiad7vwyvhxpgy5i6azrynsnu5g2x5ef7iwjafbnnvukkbc7dvygru", + "time": 1682793408 + }, + { + "cid": "bafkreiad7vwyvhxpgy5i6azrynsnu5g2x5ef7iwjafbnnvukkbc7dvygru", + "time": 1682793408 + } + ], + "validationError": false + }, + { + "dpid": "38", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiagyoholq6ypx4pdby56vfzq7a44q3sn6esvho7wcf6m4eghpcjoa", + "time": 1682813880 + }, + { + "cid": "bafkreiagyoholq6ypx4pdby56vfzq7a44q3sn6esvho7wcf6m4eghpcjoa", + "time": 1682813880 + }, + { + "cid": "bafkreiapfszw7l5sysx2hgophrztwyeonpppem2xxwbujhhwa5kipypyky", + "time": 1682814000 + }, + { + "cid": "bafkreiapfszw7l5sysx2hgophrztwyeonpppem2xxwbujhhwa5kipypyky", + "time": 1682814000 + }, + { + "cid": "bafkreiapfszw7l5sysx2hgophrztwyeonpppem2xxwbujhhwa5kipypyky", + "time": 1682822136 + }, + { + "cid": "bafkreiapfszw7l5sysx2hgophrztwyeonpppem2xxwbujhhwa5kipypyky", + "time": 1682822136 + } + ], + "validationError": false + }, + { + "dpid": "39", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibtewpmyizn2rvgbd7yqzirfcunu264zqwjc6qmf32wwtocp57eta", + "time": 1682820372 + }, + { + "cid": "bafkreibtewpmyizn2rvgbd7yqzirfcunu264zqwjc6qmf32wwtocp57eta", + "time": 1682820372 + }, + { + "cid": "bafkreiayluo2hglsq2qfahpzwqopgwaad7bqxma5we6l2bqzs2zfvk6eka", + "time": 1682820648 + }, + { + "cid": "bafkreiayluo2hglsq2qfahpzwqopgwaad7bqxma5we6l2bqzs2zfvk6eka", + "time": 1682820648 + }, + { + "cid": "bafkreiayluo2hglsq2qfahpzwqopgwaad7bqxma5we6l2bqzs2zfvk6eka", + "time": 1682821080 + }, + { + "cid": "bafkreiayluo2hglsq2qfahpzwqopgwaad7bqxma5we6l2bqzs2zfvk6eka", + "time": 1682821080 + }, + { + "cid": "bafkreiero2ggetbv2g5voe4yg7lr53cl7aocrcdbn5ndz754ani2c4xwye", + "time": 1682849124 + }, + { + "cid": "bafkreiero2ggetbv2g5voe4yg7lr53cl7aocrcdbn5ndz754ani2c4xwye", + "time": 1682849124 + } + ], + "validationError": false + }, + { + "dpid": "40", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreih3uvxd3entelbnsrhijwkperswmy4d27cjvx2fnurjqqjzvp7v54", + "time": 1682821224 + }, + { + "cid": "bafkreih3uvxd3entelbnsrhijwkperswmy4d27cjvx2fnurjqqjzvp7v54", + "time": 1682821224 + }, + { + "cid": "bafkreih3uvxd3entelbnsrhijwkperswmy4d27cjvx2fnurjqqjzvp7v54", + "time": 1682821884 + }, + { + "cid": "bafkreih3uvxd3entelbnsrhijwkperswmy4d27cjvx2fnurjqqjzvp7v54", + "time": 1682821884 + } + ], + "validationError": false + }, + { + "dpid": "41", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihesv24wbwkhgjeplqi7lu2rm5d75o6es3krxbj4rfmhk3bcxavhe", + "time": 1682854224 + }, + { + "cid": "bafkreihesv24wbwkhgjeplqi7lu2rm5d75o6es3krxbj4rfmhk3bcxavhe", + "time": 1682854224 + }, + { + "cid": "bafkreifmd5ucm3ypfkph7klhghsgyvfinkrwxw6uuiwpdjoarmxotflwaa", + "time": 1682854344 + }, + { + "cid": "bafkreifmd5ucm3ypfkph7klhghsgyvfinkrwxw6uuiwpdjoarmxotflwaa", + "time": 1682854344 + } + ], + "validationError": false + }, + { + "dpid": "42", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreie46ed23xpsfgxasdbhzq4zrni5v4dv3lbohasnqkgmohq4g6bjam", + "time": 1682856480 + }, + { + "cid": "bafkreie46ed23xpsfgxasdbhzq4zrni5v4dv3lbohasnqkgmohq4g6bjam", + "time": 1682856480 + } + ], + "validationError": false + }, + { + "dpid": "43", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigumcdo4dafutywplrgg7xgo6swf2qygljyzwktsafuhvednvpmhy", + "time": 1682951112 + }, + { + "cid": "bafkreigumcdo4dafutywplrgg7xgo6swf2qygljyzwktsafuhvednvpmhy", + "time": 1682951112 + } + ], + "validationError": false + }, + { + "dpid": "44", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihqpbdqrgnp6mebwfcqqt3izgreiw4zgiw42zmkezipmktv777itu", + "time": 1682962248 + }, + { + "cid": "bafkreihqpbdqrgnp6mebwfcqqt3izgreiw4zgiw42zmkezipmktv777itu", + "time": 1682962248 + } + ], + "validationError": false + }, + { + "dpid": "45", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihfrfianmcigzvnnetxkzwlcgza75dsah7ab5anx43phu3mke3uky", + "time": 1682993892 + }, + { + "cid": "bafkreihfrfianmcigzvnnetxkzwlcgza75dsah7ab5anx43phu3mke3uky", + "time": 1682993892 + } + ], + "validationError": false + }, + { + "dpid": "46", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreia2nvcwknooiu6t6ywob4dhd6exb3aamogse4n7kkydybjaugdr6u", + "time": 1683053508 + }, + { + "cid": "bafkreia2nvcwknooiu6t6ywob4dhd6exb3aamogse4n7kkydybjaugdr6u", + "time": 1683053508 + }, + { + "cid": "bafkreih5koqw5nvxucidlihwfslknj674oeuroclit74rkaqpe4mq6xuka", + "time": 1683222132 + }, + { + "cid": "bafkreih5koqw5nvxucidlihwfslknj674oeuroclit74rkaqpe4mq6xuka", + "time": 1683222132 + }, + { + "cid": "bafkreif3d644utirvwvkmukcrhg64palp3r4xociwsn6b6o2hxmkdxalby", + "time": 1683227616 + }, + { + "cid": "bafkreif3d644utirvwvkmukcrhg64palp3r4xociwsn6b6o2hxmkdxalby", + "time": 1683227616 + }, + { + "cid": "bafkreibn3jhdlsdsonv25t7i2bwtrbkl3jzwjbnnwylpeih3jmmzdhsfmi", + "time": 1683298680 + }, + { + "cid": "bafkreibn3jhdlsdsonv25t7i2bwtrbkl3jzwjbnnwylpeih3jmmzdhsfmi", + "time": 1683298680 + }, + { + "cid": "bafkreiepot62powegf7tt73gyiz24facsdloywggattt2asz5y4eaqhkyi", + "time": 1683299940 + }, + { + "cid": "bafkreiepot62powegf7tt73gyiz24facsdloywggattt2asz5y4eaqhkyi", + "time": 1683299940 + }, + { + "cid": "bafkreihge5qw7sc3mqc4wkf4cgpv6udtvrgipfxwyph7dhlyu6bkkt7tfq", + "time": 1705420740 + }, + { + "cid": "bafkreihge5qw7sc3mqc4wkf4cgpv6udtvrgipfxwyph7dhlyu6bkkt7tfq", + "time": 1705420740 + } + ], + "validationError": false + }, + { + "dpid": "47", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreia7orsrr4pwxe5m2gnklknpc25kjs7gnzemofki3aeh6ydh4hkfju", + "time": 1683222948 + }, + { + "cid": "bafkreia7orsrr4pwxe5m2gnklknpc25kjs7gnzemofki3aeh6ydh4hkfju", + "time": 1683222948 + } + ], + "validationError": false + }, + { + "dpid": "48", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreieahbi5tzb2od7nb2j5up4ooiglvh2lty2bgcrwjc3km7fnsplaxu", + "time": 1683232692 + }, + { + "cid": "bafkreieahbi5tzb2od7nb2j5up4ooiglvh2lty2bgcrwjc3km7fnsplaxu", + "time": 1683232692 + } + ], + "validationError": false + }, + { + "dpid": "49", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiet6onaozwmqyflpbjsa7f6f5jkhou5n3vxxkxmkgalhnr54bzftu", + "time": 1683236460 + }, + { + "cid": "bafkreiet6onaozwmqyflpbjsa7f6f5jkhou5n3vxxkxmkgalhnr54bzftu", + "time": 1683236460 + }, + { + "cid": "bafkreibp3hplo3b2hfetbrargv2gv2dkx3kfqfsqbxhkuved2k2nebxcpa", + "time": 1683236760 + }, + { + "cid": "bafkreibp3hplo3b2hfetbrargv2gv2dkx3kfqfsqbxhkuved2k2nebxcpa", + "time": 1683236760 + }, + { + "cid": "bafkreigym3lzf2ruzd3r23mflxjzafqfxoi5bncru3t4ky35vfaubbke34", + "time": 1683236760 + }, + { + "cid": "bafkreigym3lzf2ruzd3r23mflxjzafqfxoi5bncru3t4ky35vfaubbke34", + "time": 1683236760 + }, + { + "cid": "bafkreife4uk2mkecur54sq774ybtrka5l4gd5777j5cjjscfmx4vcqnfbm", + "time": 1683237288 + }, + { + "cid": "bafkreife4uk2mkecur54sq774ybtrka5l4gd5777j5cjjscfmx4vcqnfbm", + "time": 1683237288 + } + ], + "validationError": false + }, + { + "dpid": "50", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibroag6m5tps4srrtdxbfq74sskvpfu4sbhadhkh3vfonjrlmsvda", + "time": 1683886968 + }, + { + "cid": "bafkreibroag6m5tps4srrtdxbfq74sskvpfu4sbhadhkh3vfonjrlmsvda", + "time": 1683886968 + } + ], + "validationError": false + }, + { + "dpid": "51", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiheezwrynuxo6gnjd2pmahkcw3wstooxs6fvaflpjouewmh4qi3aa", + "time": 1683930000 + }, + { + "cid": "bafkreiheezwrynuxo6gnjd2pmahkcw3wstooxs6fvaflpjouewmh4qi3aa", + "time": 1683930000 + }, + { + "cid": "bafkreiasjo5wzkkk2s56tvdkmbe56vj4j7gyq345vnqpwvnvwozzhtkxfq", + "time": 1683931428 + }, + { + "cid": "bafkreiasjo5wzkkk2s56tvdkmbe56vj4j7gyq345vnqpwvnvwozzhtkxfq", + "time": 1683931428 + } + ], + "validationError": false + }, + { + "dpid": "52", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicxw5tzwajvwa757ihut3hvlgnfbpu7fa4oxfvvlssu4rikfrtmv4", + "time": 1684412244 + }, + { + "cid": "bafkreicxw5tzwajvwa757ihut3hvlgnfbpu7fa4oxfvvlssu4rikfrtmv4", + "time": 1684412244 + } + ], + "validationError": false + }, + { + "dpid": "53", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreia7yjdhq6tdxjtwyr4ajfhxypq3jxbo5augryzzeos7cqrbyy6jmi", + "time": 1684862784 + }, + { + "cid": "bafkreia7yjdhq6tdxjtwyr4ajfhxypq3jxbo5augryzzeos7cqrbyy6jmi", + "time": 1684862784 + }, + { + "cid": "bafkreifutouvscu3pbsaabgxdxqfd6zaphkcuei6i3fibdeefmrh4oujby", + "time": 1686612108 + }, + { + "cid": "bafkreifutouvscu3pbsaabgxdxqfd6zaphkcuei6i3fibdeefmrh4oujby", + "time": 1686612108 + } + ], + "validationError": false + }, + { + "dpid": "54", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigtfrsogce5ixgj4dvjgvj2qgjsujs5g4sa64svziiyz6j2bajise", + "time": 1685098464 + }, + { + "cid": "bafkreigtfrsogce5ixgj4dvjgvj2qgjsujs5g4sa64svziiyz6j2bajise", + "time": 1685098464 + }, + { + "cid": "bafkreihocw2lexz7nz4sfwmy576guhbecxnzq4wfltnx5twqn2clng3ewu", + "time": 1685098776 + }, + { + "cid": "bafkreihocw2lexz7nz4sfwmy576guhbecxnzq4wfltnx5twqn2clng3ewu", + "time": 1685098776 + } + ], + "validationError": false + }, + { + "dpid": "55", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicup2qewrwovkkgk5bun4vpws7cbq3qnv2rbt7truyw54owvtwovm", + "time": 1685442360 + }, + { + "cid": "bafkreicup2qewrwovkkgk5bun4vpws7cbq3qnv2rbt7truyw54owvtwovm", + "time": 1685442360 + } + ], + "validationError": false + }, + { + "dpid": "56", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreieis5ac2evezkciy26fvswybmyyarfnrlvyh7p5acvbhcsceayorq", + "time": 1685444172 + }, + { + "cid": "bafkreieis5ac2evezkciy26fvswybmyyarfnrlvyh7p5acvbhcsceayorq", + "time": 1685444172 + }, + { + "cid": "bafkreid6ibvbiblu6vviuc3l6ivmpmpdbj2rzt625capmi4igns2r7k4ue", + "time": 1685448060 + }, + { + "cid": "bafkreid6ibvbiblu6vviuc3l6ivmpmpdbj2rzt625capmi4igns2r7k4ue", + "time": 1685448060 + } + ], + "validationError": false + }, + { + "dpid": "57", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiaulqrzufg3qnw55rwzqtn5h2cvsawdunrfwt4j32ywt6oswi5bfm", + "time": 1685525952 + }, + { + "cid": "bafkreiaulqrzufg3qnw55rwzqtn5h2cvsawdunrfwt4j32ywt6oswi5bfm", + "time": 1685525952 + } + ], + "validationError": false + }, + { + "dpid": "58", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidlxqbem5m3kgtntq6243vujhuyvt2s72ry2k5uy4f6hmjwbezdje", + "time": 1685526132 + }, + { + "cid": "bafkreidlxqbem5m3kgtntq6243vujhuyvt2s72ry2k5uy4f6hmjwbezdje", + "time": 1685526132 + }, + { + "cid": "bafkreib2gln7ztcpt6z7q7yo6isznl6lam4zv74hwslwhplh6g55re26lm", + "time": 1685536224 + }, + { + "cid": "bafkreib2gln7ztcpt6z7q7yo6isznl6lam4zv74hwslwhplh6g55re26lm", + "time": 1685536224 + } + ], + "validationError": false + }, + { + "dpid": "59", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigj2svt7njv2nxznzm42pisbjgpfjzhoorlcsryjlx5coa2klssku", + "time": 1685613060 + }, + { + "cid": "bafkreigvuao6ogwtnr2oknvxl3a5mtulhats7dqsiuturbxnnablevorai", + "time": 1685613240 + }, + { + "cid": "bafkreigvuao6ogwtnr2oknvxl3a5mtulhats7dqsiuturbxnnablevorai", + "time": 1685613240 + } + ], + "validationError": false + }, + { + "dpid": "60", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiefsjhlwr6bcq4nscdoz2q2tkca5i7ocxgtn5nxggkf2lr5a2z2lq", + "time": 1685613216 + }, + { + "cid": "bafkreifmohd57nd6xbcjrc3b6dxgpycgijleopks7hrmza4t23dvqxd2au", + "time": 1685613708 + } + ], + "validationError": false + }, + { + "dpid": "61", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreid5vwbe6ri74rgtdevbjznreexoedsocftjqgpopx3bih656jwzni", + "time": 1685614104 + }, + { + "cid": "bafkreid5vwbe6ri74rgtdevbjznreexoedsocftjqgpopx3bih656jwzni", + "time": 1685614104 + } + ], + "validationError": false + }, + { + "dpid": "62", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiapjbbsrowag6txt3wuilla2vp6dhhijkylklmvdzc4es3qb27buq", + "time": 1685615388 + }, + { + "cid": "bafkreiapjbbsrowag6txt3wuilla2vp6dhhijkylklmvdzc4es3qb27buq", + "time": 1685615388 + } + ], + "validationError": false + }, + { + "dpid": "63", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicjmhgi5sbjvo2i3nzwfkwfmahgipbyq6iasekibgqpl75cdiqdsi", + "time": 1685615724 + } + ], + "validationError": false + }, + { + "dpid": "64", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreib2rkswbatx7qqcnymxcajqrgrywfzlsiischsrfowhbd5vjfskfi", + "time": 1685719428 + } + ], + "validationError": false + }, + { + "dpid": "65", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifdylfaiep4lc4544mow5aiq4vg37buebiybfx5wyznfi4pov6qri", + "time": 1686220584 + } + ], + "validationError": false + }, + { + "dpid": "66", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibelil5fgqul2o3chxv7g7xmdqkv2krqkv6r6mdbiw72vcqp4wxky", + "time": 1687805292 + }, + { + "cid": "bafkreiefvtk6gcvlxq3hw3lkxcjjy5aqkaxyu4swucs2wd3imjhi2yfdpm", + "time": 1687805484 + } + ], + "validationError": false + }, + { + "dpid": "67", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiazlufpwemnsbzscuycou7gi5m7t2p4yxbxvozkvxex47uczuokba", + "time": 1687807524 + }, + { + "cid": "bafkreiazlufpwemnsbzscuycou7gi5m7t2p4yxbxvozkvxex47uczuokba", + "time": 1687807524 + }, + { + "cid": "bafkreidupix2c3fizisuv2z6tluypvssf6solprgnmev6ul6vp6dprwop4", + "time": 1687808232 + }, + { + "cid": "bafkreidupix2c3fizisuv2z6tluypvssf6solprgnmev6ul6vp6dprwop4", + "time": 1687808232 + } + ], + "validationError": false + }, + { + "dpid": "68", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihakt3w53hwvneg2o3e4xysgegwk5j5rs6mug6ywlwb2bmprm4wzy", + "time": 1687812132 + }, + { + "cid": "bafkreihakt3w53hwvneg2o3e4xysgegwk5j5rs6mug6ywlwb2bmprm4wzy", + "time": 1687812132 + } + ], + "validationError": false + }, + { + "dpid": "69", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigfelcudmytsq2s2j4wcy3j7tsyatpnffpcthf6zz7q5wa4snafdm", + "time": 1687812804 + }, + { + "cid": "bafkreigfelcudmytsq2s2j4wcy3j7tsyatpnffpcthf6zz7q5wa4snafdm", + "time": 1687812804 + } + ], + "validationError": false + }, + { + "dpid": "70", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicandi5eh3gwuxwlq6k6fpeuurnbpbx33q3ijndg44go2p5ekni3y", + "time": 1687817568 + }, + { + "cid": "bafkreicandi5eh3gwuxwlq6k6fpeuurnbpbx33q3ijndg44go2p5ekni3y", + "time": 1687817568 + } + ], + "validationError": false + }, + { + "dpid": "71", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibb5g5ujmxeve56ktnuolb7rrncmbgedtrjemeshn6rxbrhn4uepe", + "time": 1688024628 + }, + { + "cid": "bafkreibb5g5ujmxeve56ktnuolb7rrncmbgedtrjemeshn6rxbrhn4uepe", + "time": 1688024628 + }, + { + "cid": "bafkreiddtartrk6isrs3j5ltx6nkcv437jsu62vc6ew3cwvxk3msebzg5e", + "time": 1688024676 + }, + { + "cid": "bafkreiddtartrk6isrs3j5ltx6nkcv437jsu62vc6ew3cwvxk3msebzg5e", + "time": 1688024676 + } + ], + "validationError": false + }, + { + "dpid": "72", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicj4c44gghcoy2ztvwe32fmbv7cuvty2hv2y4ndrnd6ghrl3ciaea", + "time": 1688552688 + }, + { + "cid": "bafkreicj4c44gghcoy2ztvwe32fmbv7cuvty2hv2y4ndrnd6ghrl3ciaea", + "time": 1688552688 + } + ], + "validationError": false + }, + { + "dpid": "73", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifdgjfu3g4qddc7g5kvnk3lshkuyfau7o2qle5ut5msptulbxsqme", + "time": 1688720808 + }, + { + "cid": "bafkreifdgjfu3g4qddc7g5kvnk3lshkuyfau7o2qle5ut5msptulbxsqme", + "time": 1688720808 + }, + { + "cid": "bafkreifdgjfu3g4qddc7g5kvnk3lshkuyfau7o2qle5ut5msptulbxsqme", + "time": 1689009768 + }, + { + "cid": "bafkreifdgjfu3g4qddc7g5kvnk3lshkuyfau7o2qle5ut5msptulbxsqme", + "time": 1689009768 + } + ], + "validationError": false + }, + { + "dpid": "74", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifqxkjzypbtz7snjp3ghjrv56bd5umihchpwfppnoz67tcmhuq7wi", + "time": 1689041640 + }, + { + "cid": "bafkreifqxkjzypbtz7snjp3ghjrv56bd5umihchpwfppnoz67tcmhuq7wi", + "time": 1689041640 + } + ], + "validationError": false + }, + { + "dpid": "75", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibtsll3aq2bynvlxnqh6nxafzdm4cpiovr3bcncbkzjcy32xalp7i", + "time": 1689294216 + }, + { + "cid": "bafkreibtsll3aq2bynvlxnqh6nxafzdm4cpiovr3bcncbkzjcy32xalp7i", + "time": 1689294216 + } + ], + "validationError": false + }, + { + "dpid": "76", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiatjdpouudloenzdzb7d3e5pogruvwbhurcnm2g5h64jmkpk2uebe", + "time": 1689518988 + }, + { + "cid": "bafkreiatjdpouudloenzdzb7d3e5pogruvwbhurcnm2g5h64jmkpk2uebe", + "time": 1689518988 + }, + { + "cid": "bafkreigg3xk6ojueylnninvwsrw62nqpt7pyjnz6thaipbydb5ltclctly", + "time": 1692182952 + }, + { + "cid": "bafkreigg3xk6ojueylnninvwsrw62nqpt7pyjnz6thaipbydb5ltclctly", + "time": 1692182952 + }, + { + "cid": "bafkreicrggm7jpxgaj2vgydvefuravrs2bh4emlt6eadx3zsbubtpulmcq", + "time": 1692330000 + }, + { + "cid": "bafkreicrggm7jpxgaj2vgydvefuravrs2bh4emlt6eadx3zsbubtpulmcq", + "time": 1692330000 + }, + { + "cid": "bafkreifgfzjltrvcz3qixyjkiubgms2r3figm37euwxzbi6pvej2me6tje", + "time": 1701997248 + }, + { + "cid": "bafkreifgfzjltrvcz3qixyjkiubgms2r3figm37euwxzbi6pvej2me6tje", + "time": 1701997248 + }, + { + "cid": "bafkreic4wiuatha4wclfbwft4vaeeqifrbb2f3tqm4eoajommogudbvswu", + "time": 1702000140 + }, + { + "cid": "bafkreic4wiuatha4wclfbwft4vaeeqifrbb2f3tqm4eoajommogudbvswu", + "time": 1702000140 + }, + { + "cid": "bafkreicraffpobz3k5rzdmigl5tzklihwuim4kwe7xl5uulmfrkr4uvm2u", + "time": 1702045680 + }, + { + "cid": "bafkreicraffpobz3k5rzdmigl5tzklihwuim4kwe7xl5uulmfrkr4uvm2u", + "time": 1702045680 + }, + { + "cid": "bafkreidtkraxowlx26oz5g6qyfuawhx5nroil4a4mo6ywa7knfel7ft2dq", + "time": 1702045944 + }, + { + "cid": "bafkreidtkraxowlx26oz5g6qyfuawhx5nroil4a4mo6ywa7knfel7ft2dq", + "time": 1702045944 + } + ], + "validationError": false + }, + { + "dpid": "77", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiaqxrcrai2j2lpk2moare5abq4vtyhxk6m5jxo5fbqkrsy24kdm7q", + "time": 1691492520 + }, + { + "cid": "bafkreiaqxrcrai2j2lpk2moare5abq4vtyhxk6m5jxo5fbqkrsy24kdm7q", + "time": 1691492520 + }, + { + "cid": "bafkreihjozked2lgpgtdcuvzejanhnm65sccwglgblxfdg3cwi72vlrtvq", + "time": 1691493636 + }, + { + "cid": "bafkreihjozked2lgpgtdcuvzejanhnm65sccwglgblxfdg3cwi72vlrtvq", + "time": 1691493636 + }, + { + "cid": "bafkreieodz3e4kzbnlg4nka5pwrgafwuuemfuejxqa5dpdaqlgt6bjs7fm", + "time": 1691496348 + }, + { + "cid": "bafkreieodz3e4kzbnlg4nka5pwrgafwuuemfuejxqa5dpdaqlgt6bjs7fm", + "time": 1691496348 + } + ], + "validationError": false + }, + { + "dpid": "78", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifixmk6tierh6qompfouk63r6clg5jbeuvwherrxacq4uoedk4o5q", + "time": 1691501736 + }, + { + "cid": "bafkreifixmk6tierh6qompfouk63r6clg5jbeuvwherrxacq4uoedk4o5q", + "time": 1691501736 + } + ], + "validationError": false + }, + { + "dpid": "79", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibtuuiejhyxu4zr2od34biucedhlmqdmqem6v2ruqu6ov2kgsfnfa", + "time": 1692472464 + }, + { + "cid": "bafkreibtuuiejhyxu4zr2od34biucedhlmqdmqem6v2ruqu6ov2kgsfnfa", + "time": 1692472464 + } + ], + "validationError": false + }, + { + "dpid": "80", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiawwe6os5lxye3hojdmwgcdt4nrs7xwfqy3p3vuv7xolhbnc2nqaq", + "time": 1693245804 + }, + { + "cid": "bafkreiawwe6os5lxye3hojdmwgcdt4nrs7xwfqy3p3vuv7xolhbnc2nqaq", + "time": 1693245804 + }, + { + "cid": "bafkreichlzplxpphzyoo3mnjg6tm2e4uplpm4d2q667a6dbz6xhctvktai", + "time": 1693246872 + }, + { + "cid": "bafkreichlzplxpphzyoo3mnjg6tm2e4uplpm4d2q667a6dbz6xhctvktai", + "time": 1693246872 + } + ], + "validationError": false + }, + { + "dpid": "81", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreieefydw5dajtfgz5xqecgyyqxt7kzzyibihy4dvnrtwakaahkn34y", + "time": 1693246440 + }, + { + "cid": "bafkreieefydw5dajtfgz5xqecgyyqxt7kzzyibihy4dvnrtwakaahkn34y", + "time": 1693246440 + }, + { + "cid": "bafkreicpdjfhoxg3gyc2xn63ppbxf7a7wvehkl4h34dapqeqekfetwunme", + "time": 1700147784 + }, + { + "cid": "bafkreicpdjfhoxg3gyc2xn63ppbxf7a7wvehkl4h34dapqeqekfetwunme", + "time": 1700147784 + } + ], + "validationError": false + }, + { + "dpid": "82", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicmvrritjqe4eatfkix3k6kgxz7oxlxengyfhg7rkubpagmxymiqa", + "time": 1693247148 + }, + { + "cid": "bafkreicmvrritjqe4eatfkix3k6kgxz7oxlxengyfhg7rkubpagmxymiqa", + "time": 1693247148 + } + ], + "validationError": false + }, + { + "dpid": "83", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreia6ccnzt76b23xkq7slvzxgebltmlkmvcbvr77nzfyca7wpq6qkru", + "time": 1693247616 + }, + { + "cid": "bafkreia6ccnzt76b23xkq7slvzxgebltmlkmvcbvr77nzfyca7wpq6qkru", + "time": 1693247616 + }, + { + "cid": "bafkreidrb3cry4mh6fcik54rotatfnz2mapg3olcsxqpodgdbecrh5iu54", + "time": 1700147268 + }, + { + "cid": "bafkreidrb3cry4mh6fcik54rotatfnz2mapg3olcsxqpodgdbecrh5iu54", + "time": 1700147268 + } + ], + "validationError": false + }, + { + "dpid": "84", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibgfpmyizfiu6mpmdcn6aqvqrli72za72ccrxsim24nhtfv3cqb7m", + "time": 1693248192 + }, + { + "cid": "bafkreibgfpmyizfiu6mpmdcn6aqvqrli72za72ccrxsim24nhtfv3cqb7m", + "time": 1693248192 + }, + { + "cid": "bafkreidfksyvtp5vjzoczjupn6h6h72dcr2p2rm63l7l5qwn6sq6d2nyjy", + "time": 1700146980 + }, + { + "cid": "bafkreidfksyvtp5vjzoczjupn6h6h72dcr2p2rm63l7l5qwn6sq6d2nyjy", + "time": 1700146980 + } + ], + "validationError": false + }, + { + "dpid": "85", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreichgcyenem343rn3cgpyymyicdgoe7vgkev7z7bccskncaux7rxt4", + "time": 1693248672 + }, + { + "cid": "bafkreichgcyenem343rn3cgpyymyicdgoe7vgkev7z7bccskncaux7rxt4", + "time": 1693248672 + }, + { + "cid": "bafkreiejwrzg3vtvrvxm75dzgmk3736v4wrhl6uin64hzq76oekbkqi2ci", + "time": 1700146392 + }, + { + "cid": "bafkreiejwrzg3vtvrvxm75dzgmk3736v4wrhl6uin64hzq76oekbkqi2ci", + "time": 1700146392 + } + ], + "validationError": false + }, + { + "dpid": "86", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihxqrtbvhxg3w2nu3ahpcu2it6qvnmca4xb72vq4w27er3v4rsjgi", + "time": 1693249560 + }, + { + "cid": "bafkreihxqrtbvhxg3w2nu3ahpcu2it6qvnmca4xb72vq4w27er3v4rsjgi", + "time": 1693249560 + }, + { + "cid": "bafkreidlqc6jfns3ftpxoopx7etmfqp75xwoptd6es36xir2fl4nkvmx6i", + "time": 1700145552 + }, + { + "cid": "bafkreidlqc6jfns3ftpxoopx7etmfqp75xwoptd6es36xir2fl4nkvmx6i", + "time": 1700145552 + } + ], + "validationError": false + }, + { + "dpid": "87", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidlb227q7gvv622itmewvsdli726msbjgtsoufaepsaajrc66d27u", + "time": 1693249908 + }, + { + "cid": "bafkreidlb227q7gvv622itmewvsdli726msbjgtsoufaepsaajrc66d27u", + "time": 1693249908 + }, + { + "cid": "bafkreibaiviks6ed4yuwaidz4zzerlhmlkbdcxucky74ah4nu37cm443lm", + "time": 1700146176 + }, + { + "cid": "bafkreibaiviks6ed4yuwaidz4zzerlhmlkbdcxucky74ah4nu37cm443lm", + "time": 1700146176 + } + ], + "validationError": false + }, + { + "dpid": "88", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibdpyr6vlsifgi3cebv7ip26ynplllfzpekxz4zfj7xna7uolpjgy", + "time": 1693250244 + }, + { + "cid": "bafkreibdpyr6vlsifgi3cebv7ip26ynplllfzpekxz4zfj7xna7uolpjgy", + "time": 1693250244 + }, + { + "cid": "bafkreif7e3nkqyrpa6pkhlnv7sdrwkgyct7fhgzqsteo457kpa46wuflhe", + "time": 1700146776 + }, + { + "cid": "bafkreif7e3nkqyrpa6pkhlnv7sdrwkgyct7fhgzqsteo457kpa46wuflhe", + "time": 1700146776 + } + ], + "validationError": false + }, + { + "dpid": "89", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidp3ed42l6cizgero5c7zfmxpmwp5hkc4tx6uz7mgioxsep4wb6rm", + "time": 1693251900 + }, + { + "cid": "bafkreidp3ed42l6cizgero5c7zfmxpmwp5hkc4tx6uz7mgioxsep4wb6rm", + "time": 1693251900 + } + ], + "validationError": false + }, + { + "dpid": "90", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiaw34rnu36p2ccawj3gopyxgl64qj3dc3ip3pzvfh5anzrvmu4z5u", + "time": 1694114940 + }, + { + "cid": "bafkreiaw34rnu36p2ccawj3gopyxgl64qj3dc3ip3pzvfh5anzrvmu4z5u", + "time": 1694114940 + }, + { + "cid": "bafkreidk7ihar3swjjf46wtttjl52govxa256725urm5upcefu4wfvnxpm", + "time": 1694187648 + }, + { + "cid": "bafkreidk7ihar3swjjf46wtttjl52govxa256725urm5upcefu4wfvnxpm", + "time": 1694187648 + }, + { + "cid": "bafkreic6n2x6jlvss4iepnkkb4o4wre4nezbbff7kw46mz2egtzxast5xe", + "time": 1695653376 + }, + { + "cid": "bafkreic6n2x6jlvss4iepnkkb4o4wre4nezbbff7kw46mz2egtzxast5xe", + "time": 1695653376 + } + ], + "validationError": false + }, + { + "dpid": "91", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigpcnierfxljhffgj4d6oyuwec4pcbkbjys6goaggw75rcobd6vnu", + "time": 1694197140 + }, + { + "cid": "bafkreigpcnierfxljhffgj4d6oyuwec4pcbkbjys6goaggw75rcobd6vnu", + "time": 1694197140 + }, + { + "cid": "bafkreidtiuwpwyewgjp3r5a7shvzgir7pvbeguxlv6zebpdbxrraialhxu", + "time": 1695653220 + }, + { + "cid": "bafkreidtiuwpwyewgjp3r5a7shvzgir7pvbeguxlv6zebpdbxrraialhxu", + "time": 1695653220 + } + ], + "validationError": false + }, + { + "dpid": "92", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicqezpklsjtuszjnsekc2dcyadgtbcfouhlc57vclrwco45gzbul4", + "time": 1695218412 + }, + { + "cid": "bafkreicqezpklsjtuszjnsekc2dcyadgtbcfouhlc57vclrwco45gzbul4", + "time": 1695218412 + } + ], + "validationError": false + }, + { + "dpid": "93", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreie2p56t2d3i762v3bow3jweile6fmryt2qlcjq3cmkz7kpqtaic2a", + "time": 1695246144 + }, + { + "cid": "bafkreie2p56t2d3i762v3bow3jweile6fmryt2qlcjq3cmkz7kpqtaic2a", + "time": 1695246144 + } + ], + "validationError": false + }, + { + "dpid": "94", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiaqnt5raa6b4ujpkgd4veg73rtp5csn6fwxrckbhq4mkrl7ws63dy", + "time": 1695246324 + }, + { + "cid": "bafkreiaqnt5raa6b4ujpkgd4veg73rtp5csn6fwxrckbhq4mkrl7ws63dy", + "time": 1695246324 + } + ], + "validationError": false + }, + { + "dpid": "95", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreied6xbi65zwpzqiiaqnhq3cdq42c7yqrx6sd32ncv6avkovcb6f6y", + "time": 1695324696 + }, + { + "cid": "bafkreied6xbi65zwpzqiiaqnhq3cdq42c7yqrx6sd32ncv6avkovcb6f6y", + "time": 1695324696 + } + ], + "validationError": false + }, + { + "dpid": "96", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigurq54verb4sihjuonnx2pbo77lbjlviol2jfjxxgyzzko7o42ka", + "time": 1695816576 + }, + { + "cid": "bafkreigurq54verb4sihjuonnx2pbo77lbjlviol2jfjxxgyzzko7o42ka", + "time": 1695816576 + } + ], + "validationError": false + }, + { + "dpid": "97", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreig76u6of7za2h5pdphz2ztsl5xdsgg2vrsh2dximjx3q2aszfjq6m", + "time": 1696295376 + }, + { + "cid": "bafkreig76u6of7za2h5pdphz2ztsl5xdsgg2vrsh2dximjx3q2aszfjq6m", + "time": 1696295376 + }, + { + "cid": "bafkreig76u6of7za2h5pdphz2ztsl5xdsgg2vrsh2dximjx3q2aszfjq6m", + "time": 1696296012 + }, + { + "cid": "bafkreig76u6of7za2h5pdphz2ztsl5xdsgg2vrsh2dximjx3q2aszfjq6m", + "time": 1696296012 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696299000 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696299000 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696299600 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696299600 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696299876 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696299876 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696299912 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696299912 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696299996 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696299996 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696440036 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696440036 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696440996 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696440996 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696459560 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696459560 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696459584 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696459584 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696466724 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696466724 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696466820 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696466820 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696466964 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696466964 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696468416 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696468416 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696479552 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696479552 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696480608 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696480608 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696480764 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696480764 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696480884 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696480884 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696481172 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696481172 + }, + { + "cid": "bafkreiciddswj3e6ho5of7x7a7liaqehnwqeg35w3cp3l5knv6k2tdlswa", + "time": 1696594740 + }, + { + "cid": "bafkreiciddswj3e6ho5of7x7a7liaqehnwqeg35w3cp3l5knv6k2tdlswa", + "time": 1696594740 + } + ], + "validationError": false + }, + { + "dpid": "98", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicsn4qia64pf7eim7sjggvmnggqadmfmrrcm5gecbpfdzxwzlk7i4", + "time": 1696303560 + }, + { + "cid": "bafkreicsn4qia64pf7eim7sjggvmnggqadmfmrrcm5gecbpfdzxwzlk7i4", + "time": 1696303944 + }, + { + "cid": "bafkreicsn4qia64pf7eim7sjggvmnggqadmfmrrcm5gecbpfdzxwzlk7i4", + "time": 1696303944 + } + ], + "validationError": false + }, + { + "dpid": "99", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696336296 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696336296 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696469268 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696469268 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536756 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536756 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536804 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536828 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536888 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536912 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536912 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536936 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536936 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536972 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536972 + } + ], + "validationError": false + }, + { + "dpid": "100", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreib2fs7g7yawpqeyjzatsv3bip5p6xr27pnblzjase3zyr4ixtbu6a", + "time": 1696506528 + }, + { + "cid": "bafkreib2fs7g7yawpqeyjzatsv3bip5p6xr27pnblzjase3zyr4ixtbu6a", + "time": 1696506528 + }, + { + "cid": "bafkreihirj6fsasmvqmzngnyqitl6fpt3ljapgwx7dpfelgvruqsu7smw4", + "time": 1696507296 + }, + { + "cid": "bafkreihirj6fsasmvqmzngnyqitl6fpt3ljapgwx7dpfelgvruqsu7smw4", + "time": 1696507296 + }, + { + "cid": "bafkreid5osij2amlc67sm7uzqp22j7y3dn6lseyuy72oh64z5rqoh5qity", + "time": 1696840824 + }, + { + "cid": "bafkreid5osij2amlc67sm7uzqp22j7y3dn6lseyuy72oh64z5rqoh5qity", + "time": 1696840824 + } + ], + "validationError": false + }, + { + "dpid": "101", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiaoby2dmz4sljyhxsizjj2yd2jvbzz2vsywii3vp6xqi4rjefxl4q", + "time": 1696589760 + }, + { + "cid": "bafkreiaoby2dmz4sljyhxsizjj2yd2jvbzz2vsywii3vp6xqi4rjefxl4q", + "time": 1696589760 + } + ], + "validationError": false + }, + { + "dpid": "102", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiceiefmvnwozgtpvvwv5exwsdxm36yl5ovunmcnjx5kjtcqvm6lwe", + "time": 1696605300 + }, + { + "cid": "bafkreiceiefmvnwozgtpvvwv5exwsdxm36yl5ovunmcnjx5kjtcqvm6lwe", + "time": 1696605300 + } + ], + "validationError": false + }, + { + "dpid": "103", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreif6p22atw6ekbaxkrnfmetfdqtnhldaqw6qtqiqc7lqbus6aizru4", + "time": 1696841976 + }, + { + "cid": "bafkreif6p22atw6ekbaxkrnfmetfdqtnhldaqw6qtqiqc7lqbus6aizru4", + "time": 1696841976 + } + ], + "validationError": false + }, + { + "dpid": "104", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiautwruptenrd4xbq5actpbmirrxprmnnxyxf37ixblmcynebjaqq", + "time": 1696842144 + }, + { + "cid": "bafkreiautwruptenrd4xbq5actpbmirrxprmnnxyxf37ixblmcynebjaqq", + "time": 1696842144 + }, + { + "cid": "bafkreie37zoipwpgqrupcmxfnhqfqpztumhcurzb27rfasa5ipao32w3ia", + "time": 1697792352 + }, + { + "cid": "bafkreie37zoipwpgqrupcmxfnhqfqpztumhcurzb27rfasa5ipao32w3ia", + "time": 1697792352 + }, + { + "cid": "bafkreiebcm7batu7zyp4aw6pzisbkldtlqsghh5jhczhkh63lxgjxp5wte", + "time": 1698779592 + }, + { + "cid": "bafkreiebcm7batu7zyp4aw6pzisbkldtlqsghh5jhczhkh63lxgjxp5wte", + "time": 1698779592 + } + ], + "validationError": false + }, + { + "dpid": "105", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreig33qp67gaov32ibvtb5gqtcnfrntrsrbzst2lcgrgnkbu4hbtcj4", + "time": 1696842444 + }, + { + "cid": "bafkreig33qp67gaov32ibvtb5gqtcnfrntrsrbzst2lcgrgnkbu4hbtcj4", + "time": 1696842444 + }, + { + "cid": "bafkreig33qp67gaov32ibvtb5gqtcnfrntrsrbzst2lcgrgnkbu4hbtcj4", + "time": 1698911760 + }, + { + "cid": "bafkreig33qp67gaov32ibvtb5gqtcnfrntrsrbzst2lcgrgnkbu4hbtcj4", + "time": 1698911760 + } + ], + "validationError": false + }, + { + "dpid": "106", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibbbm7623bsdoftewbedqd3peny6zhqpt6tjgx67ouf6hhvbv2idi", + "time": 1696941732 + }, + { + "cid": "bafkreibbbm7623bsdoftewbedqd3peny6zhqpt6tjgx67ouf6hhvbv2idi", + "time": 1696941732 + }, + { + "cid": "bafkreihemsbpld4yuzrn4ckrlriyq5ortlkycxx74ayfugnoce7oetsmam", + "time": 1696942104 + }, + { + "cid": "bafkreihemsbpld4yuzrn4ckrlriyq5ortlkycxx74ayfugnoce7oetsmam", + "time": 1696942104 + }, + { + "cid": "bafkreic4gpc3k5mrttk57w6k5fvtgvubvh6xfwgmubecx53b55xsxoavxe", + "time": 1696944228 + }, + { + "cid": "bafkreic4gpc3k5mrttk57w6k5fvtgvubvh6xfwgmubecx53b55xsxoavxe", + "time": 1696944228 + }, + { + "cid": "bafkreickteh2tt3oy43o42ikwei6tppghmtbkockk22a3niovi57ugor7q", + "time": 1696961232 + }, + { + "cid": "bafkreickteh2tt3oy43o42ikwei6tppghmtbkockk22a3niovi57ugor7q", + "time": 1696961232 + } + ], + "validationError": false + }, + { + "dpid": "107", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicgst5gqckb4bzduzxqhn2v5an2xjnmhv6qwscwtn3gjhuplpv3jm", + "time": 1697040396 + }, + { + "cid": "bafkreicgst5gqckb4bzduzxqhn2v5an2xjnmhv6qwscwtn3gjhuplpv3jm", + "time": 1697040396 + } + ], + "validationError": false + }, + { + "dpid": "108", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifzh36eve7dsmbebnvxhpalxdgcjcur7anxllzyfwnmetlsvq2f54", + "time": 1697792640 + }, + { + "cid": "bafkreifzh36eve7dsmbebnvxhpalxdgcjcur7anxllzyfwnmetlsvq2f54", + "time": 1697792640 + } + ], + "validationError": false + }, + { + "dpid": "109", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibiziudxe62de7g443yl453tpnky25ujrcdhuaudtwq7hxrrr6q3m", + "time": 1698054684 + }, + { + "cid": "bafkreibiziudxe62de7g443yl453tpnky25ujrcdhuaudtwq7hxrrr6q3m", + "time": 1698054684 + } + ], + "validationError": false + }, + { + "dpid": "110", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreic65maz27f7atu7a4euzl6jv4c2kz66ddvcxuhdajl4i4l27uwwii", + "time": 1698079308 + }, + { + "cid": "bafkreic65maz27f7atu7a4euzl6jv4c2kz66ddvcxuhdajl4i4l27uwwii", + "time": 1698079308 + }, + { + "cid": "bafkreic65maz27f7atu7a4euzl6jv4c2kz66ddvcxuhdajl4i4l27uwwii", + "time": 1698323460 + }, + { + "cid": "bafkreic65maz27f7atu7a4euzl6jv4c2kz66ddvcxuhdajl4i4l27uwwii", + "time": 1698323460 + } + ], + "validationError": false + }, + { + "dpid": "111", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiejskdyqkcsnvcl6njkivjvptts656x3qvr64nsjdnx6pcn6bdht4", + "time": 1698177444 + }, + { + "cid": "bafkreiejskdyqkcsnvcl6njkivjvptts656x3qvr64nsjdnx6pcn6bdht4", + "time": 1698177444 + }, + { + "cid": "bafkreialaclllbtsaxzdhbbut4mk57xh4r7bsj56cb44fockdxokcznbk4", + "time": 1698178344 + }, + { + "cid": "bafkreialaclllbtsaxzdhbbut4mk57xh4r7bsj56cb44fockdxokcznbk4", + "time": 1698178344 + } + ], + "validationError": false + }, + { + "dpid": "112", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreictzmcsbe3bkmb7vyludvy7q37brvsw6q7xayblyn45r23n7ru224", + "time": 1698747720 + }, + { + "cid": "bafkreictzmcsbe3bkmb7vyludvy7q37brvsw6q7xayblyn45r23n7ru224", + "time": 1698747720 + }, + { + "cid": "bafkreifpbperacf57typaumiauqsf3kcmljgm7ehu2vjmlflwepddpeth4", + "time": 1698747864 + }, + { + "cid": "bafkreifpbperacf57typaumiauqsf3kcmljgm7ehu2vjmlflwepddpeth4", + "time": 1698747864 + } + ], + "validationError": false + }, + { + "dpid": "113", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreig2nlksggv4ghb24xw7ng23klrttx3kiu3tdlnsa2gcn2zacpmxa4", + "time": 1698782484 + }, + { + "cid": "bafkreig2nlksggv4ghb24xw7ng23klrttx3kiu3tdlnsa2gcn2zacpmxa4", + "time": 1698782484 + } + ], + "validationError": false + }, + { + "dpid": "114", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibsaosbasq6er4o2mkovemlp6tgppyeudue6lsx6dbznba56omd6e", + "time": 1698782652 + }, + { + "cid": "bafkreibsaosbasq6er4o2mkovemlp6tgppyeudue6lsx6dbznba56omd6e", + "time": 1698782652 + } + ], + "validationError": false + }, + { + "dpid": "115", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiaqt4amqtdha2affz4caq6qrl3uzk4zutwfnzcc6ba5ziw6itc2ty", + "time": 1699355412 + }, + { + "cid": "bafkreiaqt4amqtdha2affz4caq6qrl3uzk4zutwfnzcc6ba5ziw6itc2ty", + "time": 1699355412 + }, + { + "cid": "bafkreichmxylugiwhtrhomfjc7njdmp6isfivmdsflhmuzenzxnyl76m5i", + "time": 1699355784 + }, + { + "cid": "bafkreichmxylugiwhtrhomfjc7njdmp6isfivmdsflhmuzenzxnyl76m5i", + "time": 1699355784 + } + ], + "validationError": false + }, + { + "dpid": "116", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreid4spqoyg2mk2r7bcju6vkxsgtcx2fl27tyivtvrvnwlqgn26udn4", + "time": 1699608000 + }, + { + "cid": "bafkreid4spqoyg2mk2r7bcju6vkxsgtcx2fl27tyivtvrvnwlqgn26udn4", + "time": 1699608000 + }, + { + "cid": "bafkreiejv6ymnxxum5c67qpkvp2eevgy7rgksq7vhzgyfxg5riwl33lzqe", + "time": 1699887960 + }, + { + "cid": "bafkreiejv6ymnxxum5c67qpkvp2eevgy7rgksq7vhzgyfxg5riwl33lzqe", + "time": 1699887960 + }, + { + "cid": "bafkreibechybrdrnwlsg3unh2pgxg2jgekg653h37e4xzc3wazyzcjzegq", + "time": 1699954776 + }, + { + "cid": "bafkreibechybrdrnwlsg3unh2pgxg2jgekg653h37e4xzc3wazyzcjzegq", + "time": 1699954776 + } + ], + "validationError": false + }, + { + "dpid": "117", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiepbbtkhudgspd6dr4rnckaqwdenedehsvppkyakute6z36bplgpy", + "time": 1699954800 + }, + { + "cid": "bafkreiepbbtkhudgspd6dr4rnckaqwdenedehsvppkyakute6z36bplgpy", + "time": 1699954800 + }, + { + "cid": "bafkreids7cf6gagvaxbmammx6ekl4e3xwhcyw33vkqmy5ml2m4epvpjwua", + "time": 1700053860 + }, + { + "cid": "bafkreids7cf6gagvaxbmammx6ekl4e3xwhcyw33vkqmy5ml2m4epvpjwua", + "time": 1700053860 + } + ], + "validationError": false + }, + { + "dpid": "118", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihv7uzjstazrksvrdwrt6j3oqiw73oqi2krvwlzojbo5yhrfrpcu4", + "time": 1699979532 + }, + { + "cid": "bafkreihv7uzjstazrksvrdwrt6j3oqiw73oqi2krvwlzojbo5yhrfrpcu4", + "time": 1699979532 + }, + { + "cid": "bafkreifwnjaykar4vdhcpyimr73hklty7nqnm77u37rzmdyhldtlleycfy", + "time": 1702053972 + }, + { + "cid": "bafkreifwnjaykar4vdhcpyimr73hklty7nqnm77u37rzmdyhldtlleycfy", + "time": 1702053972 + } + ], + "validationError": false + }, + { + "dpid": "119", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifisxmqzztc3zgleheiakn4xn5w7ze6ap5iynom46djxue54nvk5i", + "time": 1699983900 + }, + { + "cid": "bafkreifisxmqzztc3zgleheiakn4xn5w7ze6ap5iynom46djxue54nvk5i", + "time": 1699983900 + }, + { + "cid": "bafkreihhg6k56gey42vldxac36u3ueleq4nzrm2zw5fxfcdmwcdrfyjpci", + "time": 1699984152 + }, + { + "cid": "bafkreihhg6k56gey42vldxac36u3ueleq4nzrm2zw5fxfcdmwcdrfyjpci", + "time": 1699984152 + } + ], + "validationError": false + }, + { + "dpid": "120", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifonv6z5enzbl44kwvh3i3m5stmagckblhfp4skmilmt72ff3dthe", + "time": 1699984440 + }, + { + "cid": "bafkreifonv6z5enzbl44kwvh3i3m5stmagckblhfp4skmilmt72ff3dthe", + "time": 1699984440 + } + ], + "validationError": false + }, + { + "dpid": "121", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreig7g2zbirxw3spdxicv6igvu4t2frzdbipzh4q2lp7a7vzsnktdym", + "time": 1699984896 + }, + { + "cid": "bafkreig7g2zbirxw3spdxicv6igvu4t2frzdbipzh4q2lp7a7vzsnktdym", + "time": 1699984896 + } + ], + "validationError": false + }, + { + "dpid": "122", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidhtfpm7qcv36eklavzuhq7dxbfq7a2o3ovv6q55qubyr7xnvpnm4", + "time": 1700005716 + }, + { + "cid": "bafkreidhtfpm7qcv36eklavzuhq7dxbfq7a2o3ovv6q55qubyr7xnvpnm4", + "time": 1700005716 + } + ], + "validationError": false + }, + { + "dpid": "123", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifuyc6nxavordwnewceq6tdzbzs4u5u7eiohs2lflwabdmhrrcxtm", + "time": 1700006352 + }, + { + "cid": "bafkreifuyc6nxavordwnewceq6tdzbzs4u5u7eiohs2lflwabdmhrrcxtm", + "time": 1700006352 + } + ], + "validationError": false + }, + { + "dpid": "124", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiccwsruwcne5ctm4bdarr6772xgxqdcy3jg66rthmd5iaq2hnexgi", + "time": 1700046408 + }, + { + "cid": "bafkreiccwsruwcne5ctm4bdarr6772xgxqdcy3jg66rthmd5iaq2hnexgi", + "time": 1700046408 + }, + { + "cid": "bafkreihi36k65e6jlytud7hcvtxru2xbkphtxbdu3xx2pkm53qwb5mjzge", + "time": 1700046432 + }, + { + "cid": "bafkreihi36k65e6jlytud7hcvtxru2xbkphtxbdu3xx2pkm53qwb5mjzge", + "time": 1700046432 + }, + { + "cid": "bafkreiezsp3ibhch3wf4arb4ies65exfex2isowpfsrrlq6pyvatiexr5q", + "time": 1700046552 + }, + { + "cid": "bafkreiezsp3ibhch3wf4arb4ies65exfex2isowpfsrrlq6pyvatiexr5q", + "time": 1700046552 + } + ], + "validationError": false + }, + { + "dpid": "125", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidsdl7s6pqakmfhfvcauof7ovylegxa5nwp2dxuxd5rbb27vsk4d4", + "time": 1700057772 + }, + { + "cid": "bafkreidsdl7s6pqakmfhfvcauof7ovylegxa5nwp2dxuxd5rbb27vsk4d4", + "time": 1700057772 + }, + { + "cid": "bafkreidjcemwjx3ljeuja3lety52fksvk2ojukxkxudbnwu7kgse2zz3tm", + "time": 1700058384 + }, + { + "cid": "bafkreidjcemwjx3ljeuja3lety52fksvk2ojukxkxudbnwu7kgse2zz3tm", + "time": 1700058384 + } + ], + "validationError": false + }, + { + "dpid": "126", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreib6z6ysfnyw6k6ly7cpdp7qjcjbbvjoffn4ppiarimmk33sbxuoy4", + "time": 1700059584 + }, + { + "cid": "bafkreib6z6ysfnyw6k6ly7cpdp7qjcjbbvjoffn4ppiarimmk33sbxuoy4", + "time": 1700059584 + } + ], + "validationError": false + }, + { + "dpid": "127", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibqnmfw4jhrjk4ggz63kqtti7rzxroutotrrey2j37a3ad2wfuojm", + "time": 1700063400 + }, + { + "cid": "bafkreibqnmfw4jhrjk4ggz63kqtti7rzxroutotrrey2j37a3ad2wfuojm", + "time": 1700063400 + }, + { + "cid": "bafkreifgaoapp6ku2zt3awb3svh3ol75stczvu2bon373bit4whaneb2lm", + "time": 1700063832 + }, + { + "cid": "bafkreifgaoapp6ku2zt3awb3svh3ol75stczvu2bon373bit4whaneb2lm", + "time": 1700063832 + }, + { + "cid": "bafkreibbb2gkxihablys2fjtrecr2tvfbujyulblivfqn4jsl6hyx5dghy", + "time": 1708492476 + }, + { + "cid": "bafkreibbb2gkxihablys2fjtrecr2tvfbujyulblivfqn4jsl6hyx5dghy", + "time": 1708492476 + } + ], + "validationError": false + }, + { + "dpid": "128", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihjgheci62x27bgduapkcmwbxldpwyk5af5kqvbpq2nmfmtfxdmmm", + "time": 1700063832 + }, + { + "cid": "bafkreihjgheci62x27bgduapkcmwbxldpwyk5af5kqvbpq2nmfmtfxdmmm", + "time": 1700063832 + } + ], + "validationError": false + }, + { + "dpid": "129", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigtnznzipcb6j4ufpnmde3e66pzl53n7etkxjj4waorkc2vfzban4", + "time": 1700754096 + }, + { + "cid": "bafkreigtnznzipcb6j4ufpnmde3e66pzl53n7etkxjj4waorkc2vfzban4", + "time": 1700754096 + } + ], + "validationError": false + }, + { + "dpid": "130", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiaiwepaj5h3ueggcvsp7rs6zsu5emvcbxg4aantq43mjrvkb46t5i", + "time": 1701434724 + }, + { + "cid": "bafkreiaiwepaj5h3ueggcvsp7rs6zsu5emvcbxg4aantq43mjrvkb46t5i", + "time": 1701434724 + } + ], + "validationError": false + }, + { + "dpid": "131", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidw5k6li7ex6goxdky37t6obgd3472rbgygmvu5rnf6iiptrqkmiy", + "time": 1701702708 + }, + { + "cid": "bafkreidw5k6li7ex6goxdky37t6obgd3472rbgygmvu5rnf6iiptrqkmiy", + "time": 1701702708 + }, + { + "cid": "bafkreiaa4eh2bmuwlutgnvnbbd64npfqdlzxzc75li5pzhlmdkrvj5qjrq", + "time": 1701703056 + }, + { + "cid": "bafkreiaa4eh2bmuwlutgnvnbbd64npfqdlzxzc75li5pzhlmdkrvj5qjrq", + "time": 1701703056 + } + ], + "validationError": false + }, + { + "dpid": "132", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifqxy2ie6a5gwqwjdrjzpuer3d5dwb4sauljj6coojnzprlvfes2e", + "time": 1701788316 + }, + { + "cid": "bafkreifqxy2ie6a5gwqwjdrjzpuer3d5dwb4sauljj6coojnzprlvfes2e", + "time": 1701788316 + } + ], + "validationError": false + }, + { + "dpid": "133", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifyxvaek2nsdtke62wviupn7qqtgzeucrpe5c66lrycvtvestkkau", + "time": 1701795900 + }, + { + "cid": "bafkreifyxvaek2nsdtke62wviupn7qqtgzeucrpe5c66lrycvtvestkkau", + "time": 1701795900 + } + ], + "validationError": false + }, + { + "dpid": "134", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigu4xxysvqtf6cicat3iheugi6g45vsgnptbrht6p6om3txvsttye", + "time": 1701872976 + }, + { + "cid": "bafkreigu4xxysvqtf6cicat3iheugi6g45vsgnptbrht6p6om3txvsttye", + "time": 1701872976 + } + ], + "validationError": false + }, + { + "dpid": "135", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihf45jsg5rnkpv2mz2wwpf5w3u6ixu765a5hckam3j3fbl5i2tgbq", + "time": 1701875664 + }, + { + "cid": "bafkreihf45jsg5rnkpv2mz2wwpf5w3u6ixu765a5hckam3j3fbl5i2tgbq", + "time": 1701875664 + } + ], + "validationError": false + }, + { + "dpid": "136", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreih5g3pbinh264nuwgvsuerueucgpacv5ytill4sbxt7zsexgfntqi", + "time": 1702142316 + }, + { + "cid": "bafkreih5g3pbinh264nuwgvsuerueucgpacv5ytill4sbxt7zsexgfntqi", + "time": 1702142316 + }, + { + "cid": "bafkreiaitokvbuwllmihafculxuniwiydtl2cuuuhqbmkuvpk62uuhmu4e", + "time": 1702145736 + }, + { + "cid": "bafkreiaitokvbuwllmihafculxuniwiydtl2cuuuhqbmkuvpk62uuhmu4e", + "time": 1702145736 + }, + { + "cid": "bafkreifyo3tzgp3bp7a7zwxym6lskt567rdvjn4t334dczglkvgbpglla4", + "time": 1702202688 + }, + { + "cid": "bafkreifyo3tzgp3bp7a7zwxym6lskt567rdvjn4t334dczglkvgbpglla4", + "time": 1702202688 + }, + { + "cid": "bafkreif4yaj5za2adpy3wmklbstwpaciobl3j4uwcwrwcri7bbkcvwik6q", + "time": 1708382904 + }, + { + "cid": "bafkreif4yaj5za2adpy3wmklbstwpaciobl3j4uwcwrwcri7bbkcvwik6q", + "time": 1708382904 + } + ], + "validationError": false + }, + { + "dpid": "137", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiebtockthsjrwsikbjshzdikjsa3j35avolyabw2zl5nxd4np2qa4", + "time": 1702430448 + }, + { + "cid": "bafkreiebtockthsjrwsikbjshzdikjsa3j35avolyabw2zl5nxd4np2qa4", + "time": 1702430448 + }, + { + "cid": "bafkreig5muvzq5a5whji264zbzpkd452kqiswo4on3b3waibrwcte6n2jq", + "time": 1702439796 + }, + { + "cid": "bafkreig5muvzq5a5whji264zbzpkd452kqiswo4on3b3waibrwcte6n2jq", + "time": 1702439796 + } + ], + "validationError": false + }, + { + "dpid": "138", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiezlcl57kasksq7hwdqxsffpqloek4jbr4vrvausbg6ozsrnwnkfq", + "time": 1702512600 + }, + { + "cid": "bafkreiezlcl57kasksq7hwdqxsffpqloek4jbr4vrvausbg6ozsrnwnkfq", + "time": 1702512600 + }, + { + "cid": "bafkreifxevx7yu5noaquu4bojmyl6pubqotkp4wsbjpd6vbz3neuk7nlxu", + "time": 1707153744 + }, + { + "cid": "bafkreifxevx7yu5noaquu4bojmyl6pubqotkp4wsbjpd6vbz3neuk7nlxu", + "time": 1707153744 + } + ], + "validationError": false + }, + { + "dpid": "139", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreictkrrk3arfcy4rstvjjtpwrw3yf7wdgxepf5z2cmjuiv2igkdlnm", + "time": 1702512876 + }, + { + "cid": "bafkreictkrrk3arfcy4rstvjjtpwrw3yf7wdgxepf5z2cmjuiv2igkdlnm", + "time": 1702512876 + } + ], + "validationError": false + }, + { + "dpid": "140", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibz4nvkwdmqxmtxefklebrqrhbbhias3bvt7moko5jgw6hopkhwga", + "time": 1702513068 + }, + { + "cid": "bafkreibz4nvkwdmqxmtxefklebrqrhbbhias3bvt7moko5jgw6hopkhwga", + "time": 1702513068 + }, + { + "cid": "bafkreifbhbxfm6s6djz5taz5buthqlpy2cruaysfnixojzubwgkprsbq4i", + "time": 1708801020 + }, + { + "cid": "bafkreifbhbxfm6s6djz5taz5buthqlpy2cruaysfnixojzubwgkprsbq4i", + "time": 1708801020 + } + ], + "validationError": false + }, + { + "dpid": "141", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifkjw3mjt4ib4dhjjpn2sbv3oqf4c5mcf5n7zlggynvvqlwksdxay", + "time": 1702513164 + }, + { + "cid": "bafkreifkjw3mjt4ib4dhjjpn2sbv3oqf4c5mcf5n7zlggynvvqlwksdxay", + "time": 1702513164 + }, + { + "cid": "bafkreiabv34brs4dnbivmzfyggc2ryaxs7zlb3x3zh2ynie53suktlitva", + "time": 1708802436 + }, + { + "cid": "bafkreiabv34brs4dnbivmzfyggc2ryaxs7zlb3x3zh2ynie53suktlitva", + "time": 1708802436 + }, + { + "cid": "bafkreiabv34brs4dnbivmzfyggc2ryaxs7zlb3x3zh2ynie53suktlitva", + "time": 1708802436 + }, + { + "cid": "bafkreiabv34brs4dnbivmzfyggc2ryaxs7zlb3x3zh2ynie53suktlitva", + "time": 1708802436 + } + ], + "validationError": false + }, + { + "dpid": "142", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidll4iaylvaplqqqotp3e7bolx3qgqnjkzliplbhdz7v7dcrdn65q", + "time": 1702513344 + }, + { + "cid": "bafkreidll4iaylvaplqqqotp3e7bolx3qgqnjkzliplbhdz7v7dcrdn65q", + "time": 1702513344 + }, + { + "cid": "bafkreieszmyc5ph43ft77gk4pj5emhuy53if6vjbeejzxbrtusxb3ouq54", + "time": 1708802160 + }, + { + "cid": "bafkreieszmyc5ph43ft77gk4pj5emhuy53if6vjbeejzxbrtusxb3ouq54", + "time": 1708802160 + } + ], + "validationError": false + }, + { + "dpid": "143", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidjonu3vhm5vd5fogs3zrjzq3qcajjkpvwwj43gdqn2swiops5glm", + "time": 1702513392 + }, + { + "cid": "bafkreidjonu3vhm5vd5fogs3zrjzq3qcajjkpvwwj43gdqn2swiops5glm", + "time": 1702513392 + }, + { + "cid": "bafkreih25vwbntxxybpsxctpg5eqi6f7ewcwzqzpklifbfqffcrbs65k64", + "time": 1708802052 + }, + { + "cid": "bafkreih25vwbntxxybpsxctpg5eqi6f7ewcwzqzpklifbfqffcrbs65k64", + "time": 1708802052 + } + ], + "validationError": false + }, + { + "dpid": "144", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreieogvypbmg7vgut2f76b33kql6cw4vstzm4f7asoenfzh2rudpekm", + "time": 1702513452 + }, + { + "cid": "bafkreieogvypbmg7vgut2f76b33kql6cw4vstzm4f7asoenfzh2rudpekm", + "time": 1702513452 + }, + { + "cid": "bafkreib3b6ztd5tyebhjtxsj4dpl2nw3bipejak5n3zz7u7ta3et2ghyoq", + "time": 1708801908 + }, + { + "cid": "bafkreib3b6ztd5tyebhjtxsj4dpl2nw3bipejak5n3zz7u7ta3et2ghyoq", + "time": 1708801908 + } + ], + "validationError": false + }, + { + "dpid": "145", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibbu3bk7ucli5yaikmcwdduigaien2dqb2bzq4af6ufzrmu6vswty", + "time": 1702513524 + }, + { + "cid": "bafkreibbu3bk7ucli5yaikmcwdduigaien2dqb2bzq4af6ufzrmu6vswty", + "time": 1702513524 + }, + { + "cid": "bafkreig2mtcbf6eu2vraqmy5ftukn4i6fgeiwfou2znswwss5sarsotmcm", + "time": 1708801680 + }, + { + "cid": "bafkreig2mtcbf6eu2vraqmy5ftukn4i6fgeiwfou2znswwss5sarsotmcm", + "time": 1708801680 + } + ], + "validationError": false + }, + { + "dpid": "146", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreied3q6xs3itsgvjgeybu5cnmuuds2puklksrhfvy4ofjddo3nkyle", + "time": 1702513584 + }, + { + "cid": "bafkreied3q6xs3itsgvjgeybu5cnmuuds2puklksrhfvy4ofjddo3nkyle", + "time": 1702513584 + } + ], + "validationError": false + }, + { + "dpid": "147", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiapkcqpkavfwqc4id5mb7e46n3f5nr5uig4ik7bwaxk7a5tox2ztq", + "time": 1702513620 + }, + { + "cid": "bafkreiapkcqpkavfwqc4id5mb7e46n3f5nr5uig4ik7bwaxk7a5tox2ztq", + "time": 1702513620 + }, + { + "cid": "bafkreifxvagntjqfpzrigsjfajflqatzk4dogq56lqotaqjv7d3iugdrtm", + "time": 1708801212 + }, + { + "cid": "bafkreifxvagntjqfpzrigsjfajflqatzk4dogq56lqotaqjv7d3iugdrtm", + "time": 1708801212 + }, + { + "cid": "bafkreifxvagntjqfpzrigsjfajflqatzk4dogq56lqotaqjv7d3iugdrtm", + "time": 1708801236 + }, + { + "cid": "bafkreifxvagntjqfpzrigsjfajflqatzk4dogq56lqotaqjv7d3iugdrtm", + "time": 1708801236 + } + ], + "validationError": false + }, + { + "dpid": "148", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibgprhlr22zfwgrm7y3kx4jxslpozqp4pmofsrj5tbqpkaxi5glpe", + "time": 1702559448 + }, + { + "cid": "bafkreibgprhlr22zfwgrm7y3kx4jxslpozqp4pmofsrj5tbqpkaxi5glpe", + "time": 1702559448 + }, + { + "cid": "bafkreieqjqllffddjuraswoq4pm5d5cd5eu2knqe6yie7rj6aufujtct4e", + "time": 1702907160 + }, + { + "cid": "bafkreieqjqllffddjuraswoq4pm5d5cd5eu2knqe6yie7rj6aufujtct4e", + "time": 1702907160 + } + ], + "validationError": false + }, + { + "dpid": "149", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigcc2l7aay34i5zeot5wjvpspdpwp6ipfzffs3cnnpbpt7c2gqu6i", + "time": 1703003448 + }, + { + "cid": "bafkreigcc2l7aay34i5zeot5wjvpspdpwp6ipfzffs3cnnpbpt7c2gqu6i", + "time": 1703003448 + }, + { + "cid": "bafkreig6lp6265u42llqh6hkzxc54hmyfea7ax7gewg7tdyvthieotmwpy", + "time": 1703003868 + }, + { + "cid": "bafkreig6lp6265u42llqh6hkzxc54hmyfea7ax7gewg7tdyvthieotmwpy", + "time": 1703003868 + }, + { + "cid": "bafkreici3wzz7njqigyo7ebzwn3kibxgwjr43ihowwebl4exmfy75tkpjm", + "time": 1703072388 + }, + { + "cid": "bafkreici3wzz7njqigyo7ebzwn3kibxgwjr43ihowwebl4exmfy75tkpjm", + "time": 1703072388 + }, + { + "cid": "bafkreicgxdcypaq5tmmrrva3tl7k2un47pfolg3mox72j5k65zitsukfii", + "time": 1707406116 + }, + { + "cid": "bafkreicgxdcypaq5tmmrrva3tl7k2un47pfolg3mox72j5k65zitsukfii", + "time": 1707406116 + }, + { + "cid": "bafkreie7j6ji7ynh5d5yoldoxfevak55nkmcx5h7v3c6h4xy7le25sbgke", + "time": 1709143824 + }, + { + "cid": "bafkreie7j6ji7ynh5d5yoldoxfevak55nkmcx5h7v3c6h4xy7le25sbgke", + "time": 1709143824 + } + ], + "validationError": false + }, + { + "dpid": "150", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreif3aoauxavq7sxibkysi4kemqdwbcez4cjtmzoou46bj44r2rc3sa", + "time": 1703205816 + }, + { + "cid": "bafkreif3aoauxavq7sxibkysi4kemqdwbcez4cjtmzoou46bj44r2rc3sa", + "time": 1703205816 + } + ], + "validationError": false + }, + { + "dpid": "151", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicqe2blgjarm3bg6jon5sjvmu773bnuajfnkmlnvo5hd5uj2yr234", + "time": 1703212224 + }, + { + "cid": "bafkreicqe2blgjarm3bg6jon5sjvmu773bnuajfnkmlnvo5hd5uj2yr234", + "time": 1703212224 + } + ], + "validationError": false + }, + { + "dpid": "152", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifiy2ipxllse5z6kspsspgt247eadivoij736j3yehwe6cy5rn6ny", + "time": 1705091376 + }, + { + "cid": "bafkreifiy2ipxllse5z6kspsspgt247eadivoij736j3yehwe6cy5rn6ny", + "time": 1705091376 + }, + { + "cid": "bafkreihvutuhtiehsoyc66u7a7bncnqfhoosynejagkykkfwa7gkr2rsta", + "time": 1705091496 + }, + { + "cid": "bafkreihvutuhtiehsoyc66u7a7bncnqfhoosynejagkykkfwa7gkr2rsta", + "time": 1705091496 + }, + { + "cid": "bafkreiekobyktiisailjk2sauqxembzyqe26z7i7mxkl6xidhhlb62wnyi", + "time": 1706832732 + }, + { + "cid": "bafkreiekobyktiisailjk2sauqxembzyqe26z7i7mxkl6xidhhlb62wnyi", + "time": 1706832732 + } + ], + "validationError": false + }, + { + "dpid": "153", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigr54hmercrddm2nnyo46yfn3w466zeoawph7k23swzr5v6lobcjm", + "time": 1705491780 + }, + { + "cid": "bafkreigr54hmercrddm2nnyo46yfn3w466zeoawph7k23swzr5v6lobcjm", + "time": 1705491780 + } + ], + "validationError": false + }, + { + "dpid": "154", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidzawjc7uaskxy2a55gfd3pjqssl5v6nfqj4ghziglbdfuk3arfri", + "time": 1705579488 + }, + { + "cid": "bafkreidzawjc7uaskxy2a55gfd3pjqssl5v6nfqj4ghziglbdfuk3arfri", + "time": 1705579488 + } + ], + "validationError": false + }, + { + "dpid": "155", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreieqqvt2bx34g44zombuj254dzqng5l4bjc33vnuduiaklfjf7jrza", + "time": 1706550924 + }, + { + "cid": "bafkreieqqvt2bx34g44zombuj254dzqng5l4bjc33vnuduiaklfjf7jrza", + "time": 1706550924 + } + ], + "validationError": false + }, + { + "dpid": "156", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibhuuogniwgsozq6zqgpfg622ktaz4e4xtspvxv6be7zoaknlp7oi", + "time": 1706735148 + }, + { + "cid": "bafkreibhuuogniwgsozq6zqgpfg622ktaz4e4xtspvxv6be7zoaknlp7oi", + "time": 1706735148 + }, + { + "cid": "bafkreicmyxjhueivvlucnysc5sgmdnxgsmn5wryaodmdwl7xhku5o4dwki", + "time": 1706737632 + }, + { + "cid": "bafkreicmyxjhueivvlucnysc5sgmdnxgsmn5wryaodmdwl7xhku5o4dwki", + "time": 1706737632 + } + ], + "validationError": false + }, + { + "dpid": "157", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreificypwhqbtu4acdrxgbzdrpbw5dncxrcwtskrebhv53trsk23ive", + "time": 1706738172 + }, + { + "cid": "bafkreificypwhqbtu4acdrxgbzdrpbw5dncxrcwtskrebhv53trsk23ive", + "time": 1706738172 + } + ], + "validationError": false + }, + { + "dpid": "158", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigmgjpsfxzshdvozllx3m6s5ubiulcx7yumhe7armganzdiu42feu", + "time": 1706834520 + }, + { + "cid": "bafkreigmgjpsfxzshdvozllx3m6s5ubiulcx7yumhe7armganzdiu42feu", + "time": 1706834520 + } + ], + "validationError": false + }, + { + "dpid": "159", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifl7hhai6p5podahrcse5ocklgf2qdayw33raeaugk4cjgugroupq", + "time": 1707473772 + }, + { + "cid": "bafkreifl7hhai6p5podahrcse5ocklgf2qdayw33raeaugk4cjgugroupq", + "time": 1707473772 + } + ], + "validationError": false + }, + { + "dpid": "160", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifjtpqkpatgmy4jpmhsepfvpv2gmiofgyh6qpinfnstyrsufickua", + "time": 1707644916 + }, + { + "cid": "bafkreifjtpqkpatgmy4jpmhsepfvpv2gmiofgyh6qpinfnstyrsufickua", + "time": 1707644916 + }, + { + "cid": "bafkreif2hl47drgqwb6qay5dbdmmm4ivbcfus3wromwaho2wxine6niudm", + "time": 1707645552 + }, + { + "cid": "bafkreif2hl47drgqwb6qay5dbdmmm4ivbcfus3wromwaho2wxine6niudm", + "time": 1707645552 + }, + { + "cid": "bafkreihopqbkiidgwszltgcx3cp3n5m3vkfcyqf5tktaf7zpikdwqkpkmu", + "time": 1707646572 + }, + { + "cid": "bafkreihopqbkiidgwszltgcx3cp3n5m3vkfcyqf5tktaf7zpikdwqkpkmu", + "time": 1707646572 + } + ], + "validationError": false + }, + { + "dpid": "161", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreialnzhaztvhuvwkzpqlst7w3yttviws5tcpdnwvggdmxnx2ydzere", + "time": 1707848244 + }, + { + "cid": "bafkreialnzhaztvhuvwkzpqlst7w3yttviws5tcpdnwvggdmxnx2ydzere", + "time": 1707848244 + } + ], + "validationError": false + }, + { + "dpid": "162", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreieowcw35rvuvocaupds5fsremm4h6j3cris5sscfjun4o2e4bccla", + "time": 1707967356 + }, + { + "cid": "bafkreieowcw35rvuvocaupds5fsremm4h6j3cris5sscfjun4o2e4bccla", + "time": 1707967356 + } + ], + "validationError": false + }, + { + "dpid": "163", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreif4554qs4ppds7364pfeqla623ebon5nlvs5m53ecw4jhdkmtnfre", + "time": 1707967740 + }, + { + "cid": "bafkreif4554qs4ppds7364pfeqla623ebon5nlvs5m53ecw4jhdkmtnfre", + "time": 1707967740 + } + ], + "validationError": false + }, + { + "dpid": "164", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidn5fdrmh62nc4r3g5paqija32flksc23evsc5akqoqftkwfeqm2i", + "time": 1708094712 + }, + { + "cid": "bafkreidn5fdrmh62nc4r3g5paqija32flksc23evsc5akqoqftkwfeqm2i", + "time": 1708094712 + }, + { + "cid": "bafkreibpaflwrfhygpheciwlemvahtkkwdgg35dnevu25rid46iae2ws6i", + "time": 1708453920 + }, + { + "cid": "bafkreibpaflwrfhygpheciwlemvahtkkwdgg35dnevu25rid46iae2ws6i", + "time": 1708453920 + }, + { + "cid": "bafkreif7javbr3hrnuwmoggv7dtprs7axcsdldsqpwmpfcdizy5bk2tfxa", + "time": 1708514124 + }, + { + "cid": "bafkreif7javbr3hrnuwmoggv7dtprs7axcsdldsqpwmpfcdizy5bk2tfxa", + "time": 1708514124 + } + ], + "validationError": false + }, + { + "dpid": "165", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicv2zf35h43m656h2734du5ynp2zctedwxkgwtbhubg34oenhhexa", + "time": 1708109700 + }, + { + "cid": "bafkreicv2zf35h43m656h2734du5ynp2zctedwxkgwtbhubg34oenhhexa", + "time": 1708109700 + } + ], + "validationError": false + }, + { + "dpid": "166", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibfvwqckon265lpmjuinzlg6ebzo4s6dtgh7invz2prf766bvuodm", + "time": 1708372176 + }, + { + "cid": "bafkreibfvwqckon265lpmjuinzlg6ebzo4s6dtgh7invz2prf766bvuodm", + "time": 1708372176 + } + ], + "validationError": false + }, + { + "dpid": "167", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreige2oxxkk4rboadjcxlvwbvlun3e4xmrxp4qtqvdmjdfzhptuyf5a", + "time": 1708458984 + }, + { + "cid": "bafkreige2oxxkk4rboadjcxlvwbvlun3e4xmrxp4qtqvdmjdfzhptuyf5a", + "time": 1708458984 + } + ], + "validationError": false + }, + { + "dpid": "168", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiftjc6urzlqlcffupjwnezhfash4tlvgy2qnstu2vpp6tdk4zpmma", + "time": 1708493796 + }, + { + "cid": "bafkreiftjc6urzlqlcffupjwnezhfash4tlvgy2qnstu2vpp6tdk4zpmma", + "time": 1708493796 + }, + { + "cid": "bafkreic4hj66auaehgtgoz6zzks2w2r7lsxhrisjuh7dbfipvgmkhfpace", + "time": 1708690584 + }, + { + "cid": "bafkreic4hj66auaehgtgoz6zzks2w2r7lsxhrisjuh7dbfipvgmkhfpace", + "time": 1708690584 + } + ], + "validationError": false + }, + { + "dpid": "169", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidguz57tkqtmta44oov6jkgxxeg635asddp2belouydyxjndukspi", + "time": 1708495980 + }, + { + "cid": "bafkreidguz57tkqtmta44oov6jkgxxeg635asddp2belouydyxjndukspi", + "time": 1708495980 + } + ], + "validationError": false + }, + { + "dpid": "170", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidyakyvrrmovwk4ddfw2fxtgkl3f4coef75pybncmoa55jnlxx6tm", + "time": 1708501884 + }, + { + "cid": "bafkreidyakyvrrmovwk4ddfw2fxtgkl3f4coef75pybncmoa55jnlxx6tm", + "time": 1708501884 + }, + { + "cid": "bafkreiddvndkkcaqwdmetqxfl2vhfag45c4cug6aubsnlrl7uk66y3pzrq", + "time": 1710843672 + }, + { + "cid": "bafkreibsbid5gceknfrbun76wrdq73vzglgxq25yy2pg7fnpflfuucem6e", + "time": 1710844824 + }, + { + "cid": "bafkreibsbid5gceknfrbun76wrdq73vzglgxq25yy2pg7fnpflfuucem6e", + "time": 1710845520 + }, + { + "cid": "bafkreiav726womo5gxdii7ootir2uuhdn34fzej3f6ala7xynge6ag543a", + "time": 1710846540 + } + ], + "validationError": false + }, + { + "dpid": "171", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibtajzmf7ty7hhyclz4aj5f74mktbj4liyhobvs3qr7nebqprl2yi", + "time": 1708516896 + }, + { + "cid": "bafkreibtajzmf7ty7hhyclz4aj5f74mktbj4liyhobvs3qr7nebqprl2yi", + "time": 1708516896 + } + ], + "validationError": false + }, + { + "dpid": "172", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicenejlzy2ygk6vflo4xhr7hjqe22nz5f354afoo5pc65d6qf2ojq", + "time": 1708523184 + }, + { + "cid": "bafkreicenejlzy2ygk6vflo4xhr7hjqe22nz5f354afoo5pc65d6qf2ojq", + "time": 1708523184 + }, + { + "cid": "bafkreibhvfaxoampgahsqavwoc3r5qwsmb23cg5lavkgoak77x4htgjism", + "time": 1712669388 + }, + { + "cid": "bafkreiab7zb4iwbnd6atuukrzkjcph7hbc763rqxnhrl3xtk7c73c3ofsi", + "time": 1712679120 + }, + { + "cid": "bafkreifxjj6yjggeno26fceojxb3ibuoaszeettsqwumuw337owiu2goaq", + "time": 1712758368 + }, + { + "cid": "bafkreic5tnpaovahue6zvswongz52o2kog7ngwiawcmwcq63xskxfwltdm", + "time": 1712854176 + }, + { + "cid": "bafkreic5tnpaovahue6zvswongz52o2kog7ngwiawcmwcq63xskxfwltdm", + "time": 1712859180 + }, + { + "cid": "bafkreignqmhx4yaaaqytcf2q7hhvbhyz5nrsqq4sv23jbenzs65luutaqu", + "time": 1713200220 + }, + { + "cid": "bafkreihv4owtfk4yfhljptkfrcsnt6nnaobbgsfl4h2ivxgi3kbtvzspc4", + "time": 1713212124 + } + ], + "validationError": false + }, + { + "dpid": "173", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreie23vmvink27bqo7qzzsdng4ho22uhrgoscencr7s4itekrzreahy", + "time": 1708531344 + }, + { + "cid": "bafkreie23vmvink27bqo7qzzsdng4ho22uhrgoscencr7s4itekrzreahy", + "time": 1708531344 + }, + { + "cid": "bafkreie23vmvink27bqo7qzzsdng4ho22uhrgoscencr7s4itekrzreahy", + "time": 1708531620 + }, + { + "cid": "bafkreie23vmvink27bqo7qzzsdng4ho22uhrgoscencr7s4itekrzreahy", + "time": 1708531620 + }, + { + "cid": "bafkreie23vmvink27bqo7qzzsdng4ho22uhrgoscencr7s4itekrzreahy", + "time": 1708531992 + }, + { + "cid": "bafkreie23vmvink27bqo7qzzsdng4ho22uhrgoscencr7s4itekrzreahy", + "time": 1708531992 + }, + { + "cid": "bafkreie23vmvink27bqo7qzzsdng4ho22uhrgoscencr7s4itekrzreahy", + "time": 1708532064 + }, + { + "cid": "bafkreie23vmvink27bqo7qzzsdng4ho22uhrgoscencr7s4itekrzreahy", + "time": 1708532064 + } + ], + "validationError": false + }, + { + "dpid": "174", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidobtwdrk7dulyc6dghfr6zylbfisjwbs6l6ahd6qfkfdavs76dpa", + "time": 1708602732 + }, + { + "cid": "bafkreidobtwdrk7dulyc6dghfr6zylbfisjwbs6l6ahd6qfkfdavs76dpa", + "time": 1708602732 + } + ], + "validationError": false + }, + { + "dpid": "175", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreignopdmerljfo6nzpq2hj5zr5g7h3wajjxthpuikxjpsdbco4tavm", + "time": 1708619376 + }, + { + "cid": "bafkreignopdmerljfo6nzpq2hj5zr5g7h3wajjxthpuikxjpsdbco4tavm", + "time": 1708619376 + }, + { + "cid": "bafkreiae65pw54dt5vx75oenehagushpi2sh42c3zqld7der3ircmfyqam", + "time": 1708653516 + }, + { + "cid": "bafkreiae65pw54dt5vx75oenehagushpi2sh42c3zqld7der3ircmfyqam", + "time": 1708653516 + }, + { + "cid": "bafkreihm7iuibrdzlr5uyrhhkyijboyheeujettcihcgmegrna43mmvs6a", + "time": 1708672332 + }, + { + "cid": "bafkreihm7iuibrdzlr5uyrhhkyijboyheeujettcihcgmegrna43mmvs6a", + "time": 1708672332 + }, + { + "cid": "bafkreicjzr7d4odl6dzvx3acnng3cwq5sptcjn5wbqeep4juymadohagfi", + "time": 1708674912 + }, + { + "cid": "bafkreicjzr7d4odl6dzvx3acnng3cwq5sptcjn5wbqeep4juymadohagfi", + "time": 1708674912 + }, + { + "cid": "bafkreihdgbp3rrimo3sfayouabpfy5awspr6lues5rj5pjld2mcwi5ftsm", + "time": 1708729500 + }, + { + "cid": "bafkreihdgbp3rrimo3sfayouabpfy5awspr6lues5rj5pjld2mcwi5ftsm", + "time": 1708729500 + }, + { + "cid": "bafkreidpouvko3ht6dkhplrx44r4cbycx4irvw6mnunven3x2mll5kgaie", + "time": 1708890600 + }, + { + "cid": "bafkreidpouvko3ht6dkhplrx44r4cbycx4irvw6mnunven3x2mll5kgaie", + "time": 1708890600 + } + ], + "validationError": false + }, + { + "dpid": "176", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidwx6vv43n4vyd2gvnc7a7hoalg3nj6ncuxtzete7bay6lgkdjrji", + "time": 1708695348 + }, + { + "cid": "bafkreidwx6vv43n4vyd2gvnc7a7hoalg3nj6ncuxtzete7bay6lgkdjrji", + "time": 1708695348 + }, + { + "cid": "bafkreibjcr22ex3uibpoxf3fpzriafscmbivizzkqrjx7iqh5qbkg4oizq", + "time": 1708695612 + }, + { + "cid": "bafkreibjcr22ex3uibpoxf3fpzriafscmbivizzkqrjx7iqh5qbkg4oizq", + "time": 1708695612 + } + ], + "validationError": false + }, + { + "dpid": "177", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihnul5baol6hg5vsq6sokqwbm5txyb5honlphs3rpjklc4d7pj4qi", + "time": 1708882260 + }, + { + "cid": "bafkreihnul5baol6hg5vsq6sokqwbm5txyb5honlphs3rpjklc4d7pj4qi", + "time": 1708882260 + }, + { + "cid": "bafkreidp7tepg63xchd2sxngslv6douzhg53j7ndnf4bwbxgwthvjxgmhq", + "time": 1715951676 + } + ], + "validationError": false + }, + { + "dpid": "178", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibnvu2kmntm4p2ttebfqukas5hdzzthyahkkgxizihb4f3fwvszoy", + "time": 1708900272 + }, + { + "cid": "bafkreibnvu2kmntm4p2ttebfqukas5hdzzthyahkkgxizihb4f3fwvszoy", + "time": 1708900272 + }, + { + "cid": "bafkreibax2nwfvcmewzi4muxbtywulni6zvvihnipob3hvweohuu3lmawu", + "time": 1708900680 + }, + { + "cid": "bafkreibax2nwfvcmewzi4muxbtywulni6zvvihnipob3hvweohuu3lmawu", + "time": 1708900680 + }, + { + "cid": "bafkreiaicia5j7xdpo5gr3nukomg7kylxpnyfiguflr7ff5z6v45rbg3om", + "time": 1708909188 + }, + { + "cid": "bafkreiaicia5j7xdpo5gr3nukomg7kylxpnyfiguflr7ff5z6v45rbg3om", + "time": 1708909188 + } + ], + "validationError": false + }, + { + "dpid": "179", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiekmumtbr6fg6ksitwx3744knbituhthjis3mnd5facdbqc6526fy", + "time": 1708930572 + }, + { + "cid": "bafkreiekmumtbr6fg6ksitwx3744knbituhthjis3mnd5facdbqc6526fy", + "time": 1708930572 + } + ], + "validationError": false + }, + { + "dpid": "180", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihyn2pm7mqzcjabytkoszcetquu4q6zouwaeqhp6bavvlmijqvj2m", + "time": 1708965960 + }, + { + "cid": "bafkreihyn2pm7mqzcjabytkoszcetquu4q6zouwaeqhp6bavvlmijqvj2m", + "time": 1708965960 + }, + { + "cid": "bafkreigksvcw5f67h2kzbxnndwf47ch74nb4vbniepacjt6y5nm74ote4m", + "time": 1708966848 + }, + { + "cid": "bafkreigksvcw5f67h2kzbxnndwf47ch74nb4vbniepacjt6y5nm74ote4m", + "time": 1708966848 + }, + { + "cid": "bafkreifhzq76yqo66hcvcj2e7554odbcppblavfrobmyuxynaj2wv2ydlm", + "time": 1708974048 + }, + { + "cid": "bafkreifhzq76yqo66hcvcj2e7554odbcppblavfrobmyuxynaj2wv2ydlm", + "time": 1708974048 + } + ], + "validationError": false + }, + { + "dpid": "181", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreieqzlofquf3yakkfcqwzzg77ea6qrirnbli6iedpeo5zk2hktedfe", + "time": 1709032560 + }, + { + "cid": "bafkreieqzlofquf3yakkfcqwzzg77ea6qrirnbli6iedpeo5zk2hktedfe", + "time": 1709032560 + } + ], + "validationError": false + }, + { + "dpid": "182", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidjaowinhp5e3m6ikq32mfgqg5mqw6ttzccngl5aa2imyryscenjq", + "time": 1709070444 + }, + { + "cid": "bafkreidjaowinhp5e3m6ikq32mfgqg5mqw6ttzccngl5aa2imyryscenjq", + "time": 1709070444 + }, + { + "cid": "bafkreidjaowinhp5e3m6ikq32mfgqg5mqw6ttzccngl5aa2imyryscenjq", + "time": 1709070600 + }, + { + "cid": "bafkreidjaowinhp5e3m6ikq32mfgqg5mqw6ttzccngl5aa2imyryscenjq", + "time": 1709070600 + } + ], + "validationError": false + }, + { + "dpid": "183", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihfy4ibvcrdxlq3n6y6ahskxglvyhskwugy7xwi4amk4dcek7hvvi", + "time": 1709074644 + }, + { + "cid": "bafkreihfy4ibvcrdxlq3n6y6ahskxglvyhskwugy7xwi4amk4dcek7hvvi", + "time": 1709074644 + } + ], + "validationError": false + }, + { + "dpid": "184", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreif4pg7ph3qxuj4yoapw4tez3jxt52m5fhp7nkd3q2ai4xrwva46oq", + "time": 1709709132 + }, + { + "cid": "bafkreif4pg7ph3qxuj4yoapw4tez3jxt52m5fhp7nkd3q2ai4xrwva46oq", + "time": 1709709132 + } + ], + "validationError": false + }, + { + "dpid": "185", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibbt24dc64gwzwhcjtyha5qsdvmj4ztlkbhg7p7s74hjpdlrveo5a", + "time": 1709710296 + }, + { + "cid": "bafkreibbt24dc64gwzwhcjtyha5qsdvmj4ztlkbhg7p7s74hjpdlrveo5a", + "time": 1709710296 + } + ], + "validationError": false + }, + { + "dpid": "186", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiezmycqcs3426uhlpamwfidxlt72njmc22cuma47fxx5e3oi7zrpq", + "time": 1709713596 + }, + { + "cid": "bafkreiezmycqcs3426uhlpamwfidxlt72njmc22cuma47fxx5e3oi7zrpq", + "time": 1709713596 + } + ], + "validationError": false + }, + { + "dpid": "187", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiemcbfxzi5v3sjiztw4zqs7ngbbirmbcza2sxag4ur4gx3jc57weu", + "time": 1709713968 + }, + { + "cid": "bafkreiemcbfxzi5v3sjiztw4zqs7ngbbirmbcza2sxag4ur4gx3jc57weu", + "time": 1709713968 + } + ], + "validationError": false + }, + { + "dpid": "188", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifc7blw4sfdrqqyinooyk2zajg4kvobazfpxmmyxhky67xyrtg2bi", + "time": 1709717856 + }, + { + "cid": "bafkreifc7blw4sfdrqqyinooyk2zajg4kvobazfpxmmyxhky67xyrtg2bi", + "time": 1709717856 + } + ], + "validationError": false + }, + { + "dpid": "189", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreib5w5wqatnhuuekzdmqe33ci4jmczwtcw235mdugsk6sbjkewhycq", + "time": 1709718156 + }, + { + "cid": "bafkreib5w5wqatnhuuekzdmqe33ci4jmczwtcw235mdugsk6sbjkewhycq", + "time": 1709718156 + } + ], + "validationError": false + }, + { + "dpid": "190", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidlwnin6u3lbb5me7gsaomtrz3xfxruteb3oqvng2isup6dq2md2u", + "time": 1710044316 + }, + { + "cid": "bafkreidlwnin6u3lbb5me7gsaomtrz3xfxruteb3oqvng2isup6dq2md2u", + "time": 1710044316 + } + ], + "validationError": false + }, + { + "dpid": "191", + "owner": "0x371e269bff1aaA342b43b74Cf1Ad9789BaF183F7", + "versions": [ + { + "cid": "bafkreif7hsizhhb3pe5onhq7lnteu65c4wjdlhlh2yhokzsssnjiqhbizy", + "time": 1710848280 + }, + { + "cid": "bafkreif7hsizhhb3pe5onhq7lnteu65c4wjdlhlh2yhokzsssnjiqhbizy", + "time": 1710848496 + } + ], + "validationError": false + }, + { + "dpid": "192", + "owner": "0x371e269bff1aaA342b43b74Cf1Ad9789BaF183F7", + "versions": [ + { + "cid": "bafkreifup6tri42y77u4cyu5dtceve4hbesvkfhwod6cnlwnworm5kg5jy", + "time": 1710934908 + } + ], + "validationError": false + }, + { + "dpid": "193", + "owner": "0xec29aCa1a8740B8C5e2e06EBB52290700B9a2c40", + "versions": [ + { + "cid": "bafkreibs5jouyrflaifdy5h46qcao4ifl6k2uxkkdbjjhztowrzrdi7uey", + "time": 1711110348 + } + ], + "validationError": false + }, + { + "dpid": "194", + "owner": "0xec29aCa1a8740B8C5e2e06EBB52290700B9a2c40", + "versions": [ + { + "cid": "bafkreie4ql2xrlaaa3gydydecs62q6llw6ph3nql4wtv4vrvk7qlry5mii", + "time": 1711112832 + }, + { + "cid": "bafkreie4ql2xrlaaa3gydydecs62q6llw6ph3nql4wtv4vrvk7qlry5mii", + "time": 1711112916 + }, + { + "cid": "bafkreie4ql2xrlaaa3gydydecs62q6llw6ph3nql4wtv4vrvk7qlry5mii", + "time": 1711112964 + }, + { + "cid": "bafkreie4ql2xrlaaa3gydydecs62q6llw6ph3nql4wtv4vrvk7qlry5mii", + "time": 1711113060 + } + ], + "validationError": false + }, + { + "dpid": "195", + "owner": "0x4d0EC1B776aE7d57AFa42294cd6F5fa8Ab659819", + "versions": [ + { + "cid": "bafkreigl33hhuzyxtipdx26wsu4u775m47ceu7aryim3dbkquzxdzxw2cm", + "time": 1711250184 + } + ], + "validationError": false + }, + { + "dpid": "196", + "owner": "0x4d0EC1B776aE7d57AFa42294cd6F5fa8Ab659819", + "versions": [ + { + "cid": "bafkreicrbew4z2xa5msag2xqluych2cqvu4q37if7c4myrlgrso7clyr5m", + "time": 1711283700 + } + ], + "validationError": false + }, + { + "dpid": "197", + "owner": "0x711E9b9e8aD75CBD3AC024a8e4Aeeff59AfBae6c", + "versions": [ + { + "cid": "bafkreihzdyg7sncus6iiyywrmq3ieg6jpanwhopp3nermvdbj6twldqz4a", + "time": 1711484460 + } + ], + "validationError": false + }, + { + "dpid": "198", + "owner": "0xDAF8752DDcCE8a6B709aa271e7Efc60F75CDDF64", + "versions": [ + { + "cid": "bafkreifnbtsbubgr4igy3d2bdfm3t7wglonaefcpb6hltgx5ddemoirxbq", + "time": 1711485360 + } + ], + "validationError": false + }, + { + "dpid": "199", + "owner": "0xE713c665AC962155Ce2230b67034FBbc68Aa001E", + "versions": [ + { + "cid": "bafkreidrgw7m3dqhrhtkv3oof2tbuyaspmo3j7mfbyt4mcoiwsfzrelntm", + "time": 1712586828 + }, + { + "cid": "bafkreie6idsoipa3agkyg3widjx2qkqhyqesw7a4inbtf3v5bjwqmgvbu4", + "time": 1712746296 + }, + { + "cid": "bafkreifxbvttafs77huxssiyh7cia2aeds44qn7u3i6mo37rv5ok4n3yx4", + "time": 1712849196 + } + ], + "validationError": false + }, + { + "dpid": "200", + "owner": "0xb7633a1C95CDeFf14Fe90A18C61eA2EeA56ADd6F", + "versions": [ + { + "cid": "bafkreibr74kptq3taaq6vkk5ncliqjlaxfudeteoapwfj5dbk7lvabpa7a", + "time": 1712589912 + }, + { + "cid": "bafkreiehg2co367mlvhwga322q27m6k6ed3cll3jfhbeotrjr5uji4vuvy", + "time": 1712590308 + } + ], + "validationError": false + }, + { + "dpid": "201", + "owner": "0xbC4f75a4579c55B3b347C316159e03Ad9A233346", + "versions": [ + { + "cid": "bafkreigaex4kn6t5jtwjvfg6fhvu5ernugv4c2oyijj5c6sitlp7feyz4i", + "time": 1712699136 + }, + { + "cid": "bafkreibbutjlx6mftck5cdrghtnec7pupin5tmocw3jjnltk5b6ymepreu", + "time": 1712758008 + }, + { + "cid": "bafkreiasprpssrqrmt6csyxvp6h2hosczpnuhy5yet3ebdmp44nwqmnnxa", + "time": 1712910312 + }, + { + "cid": "bafkreiaml7ltpqcdawuri4pgze6lwst74dlwkkrxvu7ycxwcmucm54pzw4", + "time": 1712924748 + }, + { + "cid": "bafkreie44bdq6au5k544axgyh3t5u557sgojmk77jo6iebd2nuxdoboale", + "time": 1713181740 + }, + { + "cid": "bafkreifz6sboaziz6ozlws755w4xfa3agxerpcqfz2x3tyzpardhte57lu", + "time": 1713202788 + }, + { + "cid": "bafkreieebhdtnluia3gdhpi7cm3gskmnytq2vfmgi6mc7hkv3kqakcjqku", + "time": 1713210492 + }, + { + "cid": "bafkreicazrs2upqf67gb5z57oyoqd5p2ffsn3w4m4mpib5ttk4skwsoha4", + "time": 1713820044 + }, + { + "cid": "bafkreif33f5fja4xlt5hfng7au7u56pqxmhq7cwbsqqbo74kvh4dfmzt3a", + "time": 1713876336 + }, + { + "cid": "bafkreiffrskcqxf6sxlgi4vyfc6i7ppvsqd6fak5fr5azzxwurobetsvtm", + "time": 1713910788 + }, + { + "cid": "bafkreiffrskcqxf6sxlgi4vyfc6i7ppvsqd6fak5fr5azzxwurobetsvtm", + "time": 1713912876 + }, + { + "cid": "bafkreidymyibcfrjg6gjfdwdrsfxt2veregxrbxeilcqwawz5jstr2wgje", + "time": 1713966252 + }, + { + "cid": "bafkreiczragradkmshlydspr2hbkuj2ze5jptfrvh3ahygx2fvwxmx3eia", + "time": 1714743048 + }, + { + "cid": "bafkreicwl624bosttcswwvtkyisg2uqs2c5n65rsakaxa4c56xlxqwbnc4", + "time": 1715089932 + }, + { + "cid": "bafkreibomeyu2ha74ghyeargxgmne3zccrq3laf2hl5moilp62u5imaktq", + "time": 1715093316 + } + ], + "validationError": false + }, + { + "dpid": "202", + "owner": "0x371e269bff1aaA342b43b74Cf1Ad9789BaF183F7", + "versions": [ + { + "cid": "bafkreiblksmeh2h2rukdd3yyw2qpm2fspl233fccd3dmnjycukacslxtlu", + "time": 1712828544 + } + ], + "validationError": false + }, + { + "dpid": "203", + "owner": "0xbC4f75a4579c55B3b347C316159e03Ad9A233346", + "versions": [ + { + "cid": "bafkreieyuphulyypkgqyrenp5bsa4fmhdyjm6sxupuazdzdjr7bck3b6t4", + "time": 1712905908 + } + ], + "validationError": false + }, + { + "dpid": "204", + "owner": "0x29E9454e1Ee1bAf582403E1Dd3352134b044d6c6", + "versions": [ + { + "cid": "bafkreia3hv332uc5hjtjufiaptgqccnirp6glgqlp3kkmqqxzckk2wtque", + "time": 1714895436 + }, + { + "cid": "bafkreia3hv332uc5hjtjufiaptgqccnirp6glgqlp3kkmqqxzckk2wtque", + "time": 1714899456 + }, + { + "cid": "bafkreicedcwhhshszz4yorw4dsc67juu4eywrkfr2viacv3awmcvt7xroi", + "time": 1714902324 + } + ], + "validationError": false + }, + { + "dpid": "205", + "owner": "0x5249a44B2abEa543b2C441AC4964A08deB3Ed3CB", + "versions": [ + { + "cid": "bafkreihjkupfxvnrf5rgtwrrwacpatea6p6rfkpptk7tbyqug2yey56vmm", + "time": 1714902900 + }, + { + "cid": "bafkreifj7ps2uj2ovgbdx73j2rjrdgbsv5v52vsqbku73jk57mfo36e4ea", + "time": 1715097528 + } + ], + "validationError": false + }, + { + "dpid": "206", + "owner": "0x42d4fF8298dfcDCbb70823B146D0a1a3AF128a45", + "versions": [ + { + "cid": "bafkreibwzk6k24vak2utess6b4g3ymvoduf2wmmjq5ckp74zffetkvtp7y", + "time": 1715105532 + } + ], + "validationError": false + }, + { + "dpid": "207", + "owner": "0x29E9454e1Ee1bAf582403E1Dd3352134b044d6c6", + "versions": [ + { + "cid": "bafkreifsokpngt7o5nnf3svrjwq52a4jfmpsbo5dxrtfu7gxutn5b35zdq", + "time": 1715324136 + }, + { + "cid": "bafkreief5hvxfazsnkfzeuebbbyrqgrncfvzs62ixodku5bd2es7dxafmy", + "time": 1717411476 + } + ], + "validationError": false + }, + { + "dpid": "208", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreiecniqyzhz3ydgr6qalq2v64cptmc75ziriagcqumrg5mmldqs6ui", + "time": 1715706588 + } + ], + "validationError": false + }, + { + "dpid": "209", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreibcnzl5mhvil6ossyaldtmhvci3pgrop34rodde6nsqo4seymk35u", + "time": 1715754924 + } + ], + "validationError": false + }, + { + "dpid": "210", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreice6ojx5rphjrv3ghcwpmyceb4ftvogpjgueis7oysx4iwofux7tq", + "time": 1715756148 + } + ], + "validationError": false + }, + { + "dpid": "211", + "owner": "0xE713c665AC962155Ce2230b67034FBbc68Aa001E", + "versions": [ + { + "cid": "bafkreifxkw7fxmqs73xjkvpqib25ogct6sh7j5ult7ouemn27eyus6vteq", + "time": 1715758284 + } + ], + "validationError": false + }, + { + "dpid": "212", + "owner": "0xE713c665AC962155Ce2230b67034FBbc68Aa001E", + "versions": [ + { + "cid": "bafkreibd6z4ez67iorgtngwjgyzunrfafqp6ckd4rzxqcdkldsynzircbq", + "time": 1715758332 + } + ], + "validationError": false + }, + { + "dpid": "213", + "owner": "0xE713c665AC962155Ce2230b67034FBbc68Aa001E", + "versions": [ + { + "cid": "bafkreiftabtiwceukykjj7djbll6o7vj2b5nqljq2ayqos7a4q5bfj26qe", + "time": 1715759052 + } + ], + "validationError": false + }, + { + "dpid": "214", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreib4lne5chotkvctuooguqtknxwcu62tcg2f3czrhekq55yopr326y", + "time": 1715759664 + } + ], + "validationError": false + }, + { + "dpid": "215", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreidlca6x7or4cu26j42ujpauito7lu36sgrnkzikwtbblhxxj7ou5q", + "time": 1715783532 + } + ], + "validationError": false + }, + { + "dpid": "216", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreidxpaqx4emlzuyny7nwptse7v43fnldv6scxwerzf52ifwtj2zpmq", + "time": 1715846040 + }, + { + "cid": "bafkreidxpaqx4emlzuyny7nwptse7v43fnldv6scxwerzf52ifwtj2zpmq", + "time": 1715846232 + } + ], + "validationError": false + }, + { + "dpid": "217", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreielmjyyh4huzlvdfq5zpkq4yfynqkir7nzyw2hraph34z6pk6vpta", + "time": 1715852172 + } + ], + "validationError": false + }, + { + "dpid": "218", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreial2hxxfcpzkm474ommsvbywgkoz7giyai5y2vnzt2yuswt3qwvhe", + "time": 1715852724 + } + ], + "validationError": false + }, + { + "dpid": "219", + "owner": "0x42d4fF8298dfcDCbb70823B146D0a1a3AF128a45", + "versions": [ + { + "cid": "bafkreih5rxnqa74dgehy5vlzf2c3bjpdd4d37wjsmd6umklvtpravrymii", + "time": 1715852904 + }, + { + "cid": "bafkreif7bdndzubravkpbgllcz2uejzxvuagbrxw4kg3afvzqcz5u2epji", + "time": 1715853012 + } + ], + "validationError": false + }, + { + "dpid": "220", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreihdis2gtow2vyjw3lfrrk75nwhimvr3mol5tw2yg5m6yb4qkfzusm", + "time": 1715853288 + } + ], + "validationError": false + }, + { + "dpid": "221", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreieykztli6himlvsp66y4eq5e6olhmd57mq3ff7q5lpkl3h57gdzhy", + "time": 1715854884 + } + ], + "validationError": false + }, + { + "dpid": "222", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreigduiq7h6qo3eszrpbgfaxllcboxxa7isr35ajf3qkax2522stlhu", + "time": 1715857896 + } + ], + "validationError": false + }, + { + "dpid": "223", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreifz5uvrar2vdxtcmd2sh3xhibyansyg2joqmnclce6spwopswo7qm", + "time": 1715858892 + } + ], + "validationError": false + }, + { + "dpid": "224", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreihjdwdspwjdptweikwbzpzthv2b3vkaablm6yrgzg2syf34ay5zo4", + "time": 1715858988 + } + ], + "validationError": false + }, + { + "dpid": "225", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreibd4v3nmp6n652mrgmuha6q65cul6pq625gzirsrka4wiftdrbxkm", + "time": 1715859360 + } + ], + "validationError": false + }, + { + "dpid": "226", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreicikabkude4odfkc3h55d7tbma527qzcbq5f7urusu2f65jy2qdr4", + "time": 1715862000 + } + ], + "validationError": false + }, + { + "dpid": "227", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreickxvmqpwkg3hoiqaibcsz5mxgcquhoivflzgqloupgfvgxiahgmm", + "time": 1715862264 + } + ], + "validationError": false + }, + { + "dpid": "228", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreigpxc4535atofw53qhlwy5ljmku7cgvi64yzohjaqllh63e75iigm", + "time": 1715862396 + } + ], + "validationError": false + }, + { + "dpid": "229", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreibyqg4efuc4je3szq6augfzrlknk4kyo56jvmtlv6v3u34olfjw5q", + "time": 1715862828 + } + ], + "validationError": false + }, + { + "dpid": "230", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreice2sc42ahkjmt2fdkgrdgbpr2jbb462swclyamdykpc6guyigg3e", + "time": 1715863632 + } + ], + "validationError": false + }, + { + "dpid": "231", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreihdynlkgw62oeknjc6cpbibmk6hmql46haes3sw77twqxzxj4p7dy", + "time": 1715863932 + } + ], + "validationError": false + }, + { + "dpid": "232", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreidbb6rj2zcaufmhdqf2ioqa4ub573fsjwve3xsqtihz4t2mu7mfvm", + "time": 1715864112 + } + ], + "validationError": false + }, + { + "dpid": "233", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreih3wosdxfpkdajepb6fr6mpnbzotvx3757aapwh5jc4uj5ki4nsb4", + "time": 1715864796 + } + ], + "validationError": false + }, + { + "dpid": "234", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreieaqwjyk5oueqxkhoqbmh4priqdl2d5htgyp7euofym22t2vup2n4", + "time": 1715864856 + } + ], + "validationError": false + }, + { + "dpid": "235", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreicegqhkh77pjlaffif4jptccfjcug4x2v6uzkuhgzk7mvkp3h3pje", + "time": 1715864988 + } + ], + "validationError": false + }, + { + "dpid": "236", + "owner": "0x371e269bff1aaA342b43b74Cf1Ad9789BaF183F7", + "versions": [ + { + "cid": "bafkreiaovnmdbwprrbe2ol5wmsiohpepr74eobdzp7mnhmolazca6rmk3u", + "time": 1715945640 + } + ], + "validationError": false + }, + { + "dpid": "237", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreia5h5rgnj3tckolwznad5ufivrdkrfcwwb7ybvhauqy3tpvsanxbe", + "time": 1715966676 + } + ], + "validationError": false + }, + { + "dpid": "238", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreihna43pr26bwxltihgzpby4pfamdojeyuusiikodzsfx2cx4nizwi", + "time": 1716044616 + }, + { + "cid": "bafkreiawwiamv3sm7ujwtusakl33ncwprbmvgqygsugcjc63e57o4qedrm", + "time": 1716195456 + }, + { + "cid": "bafkreifsn65szz2c7oigkpaj7zf5vveme2bdvyimhikvcthzpfamx4amqa", + "time": 1716195624 + }, + { + "cid": "bafkreiffpqp5eqhtb5twcggyfdwxd6zciqqrm43356m5g64tkozw6ox2um", + "time": 1716196968 + }, + { + "cid": "bafkreibhvf342535vnaxqpjvapnfvuh563g6fqq26ifmmks3edyig2bqje", + "time": 1716197688 + } + ], + "validationError": false + }, + { + "dpid": "239", + "owner": "0xbC4f75a4579c55B3b347C316159e03Ad9A233346", + "versions": [ + { + "cid": "bafkreida4e3jtx44nqujveh7qstktsiwvmgvqvdrxfp6oxwtgtj3yt7rtq", + "time": 1716299616 + } + ], + "validationError": false + }, + { + "dpid": "240", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreicc35sby7tw62yixogr7cdyb74ogud2oks7ucxoqm2dxl2ns7iqxe", + "time": 1716455376 + }, + { + "cid": "bafkreih4fwgcdcuanlvqrfe23gtssi2ry5qn5aiartyyxnrgwie47vogjq", + "time": 1716456924 + }, + { + "cid": "bafkreibmiu4or57a3zt2oqwpyo55sxilbohbekoio7ar6xctre4rplmctm", + "time": 1716457200 + }, + { + "cid": "bafkreig2frbnikhvo7ybhocvvtcxemjqjkzausxmea75mj4yes4vrh3ly4", + "time": 1716457332 + }, + { + "cid": "bafkreibrhymhxsjll5amkbh4xqpi3ndr5bp5lbs6vs5x43aqzdynbzrlxa", + "time": 1716559284 + }, + { + "cid": "bafkreidwe7ueatapvutqf34m6sdvqt2deyhmzgnkme45filbvjxcqhnhya", + "time": 1717161096 + }, + { + "cid": "bafkreiaipcdk567t72ftbuvqeuyec64zw57ed4ttaftjazoy3how25y254", + "time": 1717161504 + }, + { + "cid": "bafkreiglntmzkq4nhkaqjkukhdyngilz33lmqmlclyeich6kbx6h5cayau", + "time": 1717393608 + } + ], + "validationError": false + }, + { + "dpid": "241", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreici76b6bx7smkkihhzjpv7hj26q4uowye5vnmia36gn6lkaa65f6a", + "time": 1716458616 + } + ], + "validationError": false + }, + { + "dpid": "242", + "owner": "0x29E9454e1Ee1bAf582403E1Dd3352134b044d6c6", + "versions": [ + { + "cid": "bafkreibzcu3iwi7buqwy2ibujh2sbe4gmbyhycil7w4xeuvldsa2mrbypy", + "time": 1716464784 + } + ], + "validationError": false + }, + { + "dpid": "243", + "owner": "0x008292E57A2d9B34525d82876068652e639e61D8", + "versions": [ + { + "cid": "bafkreiaxbwjw2cp7mvfaul4xlxkguafmfkxxhym7ik5bty7dfehxff3tgu", + "time": 1716551616 + } + ], + "validationError": false + }, + { + "dpid": "244", + "owner": "0xb4096E016F162d10EfC8C20F8Db22a54D80935c8", + "versions": [ + { + "cid": "bafkreiflayannh3vsjxn2khne5gjtupt3mtso4rd6x4dnmfh3rhxzkvhfm", + "time": 1717158900 + } + ], + "validationError": false + }, + { + "dpid": "245", + "owner": "0x371e269bff1aaA342b43b74Cf1Ad9789BaF183F7", + "versions": [ + { + "cid": "bafkreic56m4scp5t7fdb2zajue3tupjevoxlwaly2skqbdbncy5zbydike", + "time": 1717159332 + } + ], + "validationError": false + }, + { + "dpid": "246", + "owner": "0x42d4fF8298dfcDCbb70823B146D0a1a3AF128a45", + "versions": [ + { + "cid": "bafkreib23oradn74sxmdji6ofw4iffliheytyq7kq3ge3bnz2tooz764cu", + "time": 1717160400 + } + ], + "validationError": false + } + ] +} \ No newline at end of file diff --git a/desci-contracts/package.json b/desci-contracts/package.json index 38beb3db..ed04dd72 100644 --- a/desci-contracts/package.json +++ b/desci-contracts/package.json @@ -1,7 +1,7 @@ { "name": "@desci-labs/desci-contracts", "description": "Smart contracts implementing DeSci Nodes on-chain state and logic", - "version": "0.2.5-rc4", + "version": "0.2.5-rc5", "license": "MIT", "scripts": { "test": "hardhat clean && hardhat test", diff --git a/desci-contracts/scripts/migrateToAliasRegistry.mjs b/desci-contracts/scripts/migrateToAliasRegistry.mjs index e650b446..7c4008c0 100644 --- a/desci-contracts/scripts/migrateToAliasRegistry.mjs +++ b/desci-contracts/scripts/migrateToAliasRegistry.mjs @@ -119,7 +119,7 @@ for (const [ dpid, entry ] of importEntries) { validationError = true; }; }; - results.dpids.push({ dpid, owner: imported.owner, versions: imported.versions, importError: validationError }); + results.dpids.push({ dpid, owner: imported.owner, versions: imported.versions, validationError }); }; const failures = results.dpids.filter(r => r.validationError); @@ -138,6 +138,6 @@ const duration = Math.ceil((Date.now() - startTime) / 1000); console.log(`🏁 migration done in ${duration}s for a total of ${totalGas} gas`); const dateString = new Date().toUTCString().replaceAll(" ", "_"); -const logFilePath = `migration-data/aliasRegistry_${dateString}.json`; +const logFilePath = `migration-data/aliasRegistry_${ENV}_${dateString}.json`; writeFileSync(logFilePath, JSON.stringify(results, undefined, 2)); console.log(`📝 migration data written to ${logFilePath}`); diff --git a/desci-contracts/scripts/syncAliasRegistryMigration.mjs b/desci-contracts/scripts/syncAliasRegistryMigration.mjs index af523065..637b3671 100644 --- a/desci-contracts/scripts/syncAliasRegistryMigration.mjs +++ b/desci-contracts/scripts/syncAliasRegistryMigration.mjs @@ -16,6 +16,7 @@ * Required arguments (env variables): * 1. REGISTRY_ADDRESS - Address of existing alias registry (proxy) contract * 2. ENV - Environment to sync legacy entires from ("dev" or "prod") + * 3. PRIVATE_KEY - Admin pkey, to allow calling onlyOwner methods */ import hardhat from "hardhat"; const { ethers, hardhatArguments } = hardhat; @@ -89,12 +90,24 @@ for (const [ dpid, entry ] of importEntries) { versions: fromContract[1].map(([cid, time]) => ({cid, time: ethers.BigNumber.from(time).toNumber() })), }; - console.log(`🔎 Verifying dPID ${dpid}:`); - const originalDpid = allDpids.find(e => e.dpid === dpid); const originalOwner = originalDpid.researchObject.owner; const originalVersions = originalDpid.researchObject.versions; + if (imported.versions.length < originalVersions.length) { + console.log(`👷 Found new versions of dPID ${dpid}, updating import...`); + const tx = await registry.importLegacyDpid(dpid, entry); + const receipt = await tx.wait(); + totalGas += ethers.BigNumber.from(receipt.gasUsed).toNumber(); + + // Refresh information from contract after updating + const refreshedFromContract = await registry.legacyLookup(dpid); + imported.owner = refreshedFromContract[0]; + imported.versions = refreshedFromContract[1].map(([cid, time]) => ({cid, time: ethers.BigNumber.from(time).toNumber() })); + }; + + console.log(`🔎 Verifying dPID ${dpid}:`); + let validationError = false; const ownerCorrect = originalOwner === imported.owner.toLowerCase(); @@ -103,27 +116,33 @@ for (const [ dpid, entry ] of importEntries) { console.log(` - History:`) for (let i = 0; i < originalVersions.length; i++) { - console.log(` - v${i}:`) - const cidCorrect = originalVersions[i].cid === imported.versions[i].cid; - const timeCorrect = originalVersions[i].time === imported.versions[i].time; + if (!imported.versions[i]) { + console.log(` - v${i}: (missing in imported history)`); + } else { + console.log(` - v${i}:`); + }; + + const cidCorrect = originalVersions[i].cid === imported.versions[i]?.cid; + const timeCorrect = originalVersions[i].time === imported.versions[i]?.time; console.log(` - cid: ${cidCorrect ? "✅" : "❌"} (${originalVersions[i].cid})`); console.log(` - time: ${timeCorrect ? "✅" : "❌"} (${originalVersions[i].time})`); + if (!(cidCorrect && timeCorrect)) { validationError = true; }; }; - results.push({ dpid, owner: imported.owner, versions: imported.versions, importError: validationError }); + results.push({ dpid, owner: imported.owner, versions: imported.versions, validationError }); }; const failures = results.filter(r => r.validationError); -console.log(`🚦 dPIDs which failed validation (manually import to overwrite): ${JSON.stringify(failures)}`); +console.log(`🚦 dPIDs which failed validation (manually import to overwrite): ${JSON.stringify(failures, undefined, 2)}`); const duration = Math.ceil((Date.now() - startTime) / 1000); console.log(`🏁 sync done in ${duration}s for a total of ${totalGas} gas`); const dateString = new Date().toUTCString().replaceAll(" ", "_"); -const logFilePath = `migration-data/aliasRegistrySync_${dateString}.json`; +const logFilePath = `migration-data/aliasRegistrySync_${ENV}_${dateString}.json`; writeFileSync(logFilePath, JSON.stringify(results, undefined, 2)); console.log(`📝 migration data written to ${logFilePath}`); From a962f6c116f7dcf352551725b4c8e6418fdd19ab Mon Sep 17 00:00:00 2001 From: m0ar Date: Sat, 1 Jun 2024 14:43:32 +0200 Subject: [PATCH 125/278] dockerfile: slim down build closure --- .dockerignore | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.dockerignore b/.dockerignore index 1e31546e..29465bbd 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,11 +1,12 @@ +**/node_modules +**/dist +**/.vscode +desci-server/log config dist -./node_modules .git .env desci-art-viewer desci-dapp -desci-server/node_modules local-data database -desci-server/log \ No newline at end of file From 9196831f98285150023dca5ba7ae2b61ea292c01 Mon Sep 17 00:00:00 2001 From: m0ar Date: Tue, 4 Jun 2024 16:35:28 +0200 Subject: [PATCH 126/278] [wip] separate publish functionality for codex-first --- nodes-lib/package-lock.json | 18 ++--- nodes-lib/package.json | 4 +- nodes-lib/src/api.ts | 115 +++++++++++++++++++++++++++++-- nodes-lib/src/chain.ts | 76 ++++++++++++++++---- nodes-lib/src/codex.ts | 37 ++++++++-- nodes-lib/src/config/chain.ts | 60 ++++++++++++++-- nodes-lib/src/config/index.ts | 19 +++-- nodes-lib/src/publish.ts | 44 +++++++++++- nodes-lib/src/util/converting.ts | 24 +++++-- nodes-lib/src/util/signing.ts | 7 +- 10 files changed, 347 insertions(+), 57 deletions(-) diff --git a/nodes-lib/package-lock.json b/nodes-lib/package-lock.json index f45c6184..38a0798b 100644 --- a/nodes-lib/package-lock.json +++ b/nodes-lib/package-lock.json @@ -1,16 +1,16 @@ { "name": "@desci-labs/nodes-lib", - "version": "0.0.5-rc9", + "version": "0.0.7-rc0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@desci-labs/nodes-lib", - "version": "0.0.5-rc9", + "version": "0.0.7-rc0", "license": "MIT", "dependencies": { "@desci-labs/desci-codex-lib": "^1.1.7", - "@desci-labs/desci-contracts": "^0.2.3-rc3", + "@desci-labs/desci-contracts": "^0.2.5-rc1", "@desci-labs/desci-models": "^0.2.3-rc1", "@didtools/cacao": "^3.0.1", "@didtools/pkh-ethereum": "^0.5.0", @@ -1010,9 +1010,9 @@ } }, "node_modules/@desci-labs/desci-contracts": { - "version": "0.2.3-rc3", - "resolved": "https://registry.npmjs.org/@desci-labs/desci-contracts/-/desci-contracts-0.2.3-rc3.tgz", - "integrity": "sha512-3OmnrMa+L9qK/iNkuPS2HS/ihsNFKly3X8vjQK0cHhTH2qh6/FBbcIK77uOF9yi0ldOm+VfPSL2p7s8BC+bKow==" + "version": "0.2.5-rc1", + "resolved": "https://registry.npmjs.org/@desci-labs/desci-contracts/-/desci-contracts-0.2.5-rc1.tgz", + "integrity": "sha512-wA4zDRp3GT3ZKo0/qFT2fKuLElQFXgycBnuaa2RPCOEfxQXFOqDYOyaqnhbklnutjit1MjwitiO6E6SFWzk6zg==" }, "node_modules/@desci-labs/desci-models": { "version": "0.2.3-rc1", @@ -10840,9 +10840,9 @@ } }, "@desci-labs/desci-contracts": { - "version": "0.2.3-rc3", - "resolved": "https://registry.npmjs.org/@desci-labs/desci-contracts/-/desci-contracts-0.2.3-rc3.tgz", - "integrity": "sha512-3OmnrMa+L9qK/iNkuPS2HS/ihsNFKly3X8vjQK0cHhTH2qh6/FBbcIK77uOF9yi0ldOm+VfPSL2p7s8BC+bKow==" + "version": "0.2.5-rc1", + "resolved": "https://registry.npmjs.org/@desci-labs/desci-contracts/-/desci-contracts-0.2.5-rc1.tgz", + "integrity": "sha512-wA4zDRp3GT3ZKo0/qFT2fKuLElQFXgycBnuaa2RPCOEfxQXFOqDYOyaqnhbklnutjit1MjwitiO6E6SFWzk6zg==" }, "@desci-labs/desci-models": { "version": "0.2.3-rc1", diff --git a/nodes-lib/package.json b/nodes-lib/package.json index 4964b363..1d4017f2 100644 --- a/nodes-lib/package.json +++ b/nodes-lib/package.json @@ -1,6 +1,6 @@ { "name": "@desci-labs/nodes-lib", - "version": "0.0.6", + "version": "0.0.7-rc0", "homepage": "https://github.com/desci-labs/nodes#readme", "description": "Stand-alone client library for interacting with desci-server", "repository": { @@ -27,7 +27,7 @@ }, "dependencies": { "@desci-labs/desci-codex-lib": "^1.1.7", - "@desci-labs/desci-contracts": "^0.2.3-rc3", + "@desci-labs/desci-contracts": "^0.2.5-rc5", "@desci-labs/desci-models": "^0.2.3-rc1", "@didtools/cacao": "^3.0.1", "@didtools/pkh-ethereum": "^0.5.0", diff --git a/nodes-lib/src/api.ts b/nodes-lib/src/api.ts index a8965a2e..188f9c76 100644 --- a/nodes-lib/src/api.ts +++ b/nodes-lib/src/api.ts @@ -22,13 +22,15 @@ import { import FormData from "form-data"; import { createReadStream } from "fs"; import type { NodeIDs } from "@desci-labs/desci-codex-lib"; -import { publish } from "./publish.js"; +import { legacyPublish, publish } from "./publish.js"; import type { ResearchObjectDocument } from "./automerge.js"; import { randomUUID } from "crypto"; import { getNodesLibInternalConfig } from "./config/index.js"; import { makeRequest } from "./routes.js"; import { Signer } from "ethers"; import { type DID } from "dids"; +import { getFullState } from "./codex.js"; +import { convertUUIDToDecimal } from "./util/converting.js"; export const ENDPOINTS = { deleteData: { @@ -128,6 +130,12 @@ export const ENDPOINTS = { _payloadT: {}, _responseT: {}, }, + createDpid: { + method: "post", + route: `/v1/nodes/createDpid`, + _payloadT: <{ uuid: string }>{}, + _responseT: <{ dpid: number }>{}, + }, /** Append `/[uuid] `*/ dpidHistory: { method: "get", @@ -326,6 +334,77 @@ export type PublishResponse = { dpidTxId?: string }; +/** + * Publish a node, meaning compile the state of the drive into an actual + * IPLD DAG, make the IPFS CID's public, publish the references to Codex + * and create a dPID alias for it. + * + * @param uuid - UUID of the node to publish + * @param didOrSigner - authenticated did-session DID, or a generic signer +*/ +export const publishNode = async ( + uuid: string, + didOrSigner: DID | Signer, +): Promise => { + const publishResult = await publish(uuid, didOrSigner); + const pubParams: PublishParams = { + uuid, + cid: publishResult.cid, + manifest: publishResult.manifest, + ceramicStream: publishResult.ceramicIDs.streamID, + commitId: publishResult.ceramicIDs.commitID, + // required in DB & this string is used to detect non-tx's in publish worker + transactionId: "ceramic", + }; + + try { + await makeRequest(ENDPOINTS.publish, getHeaders(), pubParams); + } catch (e) { + console.log(`Publish successful, but backend update failed for node ${uuid}`); + throw e; + }; + + let dpid; + try { + dpid = await createDpid(uuid); + await changeManifest( + uuid, + [{ + type: "Publish Dpid", + dpid: { prefix: "", id: dpid.toString() } + }], + ); + } catch (e) { + console.log(`Failed to create dPID alias for node ${uuid}...`); + }; + + return { + ceramicIDs: publishResult.ceramicIDs, + updatedManifest: publishResult.manifest, + updatedManifestCid: publishResult.cid, + }; +}; + +/** + * Create a new dPID in the alias registry. Only possible to do once per node. + * + * @param uuid - UUID of the node to mint a dPID + * @throws on dPID minting failure +*/ +export const createDpid = async ( + uuid: string, +): Promise => { + let dpid: number; + try { + const res = await makeRequest(ENDPOINTS.createDpid, getHeaders(), { uuid }); + dpid = res.dpid; + } catch (e) { + console.log(`Couldn't create dPID alias for node ${uuid}`) + throw e; + }; + return dpid; +}; + /** * Publish a draft node, meaning to compile the state of the drive into an * actual IPLD DAG, make the IPFS CIDs public, and register the node on @@ -335,13 +414,14 @@ export type PublishResponse = { * @param signer - Signer to use for publish, if not set with env * @throws (@link WrongOwnerError) if signer address isn't research object token owner * @throws (@link DpidPublishError) if dPID couldnt be registered or updated + * @depreated use publishNode instead, as this function uses the old on-chain registry */ export const publishDraftNode = async ( uuid: string, signer: Signer, did?: DID, ): Promise => { - const publishResult = await publish(uuid, signer, did); + const publishResult = await legacyPublish(uuid, signer, did); const pubParams: PublishParams = { uuid, @@ -656,8 +736,6 @@ export const addExternalCid = async ( export type IndexedNodeVersion = { /** Manifest CID in EVM format */ cid: string; - /** Transaction ID of the update event */ - id: string; /** Epoch timestamp of the update*/ time: string; }; @@ -676,8 +754,35 @@ export type IndexedNode = { versions: IndexedNodeVersion[]; }; +export const getPublishHistory = async ( + uuid: string, +): Promise => { + const { ceramicStream,} = await getDraftNode(uuid); + + if (!ceramicStream) { + return await getDpidHistory(uuid); + }; + + const resolved = await getFullState(ceramicStream); + const versions = resolved.events.map(e => ({ + cid: e.cid.toString(), + time: e.timestamp?.toString() || "", // May happen if commit is not anchored + })); + + const indexedNode: IndexedNode = { + id: uuid, + id10: convertUUIDToDecimal(uuid), + owner: resolved.owner, + recentCid: resolved.manifest, + versions, + }; + + return indexedNode; +}; + /** - * The the dPID publish history for a node. + * Get the dPID publish history for a node. + * @deprecated use getPublishHistory */ export const getDpidHistory = async ( uuid: string, diff --git a/nodes-lib/src/chain.ts b/nodes-lib/src/chain.ts index 7d7f232d..35d0294e 100644 --- a/nodes-lib/src/chain.ts +++ b/nodes-lib/src/chain.ts @@ -1,20 +1,27 @@ -import { BigNumber, ContractReceipt, Signer } from "ethers"; +import { BigNumber, ContractReceipt, Signer, providers, utils } from "ethers"; import { convertUUIDToHex, convertCidTo0xHex} from "./util/converting.js"; import { changeManifest, prePublishDraftNode, type PrepublishResponse } from "./api.js" import { getNodesLibInternalConfig } from "./config/index.js"; -import { formatBytes32String } from "ethers/lib/utils.js"; import { DpidRegistrationError, DpidUpdateError, WrongOwnerError } from "./errors.js"; +import { StreamID } from "@desci-labs/desci-codex-lib/dist/streams.js"; +import { typechain as tc } from "@desci-labs/desci-contracts"; const LOG_CTX = "[nodes-lib::chain]" const DEFAULT_DPID_PREFIX_STRING = "beta"; -const DEFAULT_DPID_PREFIX = formatBytes32String(DEFAULT_DPID_PREFIX_STRING); +const DEFAULT_DPID_PREFIX = utils.formatBytes32String(DEFAULT_DPID_PREFIX_STRING); -const researchObjectContract = (signer: Signer) => - getNodesLibInternalConfig().chainConfig.researchObjectConnector(signer); +const researchObjectWriter = (signer: Signer) => + getNodesLibInternalConfig().legacyChainConfig.researchObjectConnector(signer); -const dpidRegistryContract = (signer: Signer) => - getNodesLibInternalConfig().chainConfig.dpidRegistryConnector(signer); +const dpidRegistryWriter = (signer: Signer) => + getNodesLibInternalConfig().legacyChainConfig.dpidRegistryConnector(signer); + +const dpidAliasRegistryWriter = (signer: Signer) => + getNodesLibInternalConfig().chainConfig.dpidAliasRegistryConnector(signer); + +const dpidAliasRegistryReader = (provider: providers.Provider) => + getNodesLibInternalConfig().chainConfig.dpidAliasRegistryConnector(provider); export type DpidPublishResult = { prepubResult: PrepublishResponse, @@ -26,6 +33,7 @@ export type DpidPublishResult = { * * @throws (@link WrongOwnerError) if signer address isn't token owner * @throws (@link DpidPublishError) if dPID couldnt be registered or updated + * @deprecated */ export const dpidPublish = async ( uuid: string, @@ -80,8 +88,42 @@ export const dpidPublish = async ( return { prepubResult, reciept }; }; +/** + * Mint a new ID for a stream in the new dPID alias registry. + * + * Note that the alias registry is immutable, so there is no + * risk involved with letting a third party mint a dPID alias + * for you. + * + * Instead of performing this action, you can use the corresponding + * API method and let the backend mint the ID for you. + */ +export const createDpidAlias = async ( + streamId: StreamID, + signer: Signer, +): Promise<{ dpid: number, receipt: ContractReceipt}> => { + const tx = await dpidAliasRegistryWriter(signer).mintDpid(streamId.toString()); + const receipt = await tx.wait(); + const [ dpid ] = receipt.events?.find(e => e.event === "DpidMinted")?.args!; + + return { dpid, receipt }; +}; + +/** + * Lookup the history of a legacy dPID in the new alias registry. + */ +export const lookupLegacyDpid = async ( + dpid: number +): Promise => { + const provider = new providers.JsonRpcProvider( + getNodesLibInternalConfig().chainConfig.rpcUrl + ); + return await dpidAliasRegistryReader(provider).legacyLookup(dpid); +}; + /** * Update an existing dPID with a new version of the manifest. + * @deprecated */ const updateExistingDpid = async ( uuid: string, @@ -91,7 +133,7 @@ const updateExistingDpid = async ( const cidBytes = convertCidTo0xHex(prepubManifestCid); const hexUuid = convertUUIDToHex(uuid); - const tx = await researchObjectContract(signer).updateMetadata(hexUuid, cidBytes); + const tx = await researchObjectWriter(signer).updateMetadata(hexUuid, cidBytes); return await tx.wait() }; @@ -99,13 +141,14 @@ const updateExistingDpid = async ( * Optimistically create a manifest with the next available dPID, * and try to register it as such. * @throws on dpid registration failure. + * @deprecated */ const registerNewDpid = async ( uuid: string, signer: Signer, ): Promise<{ reciept: ContractReceipt, prepubResult: PrepublishResponse}> => { const optimisticDpid = await getPreliminaryDpid(signer); - const regFee = await dpidRegistryContract(signer).getFee(); + const regFee = await dpidRegistryWriter(signer).getFee(); await changeManifest( uuid, @@ -123,7 +166,7 @@ const registerNewDpid = async ( const hexUuid = convertUUIDToHex(uuid); // Throws if the expected dPID isn't available - const tx = await researchObjectContract(signer).mintWithDpid( + const tx = await researchObjectWriter(signer).mintWithDpid( hexUuid, cidBytes, DEFAULT_DPID_PREFIX, @@ -145,23 +188,30 @@ const registerNewDpid = async ( /** * Get the next dPID up for minting, for creating an optimistic manifest. * @returns the next free dPID + * @deprecated */ const getPreliminaryDpid = async ( signer: Signer, ): Promise => { - const [nextFreeDpid, _] = await dpidRegistryContract(signer) + const [nextFreeDpid, _] = await dpidRegistryWriter(signer) .getOrganization(DEFAULT_DPID_PREFIX); return nextFreeDpid; }; +/** + * @deprecated + */ export const hasDpid = async ( uuid: string, signer: Signer, ): Promise => - await researchObjectContract(signer).exists(convertUUIDToHex(uuid)); + await researchObjectWriter(signer).exists(convertUUIDToHex(uuid)); +/** + * @deprecated + */ export const getResearchObjectOwner = async ( uuid: string, signer: Signer, ): Promise => - (await researchObjectContract(signer).ownerOf(convertUUIDToHex(uuid))).toLowerCase();; + (await researchObjectWriter(signer).ownerOf(convertUUIDToHex(uuid))).toLowerCase();; diff --git a/nodes-lib/src/codex.ts b/nodes-lib/src/codex.ts index 896c81ae..8e748641 100644 --- a/nodes-lib/src/codex.ts +++ b/nodes-lib/src/codex.ts @@ -2,7 +2,7 @@ import { createResearchObject, newComposeClient, updateResearchObject, - type ComposeClient, + ComposeClient, type NodeIDs, queryResearchObject, resolveHistory, @@ -141,16 +141,45 @@ const backfillNewStream = async ( return streamID; }; +/** + * Get full historical publish state of a research object. +*/ +export const getFullState = async ( + streamID: string, +) => { + const ceramic = newCeramicClient(getNodesLibInternalConfig().ceramicNodeUrl); + const compose = newComposeClient({ ceramic }); + const resolved = await queryResearchObject( + compose, + streamID, + "owner { id } manifest" + ) as unknown as { owner: { id: string }, manifest: string}; + + console.log(JSON.stringify(resolved)) + + if (!resolved) { + console.log("Failed to resolve research object:", { streamID }); + throw new Error("codex resolution failed"); + }; + + const events = await getCodexHistory(streamID); + return { + owner: resolved.owner, // explicitly selected in query + manifest: resolved.manifest, // explicitly selected in query + events, + }; +}; + /** * Get the state of a research object as published on Codex. */ -export const getPublishedFromCodex = async ( - id: string +export const getCurrentState = async ( + streamID: string ) => { const ceramic = newCeramicClient(getNodesLibInternalConfig().ceramicNodeUrl); const compose = newComposeClient({ ceramic }); - return await queryResearchObject(compose, id); + return await queryResearchObject(compose, streamID); }; /** diff --git a/nodes-lib/src/config/chain.ts b/nodes-lib/src/config/chain.ts index 9474268f..3f1c72b0 100644 --- a/nodes-lib/src/config/chain.ts +++ b/nodes-lib/src/config/chain.ts @@ -5,16 +5,19 @@ import { type NodesEnv } from "./index.js"; export type NodesContract = | tc.ResearchObject | tc.ResearchObjectV2 - | tc.DpidRegistry; + | tc.DpidRegistry + | tc.DpidAliasRegistry; export type ContractConnector = (signerOrProvider: Signer | providers.Provider) => T; export type ChainID = - | "1337" - | "11155111"; + | "1337" // local + | "11155111" // sepolia + | "11155420" // optimism sepolia + | "10"; // optimism mainnet -export type ChainConfig = { +export type LegacyChainConfig = { /** Decimal chain ID */ chainId: ChainID, /** RPC URL to use for communication */ @@ -25,7 +28,16 @@ export type ChainConfig = { dpidRegistryConnector: ContractConnector, }; -export const CHAIN_CONFIGS = { +export type ChainConfig = { + /** Decimal chain ID */ + chainId: ChainID, + /** RPC URL to use for communication */ + rpcUrl: string, + /** Given a signer or provider, create a contract instance */ + dpidAliasRegistryConnector: ContractConnector, +}; + +export const LEGACY_CHAIN_CONFIGS = { local: { chainId: "1337", rpcUrl: "http://localhost:8545", @@ -74,4 +86,40 @@ export const CHAIN_CONFIGS = { signerOrProvider ), }, -} as const satisfies { [Env in NodesEnv]: ChainConfig }; +} as const satisfies { [Env in NodesEnv]: LegacyChainConfig }; + +export const CHAIN_CONFIGS = { + local: { + chainId: "1337", + rpcUrl: "http://localhost:8545", + dpidAliasRegistryConnector: signerOrProvider => tc.DpidAliasRegistry__factory.connect( + contracts.localDpidAliasInfo.proxies.at(0)!.address, + signerOrProvider, + ), + }, + dev: { + chainId: "11155420", + rpcUrl: "https://reverse-proxy-dev.desci.com/rpc_opt_sepolia", + dpidAliasRegistryConnector: signerOrProvider => tc.DpidAliasRegistry__factory.connect( + contracts.devDpidAliasInfo.proxies.at(0)!.address, + signerOrProvider, + ), + }, + staging: { + chainId: "11155420", + rpcUrl: "https://reverse-proxy-staging.desci.com/rpc_opt_sepolia", + dpidAliasRegistryConnector: signerOrProvider => tc.DpidAliasRegistry__factory.connect( + contracts.devDpidAliasInfo.proxies.at(0)!.address, + signerOrProvider, + ), + }, + prod: { + chainId: "10", + rpcUrl: "https://reverse-proxy-prod.desci.com/rpc_opt_mainnet", + dpidAliasRegistryConnector: signerOrProvider => tc.DpidAliasRegistry__factory.connect( + "NOT_DEPLOYED",//contracts.prodDpidAliasInfo.proxies.at(0)!.address, + signerOrProvider, + ), + } + +} as const satisfies { [Env in NodesEnv]: ChainConfig}; diff --git a/nodes-lib/src/config/index.ts b/nodes-lib/src/config/index.ts index 5676d32f..39146759 100644 --- a/nodes-lib/src/config/index.ts +++ b/nodes-lib/src/config/index.ts @@ -1,5 +1,5 @@ import { getResources } from "@desci-labs/desci-codex-lib"; -import { CHAIN_CONFIGS, ChainConfig } from "./chain.js"; +import { CHAIN_CONFIGS, ChainConfig, LEGACY_CHAIN_CONFIGS, LegacyChainConfig } from "./chain.js"; export type NodesEnv = | "local" @@ -7,10 +7,11 @@ export type NodesEnv = | "staging" | "prod"; -export type Config = { +export type NodesLibConfig = { apiUrl: string, apiKey?: string, ceramicNodeUrl: string, + legacyChainConfig: LegacyChainConfig, chainConfig: ChainConfig, }; @@ -19,30 +20,34 @@ export const NODESLIB_CONFIGS = { apiUrl: "http://localhost:5420", apiKey: undefined, ceramicNodeUrl: "http://localhost:7007", + legacyChainConfig: LEGACY_CHAIN_CONFIGS.local, chainConfig: CHAIN_CONFIGS.local, }, dev: { apiUrl: "https://nodes-api-dev.desci.com", apiKey: undefined, ceramicNodeUrl: "https://ceramic-dev.desci.com", + legacyChainConfig: LEGACY_CHAIN_CONFIGS.dev, chainConfig: CHAIN_CONFIGS.dev, }, staging: { apiUrl: "https://nodes-api-staging.desci.com", apiKey: undefined, ceramicNodeUrl: "https://ceramic-dev.desci.com", - chainConfig: CHAIN_CONFIGS.dev, // also using the dev sepolia contracts + legacyChainConfig: LEGACY_CHAIN_CONFIGS.dev, // also using the dev contracts + chainConfig: CHAIN_CONFIGS.dev, // also using dev contracts }, prod: { apiUrl: "https://nodes-api.desci.com", apiKey: undefined, ceramicNodeUrl: "https://ceramic-prod.desci.com", + legacyChainConfig: LEGACY_CHAIN_CONFIGS.prod, chainConfig: CHAIN_CONFIGS.prod, }, -} as const satisfies { [Env in NodesEnv]: Config }; +} as const satisfies { [Env in NodesEnv ]: NodesLibConfig }; // Default config to dev environment -let config: Config = NODESLIB_CONFIGS.dev; +let config: NodesLibConfig = NODESLIB_CONFIGS.dev; console.log(`[nodes-lib::config] initialising with nodes-dev config. Use setConfig and setApiKey to change this: \n${JSON.stringify(NODESLIB_CONFIGS.dev, undefined, 2)}`); console.log("[nodes-lib::config] config.apiKey is unset; non-public API requests WILL fail unless running in browser with auth cookies!") @@ -59,7 +64,7 @@ export const setApiKey = (apiKey: string) => { /** * Set a new configuration. You likely want a preset from the `CONFIGS` object. */ -export const setNodesLibConfig = (newConfig: Config): void => { +export const setNodesLibConfig = (newConfig: NodesLibConfig): void => { const confWithRedactedKey = JSON.stringify( { ...newConfig, @@ -82,7 +87,7 @@ export const setNodesLibConfig = (newConfig: Config): void => { * masked by the type to allow browser auth cookie override. */ export const getNodesLibInternalConfig = () => { - return config as Required; + return config as Required; }; export { getResources }; diff --git a/nodes-lib/src/publish.ts b/nodes-lib/src/publish.ts index 2b00e1e6..1ad693e7 100644 --- a/nodes-lib/src/publish.ts +++ b/nodes-lib/src/publish.ts @@ -1,9 +1,46 @@ import { type NodeIDs } from "@desci-labs/desci-codex-lib"; -import { getDpidHistory } from "./api.js"; -import { dpidPublish, hasDpid } from "./chain.js"; +import { IndexedNodeVersion, getDpidHistory, getDraftNode, prePublishDraftNode } from "./api.js"; +import { dpidPublish, hasDpid, lookupLegacyDpid } from "./chain.js"; import { codexPublish } from "./codex.js"; import { Signer } from "ethers"; import { type DID } from "dids"; +import { bnToString } from "./util/converting.js"; + +/** + * Publish node to Codex, potentially migrating history from dPID token. + * Does *not* automatically register a dPID in the alias registry. + */ +export const publish = async ( + uuid: string, + didOrSigner: DID | Signer, +) => { + const node = await getDraftNode(uuid); + const prepubResult = await prePublishDraftNode(uuid); + const dpid = node.manifestData.dpid?.id; + + // We know about a dPID, but not about a stream => should backfill history + const hasHistory = + (dpid !== undefined) && (prepubResult.ceramicStream === undefined); + + let history: IndexedNodeVersion[] = []; + if (hasHistory) { + const legacyEntry = await lookupLegacyDpid(parseInt(dpid)); + // Wrangle BigNumber timestamp to string epoch + history = legacyEntry.versions.map( + ({ cid, time }) => ({ cid, time: bnToString(time) }) + ); + }; + + // Performs backfill migration if there is no stream on record, otherwise + // we can send the empty history array and avoid the history query + const ceramicIDs = await codexPublish(prepubResult, history, didOrSigner); + + return { + cid: prepubResult.updatedManifestCid, + manifest: prepubResult.updatedManifest, + ceramicIDs, + }; +}; /** * The complete publish flow, including both the dPID registry and Codex. @@ -14,8 +51,9 @@ import { type DID } from "dids"; * * @throws (@link WrongOwnerError) if signer address isn't token owner * @throws (@link DpidPublishError) if dPID couldnt be registered or updated + * @deprecated */ -export const publish = async ( +export const legacyPublish = async ( uuid: string, signer: Signer, did?: DID, diff --git a/nodes-lib/src/util/converting.ts b/nodes-lib/src/util/converting.ts index 38af90b3..dbc733e4 100644 --- a/nodes-lib/src/util/converting.ts +++ b/nodes-lib/src/util/converting.ts @@ -3,8 +3,9 @@ import Base64Binary from "./base64binary.js"; import { base16 } from "multiformats/bases/base16"; import { base32 } from "multiformats/bases/base32"; import { CID } from "multiformats/cid"; +import { BigNumber, BigNumberish, utils } from "ethers"; -export const convertUUIDToHex = (uuid: string) => { +export const convertUUIDToHex = (uuid: string): string => { const decoded = decode(uuid); const buffer = Base64Binary.decodeArrayBuffer(decoded).slice(0, 32); let base64UuidToBase16 = Buffer.from(buffer).toString("hex"); @@ -14,14 +15,23 @@ export const convertUUIDToHex = (uuid: string) => { return base64UuidToBase16; }; -export const convertCidTo0xHex = (cid: string) => { +export const convertUUIDToDecimal = (uuid: string): string => { + const asHex = convertUUIDToHex(uuid); + return BigNumber.from(asHex).toString(); +}; + +export const convertCidTo0xHex = (cid: string): string => { const c = CID.parse(cid) const rootStrHex = c.toString(base16); - const paddedAndPrefixed = "0x" + (rootStrHex.length % 2 === 0 ? rootStrHex : "0" + rootStrHex); + const paddedAndPrefixed = "0x" + ( + rootStrHex.length % 2 === 0 + ? rootStrHex + : "0" + rootStrHex + ); return paddedAndPrefixed; }; -export const convert0xHexToCid = (hexCid: string) => { +export const convert0xHexToCid = (hexCid: string): string => { const without0x = hexCid.substring(2); const withoutPadding = without0x.length % 2 === 0 ? without0x.substring(1) @@ -31,3 +41,9 @@ export const convert0xHexToCid = (hexCid: string) => { const cid = CID.decode(cidBytes); return cid.toString(base32); }; + +export const bnToNumber = (bn: BigNumberish): number => + BigNumber.from(bn).toNumber(); + +export const bnToString = (bn: BigNumberish): string => + BigNumber.from(bn).toString(); diff --git a/nodes-lib/src/util/signing.ts b/nodes-lib/src/util/signing.ts index de874434..bd193e6f 100644 --- a/nodes-lib/src/util/signing.ts +++ b/nodes-lib/src/util/signing.ts @@ -1,5 +1,4 @@ -import { Signer, Wallet, getDefaultProvider, providers } from "ethers"; -import { SigningKey } from "ethers/lib/utils.js"; +import { Signer, Wallet, utils, getDefaultProvider, providers } from "ethers"; import { getNodesLibInternalConfig } from "../config/index.js"; import { AuthMethod, AuthMethodOpts, Cacao, SiweMessage } from "@didtools/cacao"; import { EthereumWebAuth, normalizeAccountId } from "@didtools/pkh-ethereum"; @@ -11,9 +10,9 @@ export const signerFromPkey = (pkey: string): Signer => walletFromPkey(pkey); const walletFromPkey = (pkey: string): Wallet => { - const provider = getDefaultProvider(getNodesLibInternalConfig().chainConfig.rpcUrl); + const provider = getDefaultProvider(getNodesLibInternalConfig().legacyChainConfig.rpcUrl); const paddedPkey = ensurePkeyPadding(pkey); - const key = new SigningKey(paddedPkey); + const key = new utils.SigningKey(paddedPkey); return new Wallet(key, provider); }; From 4fb3a200449f112d15106bb03d4c551515e1f11a Mon Sep 17 00:00:00 2001 From: m0ar Date: Wed, 5 Jun 2024 16:09:26 +0200 Subject: [PATCH 127/278] contracts: add capability for contract owner to fix dpid upgrades --- .../opSepoliaDev-dpid-alias-registry.json | 46 ++++++++----------- .../DpidAliasRegistry.json | 24 +--------- .../contracts/DpidAliasRegistry.sol | 42 +++++++++-------- desci-contracts/hardhat.config.ts | 31 ++++++++++--- ...ry_dev_Wed,_12_Jun_2024_13:23:15_GMT.json} | 28 ++++++++++- desci-contracts/package.json | 4 +- .../deployDpidAliasRegistry.js | 0 .../migrateToAliasRegistry.mjs | 0 .../syncAliasRegistryMigration.mjs | 0 desci-contracts/test/DpidAliasRegistry.ts | 19 ++++---- .../typechain-types/DpidAliasRegistry.ts | 46 ------------------- .../factories/DpidAliasRegistry__factory.ts | 22 +-------- 12 files changed, 107 insertions(+), 155 deletions(-) rename desci-contracts/migration-data/{aliasRegistry_dev__Mon,_03_Jun_2024_11:21:28_GMT.json => aliasRegistry_dev_Wed,_12_Jun_2024_13:23:15_GMT.json} (99%) rename desci-contracts/scripts/{ => alias-registry}/deployDpidAliasRegistry.js (100%) rename desci-contracts/scripts/{ => alias-registry}/migrateToAliasRegistry.mjs (100%) rename desci-contracts/scripts/{ => alias-registry}/syncAliasRegistryMigration.mjs (100%) diff --git a/desci-contracts/.openzeppelin/opSepoliaDev-dpid-alias-registry.json b/desci-contracts/.openzeppelin/opSepoliaDev-dpid-alias-registry.json index 6af45131..f88f3115 100644 --- a/desci-contracts/.openzeppelin/opSepoliaDev-dpid-alias-registry.json +++ b/desci-contracts/.openzeppelin/opSepoliaDev-dpid-alias-registry.json @@ -1,20 +1,20 @@ { "manifestVersion": "3.2", "admin": { - "address": "0x64f1dE5b953135c5cEC03DB2B99ffcA0fe11eF88", - "txHash": "0xa1134fbf6b5e3bdfc450beafff59cfb7c3e978014396d52775a304dca2bffb97" + "address": "0x280685c10281F16b4A8585810f695E293B6097eB", + "txHash": "0x5d600bd4cc7f920597350266a6d3840c9d938b6bf5f0d0ccde77117fd2c95ea0" }, "proxies": [ { - "address": "0x7906AC53C2F59d0Eb36dC126336322d25Da15B62", - "txHash": "0xf583111b6d255339f06748889e3adbf9fc313bcdad0480b22f4767b179c673d7", + "address": "0x2Ea4Ee2Af79495e045EBe925aC67d755520877e7", + "txHash": "0x32b16b14970350db7db8bdc9da8c7ddffa389f5678e810f3d3208cb277b76a1c", "kind": "transparent" } ], "impls": { - "e48cadec43394f09ce202bd07138068396bd5f4bf01fcb81e0856ebd63ce19bc": { - "address": "0x5f8ffCbAeAB5F7749bc3Cb333e634265C2D3DF22", - "txHash": "0x996f85a02d3bd579767511ed14a00ebe74ef6ba40319f09f049ad32797dc8d0f", + "a230b5b705959d3e3e4fc01d0b0da971f2e249681ed6a78165280ba33db100b5": { + "address": "0x682c122e535aB4637AA6d8DCCCa106CA89831918", + "txHash": "0x6e925112f68a35e6e8a9ba70f88cab98bc88e3de0e64f5f4d398efb8aaab1721", "layout": { "solcVersion": "0.8.4", "storage": [ @@ -83,37 +83,29 @@ "contract": "DpidAliasRegistry", "src": "contracts/DpidAliasRegistry.sol:10" }, - { - "label": "migrationFrozen", - "offset": 0, - "slot": "152", - "type": "t_bool", - "contract": "DpidAliasRegistry", - "src": "contracts/DpidAliasRegistry.sol:13" - }, { "label": "registry", "offset": 0, - "slot": "153", + "slot": "152", "type": "t_mapping(t_uint256,t_string_storage)", "contract": "DpidAliasRegistry", - "src": "contracts/DpidAliasRegistry.sol:16" + "src": "contracts/DpidAliasRegistry.sol:13" }, { "label": "reverseRegistry", "offset": 0, - "slot": "154", + "slot": "153", "type": "t_mapping(t_string_memory_ptr,t_uint256)", "contract": "DpidAliasRegistry", - "src": "contracts/DpidAliasRegistry.sol:19" + "src": "contracts/DpidAliasRegistry.sol:16" }, { "label": "legacy", "offset": 0, - "slot": "155", - "type": "t_mapping(t_uint256,t_struct(LegacyDpidEntry)845_storage)", + "slot": "154", + "type": "t_mapping(t_uint256,t_struct(LegacyDpidEntry)843_storage)", "contract": "DpidAliasRegistry", - "src": "contracts/DpidAliasRegistry.sol:128" + "src": "contracts/DpidAliasRegistry.sol:125" } ], "types": { @@ -121,7 +113,7 @@ "label": "address", "numberOfBytes": "20" }, - "t_array(t_struct(LegacyVersion)838_storage)dyn_storage": { + "t_array(t_struct(LegacyVersion)836_storage)dyn_storage": { "label": "struct DpidAliasRegistry.LegacyVersion[]", "numberOfBytes": "32" }, @@ -145,7 +137,7 @@ "label": "mapping(uint256 => string)", "numberOfBytes": "32" }, - "t_mapping(t_uint256,t_struct(LegacyDpidEntry)845_storage)": { + "t_mapping(t_uint256,t_struct(LegacyDpidEntry)843_storage)": { "label": "mapping(uint256 => struct DpidAliasRegistry.LegacyDpidEntry)", "numberOfBytes": "32" }, @@ -157,7 +149,7 @@ "label": "string", "numberOfBytes": "32" }, - "t_struct(LegacyDpidEntry)845_storage": { + "t_struct(LegacyDpidEntry)843_storage": { "label": "struct DpidAliasRegistry.LegacyDpidEntry", "members": [ { @@ -168,14 +160,14 @@ }, { "label": "versions", - "type": "t_array(t_struct(LegacyVersion)838_storage)dyn_storage", + "type": "t_array(t_struct(LegacyVersion)836_storage)dyn_storage", "offset": 0, "slot": "1" } ], "numberOfBytes": "64" }, - "t_struct(LegacyVersion)838_storage": { + "t_struct(LegacyVersion)836_storage": { "label": "struct DpidAliasRegistry.LegacyVersion", "members": [ { diff --git a/desci-contracts/artifacts/contracts/DpidAliasRegistry.sol/DpidAliasRegistry.json b/desci-contracts/artifacts/contracts/DpidAliasRegistry.sol/DpidAliasRegistry.json index 842f1f8f..75d6a5e1 100644 --- a/desci-contracts/artifacts/contracts/DpidAliasRegistry.sol/DpidAliasRegistry.json +++ b/desci-contracts/artifacts/contracts/DpidAliasRegistry.sol/DpidAliasRegistry.json @@ -166,13 +166,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [], - "name": "freezeMigration", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [ { @@ -284,19 +277,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [], - "name": "migrationFrozen", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -478,8 +458,8 @@ "type": "function" } ], - "bytecode": "0x60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d3565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000127565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff161015620000ed5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e4919062000149565b60405180910390a15b565b6000620000fe60278362000166565b91506200010b8262000184565b604082019050919050565b620001218162000177565b82525050565b600060208201905081810360008301526200014281620000ef565b9050919050565b600060208201905062000160600083018462000116565b92915050565b600082825260208201905092915050565b600060ff82169050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b612bc280620001e36000396000f3fe608060405234801561001057600080fd5b506004361061012c5760003560e01c80638129fc1c116100ad578063afc2691111610071578063afc26911146102f7578063b724de3a14610315578063b9e2924114610345578063ded8896b14610363578063f2fde38b1461037f5761012c565b80638129fc1c1461027957806382b7b500146102835780638456cb59146102b35780638da5cb5b146102bd578063a5ad8ac6146102db5761012c565b80635893253c116100f45780635893253c146101c15780635c975abb146101f1578063715018a61461020f578063788243d514610219578063810a9afa146102495761012c565b80630d70b3aa14610131578063144ae8551461013b5780633f4ba83a146101575780634f896d4f14610161578063587a8cbf14610191575b600080fd5b61013961039b565b005b610155600480360381019061015091906114c1565b6103c0565b005b61015f61047e565b005b61017b60048036038101906101769190611440565b610498565b6040516101889190611a51565b60405180910390f35b6101ab60048036038101906101a691906113ff565b61053d565b6040516101b89190611bd5565b60405180910390f35b6101db60048036038101906101d69190611440565b61056b565b6040516101e89190611a51565b60405180910390f35b6101f961060b565b6040516102069190611a1b565b60405180910390f35b610217610622565b005b610233600480360381019061022e9190611440565b610636565b6040516102409190611a00565b60405180910390f35b610263600480360381019061025e9190611440565b610674565b6040516102709190611bb3565b60405180910390f35b6102816107f2565b005b61029d600480360381019061029891906113ba565b610940565b6040516102aa9190611bd5565b60405180910390f35b6102bb61096b565b005b6102c5610985565b6040516102d29190611a00565b60405180910390f35b6102f560048036038101906102f09190611440565b6109af565b005b6102ff6109c9565b60405161030c9190611bd5565b60405180910390f35b61032f600480360381019061032a91906113ba565b6109cf565b60405161033c9190611bd5565b60405180910390f35b61034d610aec565b60405161035a9190611a1b565b60405180910390f35b61037d60048036038101906103789190611469565b610aff565b005b61039960048036038101906103949190611391565b610cfc565b005b6103a3610d80565b6001609860006101000a81548160ff021916908315150217905550565b6103c8610d80565b60001515609860009054906101000a900460ff1615151461041e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041590611ad3565b60405180910390fd5b80609b6000848152602001908152602001600020818161043e9190612ae5565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada8282604051610472929190611c22565b60405180910390a15050565b610486610d80565b61048e610dfe565b610496610e47565b565b60606099600083815260200190815260200160002080546104b890612449565b80601f01602080910402602001604051908101604052809291908181526020018280546104e490612449565b80156105315780601f1061050657610100808354040283529160200191610531565b820191906000526020600020905b81548152906001019060200180831161051457829003601f168201915b50505050509050919050565b609a818051602081018201805184825260208301602085012081835280955050505050506000915090505481565b6099602052806000526040600020600091509050805461058a90612449565b80601f01602080910402602001604051908101604052809291908181526020018280546105b690612449565b80156106035780601f106105d857610100808354040283529160200191610603565b820191906000526020600020905b8154815290600101906020018083116105e657829003601f168201915b505050505081565b6000606560009054906101000a900460ff16905090565b61062a610d80565b6106346000610eaa565b565b609b6020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b61067c6111c7565b609b60008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b828210156107e3578382906000526020600020906002020160405180604001604052908160008201805461074890612449565b80601f016020809104026020016040519081016040528092919081815260200182805461077490612449565b80156107c15780601f10610796576101008083540402835291602001916107c1565b820191906000526020600020905b8154815290600101906020018083116107a457829003601f168201915b5050505050815260200160018201548152505081526020019060010190610715565b50505050815250509050919050565b60008060019054906101000a900460ff161590508080156108235750600160008054906101000a900460ff1660ff16105b80610850575061083230610f70565b15801561084f5750600160008054906101000a900460ff1660ff16145b5b61088f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161088690611b33565b60405180910390fd5b60016000806101000a81548160ff021916908360ff16021790555080156108cc576001600060016101000a81548160ff0219169083151502179055505b6108d4610f93565b6108dc610fec565b6108e4611045565b801561093d5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516109349190611a36565b60405180910390a15b50565b6000609a83836040516109549291906119e7565b908152602001604051809103902054905092915050565b610973610d80565b61097b6110a8565b610983611045565b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6109b7610d80565b6109bf610dfe565b8060978190555050565b60975481565b600082826000609a83836040516109e79291906119e7565b90815260200160405180910390205414610a36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a2d90611b13565b60405180910390fd5b610a3e6110a8565b600060975490508585609960008481526020019081526020016000209190610a679291906111f7565b5080609a8787604051610a7b9291906119e7565b9081526020016040518091039020819055507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d818787604051610ac093929190611bf0565b60405180910390a160976000815480929190610adb906124c8565b919050555080935050505092915050565b609860009054906101000a900460ff1681565b81816000609a8383604051610b159291906119e7565b90815260200160405180910390205414610b64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b5b90611b13565b60405180910390fd5b610b6c6110a8565b6000609960008781526020019081526020016000208054610b8c90612449565b905014610bce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bc590611a93565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16609b600087815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610c72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6990611b93565b60405180910390fd5b8383609960008881526020019081526020016000209190610c949291906111f7565b5084609a8585604051610ca89291906119e7565b9081526020016040518091039020819055507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c858585604051610ced93929190611bf0565b60405180910390a15050505050565b610d04610d80565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610d74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6b90611ab3565b60405180910390fd5b610d7d81610eaa565b50565b610d886110f2565b73ffffffffffffffffffffffffffffffffffffffff16610da6610985565b73ffffffffffffffffffffffffffffffffffffffff1614610dfc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610df390611b53565b60405180910390fd5b565b610e0661060b565b610e45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e3c90611a73565b60405180910390fd5b565b610e4f610dfe565b6000606560006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610e936110f2565b604051610ea09190611a00565b60405180910390a1565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610fe2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fd990611b73565b60405180910390fd5b610fea6110fa565b565b600060019054906101000a900460ff1661103b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103290611b73565b60405180910390fd5b61104361115b565b565b61104d6110a8565b6001606560006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586110916110f2565b60405161109e9190611a00565b60405180910390a1565b6110b061060b565b156110f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110e790611af3565b60405180910390fd5b565b600033905090565b600060019054906101000a900460ff16611149576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161114090611b73565b60405180910390fd5b6111596111546110f2565b610eaa565b565b600060019054906101000a900460ff166111aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111a190611b73565b60405180910390fd5b6000606560006101000a81548160ff021916908315150217905550565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b82805461120390612449565b90600052602060002090601f016020900481019282611225576000855561126c565b82601f1061123e57803560ff191683800117855561126c565b8280016001018555821561126c579182015b8281111561126b578235825591602001919060010190611250565b5b509050611279919061127d565b5090565b5b8082111561129657600081600090555060010161127e565b5090565b60006112ad6112a884611d49565b611d24565b9050828152602081018484840111156112c557600080fd5b6112d084828561237b565b509392505050565b6000813590506112e781612b59565b92915050565b60008083601f8401126112ff57600080fd5b8235905067ffffffffffffffff81111561131857600080fd5b60208301915083600182028301111561133057600080fd5b9250929050565b600082601f83011261134857600080fd5b813561135884826020860161129a565b91505092915050565b60006040828403121561137357600080fd5b81905092915050565b60008135905061138b81612b70565b92915050565b6000602082840312156113a357600080fd5b60006113b1848285016112d8565b91505092915050565b600080602083850312156113cd57600080fd5b600083013567ffffffffffffffff8111156113e757600080fd5b6113f3858286016112ed565b92509250509250929050565b60006020828403121561141157600080fd5b600082013567ffffffffffffffff81111561142b57600080fd5b61143784828501611337565b91505092915050565b60006020828403121561145257600080fd5b60006114608482850161137c565b91505092915050565b60008060006040848603121561147e57600080fd5b600061148c8682870161137c565b935050602084013567ffffffffffffffff8111156114a957600080fd5b6114b5868287016112ed565b92509250509250925092565b600080604083850312156114d457600080fd5b60006114e28582860161137c565b925050602083013567ffffffffffffffff8111156114ff57600080fd5b61150b85828601611361565b9150509250929050565b6000611521838361193d565b905092915050565b6000611535838361198c565b905092915050565b611546816120c3565b82525050565b611555816120c3565b82525050565b60006115678385611e26565b93508360208402850161157984611d91565b8060005b878110156115bd578484038952611594828461202e565b61159e8582611515565b94506115a983611e0c565b925060208a0199505060018101905061157d565b50829750879450505050509392505050565b60006115da82611de0565b6115e48185611e26565b9350836020820285016115f685611d9b565b8060005b8581101561163257848403895281516116138582611529565b945061161e83611e19565b925060208a019950506001810190506115fa565b50829750879550505050505092915050565b61164d816120d5565b82525050565b61165c816121be565b82525050565b600061166e8385611e37565b935061167b83858461237b565b6116848361271f565b840190509392505050565b600061169b8385611e48565b93506116a883858461237b565b6116b18361271f565b840190509392505050565b60006116c88385611e59565b93506116d583858461237b565b82840190509392505050565b60006116ec82611e01565b6116f68185611e37565b935061170681856020860161238a565b61170f8161271f565b840191505092915050565b600061172582611e01565b61172f8185611e48565b935061173f81856020860161238a565b6117488161271f565b840191505092915050565b6000611760601483611e48565b915061176b826127ab565b602082019050919050565b6000611783601583611e48565b915061178e826127d4565b602082019050919050565b60006117a6602683611e48565b91506117b1826127fd565b604082019050919050565b60006117c9601383611e48565b91506117d48261284c565b602082019050919050565b60006117ec601083611e48565b91506117f782612875565b602082019050919050565b600061180f601983611e48565b915061181a8261289e565b602082019050919050565b6000611832602e83611e48565b915061183d826128c7565b604082019050919050565b6000611855602083611e48565b915061186082612916565b602082019050919050565b6000611878602b83611e48565b91506118838261293f565b604082019050919050565b600061189b601983611e48565b91506118a68261298e565b602082019050919050565b6000604083016118c46000840184611f69565b6118d1600086018261153d565b506118df6020840184611f80565b85830360208701526118f283828461155b565b925050508091505092915050565b6000604083016000830151611918600086018261153d565b506020830151848203602086015261193082826115cf565b9150508091505092915050565b6000604083016119506000840184611fd7565b8583036000870152611963838284611662565b925050506119746020840184612052565b61198160208601826119c9565b508091505092915050565b600060408301600083015184820360008601526119a982826116e1565b91505060208301516119be60208601826119c9565b508091505092915050565b6119d281612101565b82525050565b6119e181612101565b82525050565b60006119f48284866116bc565b91508190509392505050565b6000602082019050611a15600083018461154c565b92915050565b6000602082019050611a306000830184611644565b92915050565b6000602082019050611a4b6000830184611653565b92915050565b60006020820190508181036000830152611a6b818461171a565b905092915050565b60006020820190508181036000830152611a8c81611753565b9050919050565b60006020820190508181036000830152611aac81611776565b9050919050565b60006020820190508181036000830152611acc81611799565b9050919050565b60006020820190508181036000830152611aec816117bc565b9050919050565b60006020820190508181036000830152611b0c816117df565b9050919050565b60006020820190508181036000830152611b2c81611802565b9050919050565b60006020820190508181036000830152611b4c81611825565b9050919050565b60006020820190508181036000830152611b6c81611848565b9050919050565b60006020820190508181036000830152611b8c8161186b565b9050919050565b60006020820190508181036000830152611bac8161188e565b9050919050565b60006020820190508181036000830152611bcd8184611900565b905092915050565b6000602082019050611bea60008301846119d8565b92915050565b6000604082019050611c0560008301866119d8565b8181036020830152611c1881848661168f565b9050949350505050565b6000604082019050611c3760008301856119d8565b8181036020830152611c4981846118b1565b90509392505050565b60008083356001602003843603038112611c6b57600080fd5b80840192508235915067ffffffffffffffff821115611c8957600080fd5b602083019250602082023603831315611ca157600080fd5b509250929050565b60008083356001602003843603038112611cc257600080fd5b80840192508235915067ffffffffffffffff821115611ce057600080fd5b602083019250600182023603831315611cf857600080fd5b509250929050565b600082356001604003833603038112611d1857600080fd5b80830191505092915050565b6000611d2e611d3f565b9050611d3a8282612497565b919050565b6000604051905090565b600067ffffffffffffffff821115611d6457611d636125bc565b5b611d6d8261271f565b9050602081019050919050565b6000819050611d8a826002612069565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6020841060008114611ebd57601f841160018114611e8d57611e86868561247b565b8355611eb7565b611e9683611dc0565b611eab6020601f880104820160018301612126565b611eb587856129b7565b505b50611f06565b611ec682611dc0565b6020601f8701048101601f87168015611ee757611ee681600184036125eb565b5b611ef96020601f890104840183612126565b6001886002021785555050505b5050505050565b6020831060008114611f58576020851060008114611f3657611f2f868561247b565b8355611f52565b8360ff1916935083611f4784611dc0565b556001866002020183555b50611f62565b6001856002020182555b5050505050565b6000611f7860208401846112d8565b905092915050565b60008083356001602003843603038112611f9957600080fd5b83810192508235915060208301925067ffffffffffffffff821115611fbd57600080fd5b602082023603841315611fcf57600080fd5b509250929050565b60008083356001602003843603038112611ff057600080fd5b83810192508235915060208301925067ffffffffffffffff82111561201457600080fd5b60018202360384131561202657600080fd5b509250929050565b60008235600160400383360303811261204657600080fd5b82810191505092915050565b6000612061602084018461137c565b905092915050565b600061207482612101565b915061207f83612101565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156120b8576120b761255e565b5b828202905092915050565b60006120ce826120e1565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b6121236000826126ca565b50565b5b818110156121455761213a600082612793565b600181019050612127565b5050565b5b818110156121685761215d600082612775565b60028101905061214a565b5050565b8181101561218a5761217f600082612793565b60018101905061216c565b5050565b61219b6000808301612757565b6121a9600060018301612793565b50565b60006121b7826121d0565b9050919050565b60006121c98261210b565b9050919050565b60006121db826121e2565b9050919050565b60006121ed826120e1565b9050919050565b60006121ff82612101565b9050919050565b6122108383611dd5565b61221a8183612666565b61222383611d91565b61222c83611dab565b6000805b84811015612265576122428488611d00565b61224d818486612b16565b60208501945060028401935050600181019050612230565b5050505050505050565b6122798383611df6565b67ffffffffffffffff811115612292576122916125bc565b5b61229c8254612449565b600080601f8411601f841117156122b9576122b685611dc0565b90505b601f8311156122ec576020601f850104810160208510156122d8578190505b6122ea6020601f860104830182612126565b505b601f8411600181146123195760008515612307578388013590505b612311868261247b565b875550612371565b601f1985168260005b8281101561234757858a01358255600182019150602086019550602081019050612322565b8783101561236457858a0135612360601f8a1682612511565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b838110156123a857808201518184015260208101905061238d565b838111156123b7576000848401525b50505050565b6000810160008301806123cf8161263a565b90506123db8184612aa2565b50505060018101602083016123f08185611c52565b6123fb818386612ac5565b505050505050565b60008101600083016124158185611ca9565b612420818386612ad5565b5050505060018101602083018061243681612650565b90506124428184612af3565b5050505050565b6000600282049050600182168061246157607f821691505b602082108114156124755761247461258d565b5b50919050565b60006124878383612511565b9150826002028217905092915050565b6124a08261271f565b810181811067ffffffffffffffff821117156124bf576124be6125bc565b5b80604052505050565b60006124d382612101565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156125065761250561255e565b5b600182019050919050565b60006125226000198460080261274a565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61261b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8360200360080261274a565b815481168255505050565b6000819050919050565b6000819050919050565b6000813561264781612b59565b80915050919050565b6000813561265d81612b70565b80915050919050565b680100000000000000008211156126805761267f6125bc565b5b61268981611deb565b828255808310156126c55761269d81611d7a565b6126a684611d7a565b6126af84611dab565b8181018382016126bf8183612149565b50505050505b505050565b680100000000000000008211156126e4576126e36125bc565b5b80546126ef81612449565b808411156127045761270384828486611f0d565b5b808410156127195761271884828486611e64565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b600082146127685761276761252f565b5b61277181612118565b5050565b600082146127865761278561252f565b5b61278f8161218e565b5050565b61279b612b87565b6127a6818484612b34565b505050565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f6d6967726174696f6e2069732066726f7a656e00000000000000000000000000600082015250565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b7f73747265616d20616c7265616479206861732061206450494400000000000000600082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b6129c081611dc0565b6129cb83825461247b565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff6129f884612730565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612a3a84612730565b9350801983169250808416831791505092915050565b600060088302612a807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261273d565b612a8a868361273d565b95508019841693508086168417925050509392505050565b612aab826121ac565b612abe612ab782612626565b83546129d8565b8255505050565b612ad0838383612206565b505050565b612ae083838361226f565b505050565b612aef82826123bd565b5050565b612afc826121f4565b612b0f612b0882612630565b8354612a0e565b8255505050565b8115612b2557612b2461252f565b5b612b2f8382612403565b505050565b612b3d836121f4565b612b51612b4982612630565b848454612a50565b825550505050565b612b62816120c3565b8114612b6d57600080fd5b50565b612b7981612101565b8114612b8457600080fd5b50565b60009056fea264697066735822122025321e8b3f610ad6d87a9b3497059176ff710a769edbe017d76013391f10763b64736f6c63430008040033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061012c5760003560e01c80638129fc1c116100ad578063afc2691111610071578063afc26911146102f7578063b724de3a14610315578063b9e2924114610345578063ded8896b14610363578063f2fde38b1461037f5761012c565b80638129fc1c1461027957806382b7b500146102835780638456cb59146102b35780638da5cb5b146102bd578063a5ad8ac6146102db5761012c565b80635893253c116100f45780635893253c146101c15780635c975abb146101f1578063715018a61461020f578063788243d514610219578063810a9afa146102495761012c565b80630d70b3aa14610131578063144ae8551461013b5780633f4ba83a146101575780634f896d4f14610161578063587a8cbf14610191575b600080fd5b61013961039b565b005b610155600480360381019061015091906114c1565b6103c0565b005b61015f61047e565b005b61017b60048036038101906101769190611440565b610498565b6040516101889190611a51565b60405180910390f35b6101ab60048036038101906101a691906113ff565b61053d565b6040516101b89190611bd5565b60405180910390f35b6101db60048036038101906101d69190611440565b61056b565b6040516101e89190611a51565b60405180910390f35b6101f961060b565b6040516102069190611a1b565b60405180910390f35b610217610622565b005b610233600480360381019061022e9190611440565b610636565b6040516102409190611a00565b60405180910390f35b610263600480360381019061025e9190611440565b610674565b6040516102709190611bb3565b60405180910390f35b6102816107f2565b005b61029d600480360381019061029891906113ba565b610940565b6040516102aa9190611bd5565b60405180910390f35b6102bb61096b565b005b6102c5610985565b6040516102d29190611a00565b60405180910390f35b6102f560048036038101906102f09190611440565b6109af565b005b6102ff6109c9565b60405161030c9190611bd5565b60405180910390f35b61032f600480360381019061032a91906113ba565b6109cf565b60405161033c9190611bd5565b60405180910390f35b61034d610aec565b60405161035a9190611a1b565b60405180910390f35b61037d60048036038101906103789190611469565b610aff565b005b61039960048036038101906103949190611391565b610cfc565b005b6103a3610d80565b6001609860006101000a81548160ff021916908315150217905550565b6103c8610d80565b60001515609860009054906101000a900460ff1615151461041e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041590611ad3565b60405180910390fd5b80609b6000848152602001908152602001600020818161043e9190612ae5565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada8282604051610472929190611c22565b60405180910390a15050565b610486610d80565b61048e610dfe565b610496610e47565b565b60606099600083815260200190815260200160002080546104b890612449565b80601f01602080910402602001604051908101604052809291908181526020018280546104e490612449565b80156105315780601f1061050657610100808354040283529160200191610531565b820191906000526020600020905b81548152906001019060200180831161051457829003601f168201915b50505050509050919050565b609a818051602081018201805184825260208301602085012081835280955050505050506000915090505481565b6099602052806000526040600020600091509050805461058a90612449565b80601f01602080910402602001604051908101604052809291908181526020018280546105b690612449565b80156106035780601f106105d857610100808354040283529160200191610603565b820191906000526020600020905b8154815290600101906020018083116105e657829003601f168201915b505050505081565b6000606560009054906101000a900460ff16905090565b61062a610d80565b6106346000610eaa565b565b609b6020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b61067c6111c7565b609b60008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b828210156107e3578382906000526020600020906002020160405180604001604052908160008201805461074890612449565b80601f016020809104026020016040519081016040528092919081815260200182805461077490612449565b80156107c15780601f10610796576101008083540402835291602001916107c1565b820191906000526020600020905b8154815290600101906020018083116107a457829003601f168201915b5050505050815260200160018201548152505081526020019060010190610715565b50505050815250509050919050565b60008060019054906101000a900460ff161590508080156108235750600160008054906101000a900460ff1660ff16105b80610850575061083230610f70565b15801561084f5750600160008054906101000a900460ff1660ff16145b5b61088f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161088690611b33565b60405180910390fd5b60016000806101000a81548160ff021916908360ff16021790555080156108cc576001600060016101000a81548160ff0219169083151502179055505b6108d4610f93565b6108dc610fec565b6108e4611045565b801561093d5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516109349190611a36565b60405180910390a15b50565b6000609a83836040516109549291906119e7565b908152602001604051809103902054905092915050565b610973610d80565b61097b6110a8565b610983611045565b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6109b7610d80565b6109bf610dfe565b8060978190555050565b60975481565b600082826000609a83836040516109e79291906119e7565b90815260200160405180910390205414610a36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a2d90611b13565b60405180910390fd5b610a3e6110a8565b600060975490508585609960008481526020019081526020016000209190610a679291906111f7565b5080609a8787604051610a7b9291906119e7565b9081526020016040518091039020819055507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d818787604051610ac093929190611bf0565b60405180910390a160976000815480929190610adb906124c8565b919050555080935050505092915050565b609860009054906101000a900460ff1681565b81816000609a8383604051610b159291906119e7565b90815260200160405180910390205414610b64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b5b90611b13565b60405180910390fd5b610b6c6110a8565b6000609960008781526020019081526020016000208054610b8c90612449565b905014610bce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bc590611a93565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16609b600087815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610c72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6990611b93565b60405180910390fd5b8383609960008881526020019081526020016000209190610c949291906111f7565b5084609a8585604051610ca89291906119e7565b9081526020016040518091039020819055507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c858585604051610ced93929190611bf0565b60405180910390a15050505050565b610d04610d80565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610d74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6b90611ab3565b60405180910390fd5b610d7d81610eaa565b50565b610d886110f2565b73ffffffffffffffffffffffffffffffffffffffff16610da6610985565b73ffffffffffffffffffffffffffffffffffffffff1614610dfc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610df390611b53565b60405180910390fd5b565b610e0661060b565b610e45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e3c90611a73565b60405180910390fd5b565b610e4f610dfe565b6000606560006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610e936110f2565b604051610ea09190611a00565b60405180910390a1565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610fe2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fd990611b73565b60405180910390fd5b610fea6110fa565b565b600060019054906101000a900460ff1661103b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103290611b73565b60405180910390fd5b61104361115b565b565b61104d6110a8565b6001606560006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586110916110f2565b60405161109e9190611a00565b60405180910390a1565b6110b061060b565b156110f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110e790611af3565b60405180910390fd5b565b600033905090565b600060019054906101000a900460ff16611149576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161114090611b73565b60405180910390fd5b6111596111546110f2565b610eaa565b565b600060019054906101000a900460ff166111aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111a190611b73565b60405180910390fd5b6000606560006101000a81548160ff021916908315150217905550565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b82805461120390612449565b90600052602060002090601f016020900481019282611225576000855561126c565b82601f1061123e57803560ff191683800117855561126c565b8280016001018555821561126c579182015b8281111561126b578235825591602001919060010190611250565b5b509050611279919061127d565b5090565b5b8082111561129657600081600090555060010161127e565b5090565b60006112ad6112a884611d49565b611d24565b9050828152602081018484840111156112c557600080fd5b6112d084828561237b565b509392505050565b6000813590506112e781612b59565b92915050565b60008083601f8401126112ff57600080fd5b8235905067ffffffffffffffff81111561131857600080fd5b60208301915083600182028301111561133057600080fd5b9250929050565b600082601f83011261134857600080fd5b813561135884826020860161129a565b91505092915050565b60006040828403121561137357600080fd5b81905092915050565b60008135905061138b81612b70565b92915050565b6000602082840312156113a357600080fd5b60006113b1848285016112d8565b91505092915050565b600080602083850312156113cd57600080fd5b600083013567ffffffffffffffff8111156113e757600080fd5b6113f3858286016112ed565b92509250509250929050565b60006020828403121561141157600080fd5b600082013567ffffffffffffffff81111561142b57600080fd5b61143784828501611337565b91505092915050565b60006020828403121561145257600080fd5b60006114608482850161137c565b91505092915050565b60008060006040848603121561147e57600080fd5b600061148c8682870161137c565b935050602084013567ffffffffffffffff8111156114a957600080fd5b6114b5868287016112ed565b92509250509250925092565b600080604083850312156114d457600080fd5b60006114e28582860161137c565b925050602083013567ffffffffffffffff8111156114ff57600080fd5b61150b85828601611361565b9150509250929050565b6000611521838361193d565b905092915050565b6000611535838361198c565b905092915050565b611546816120c3565b82525050565b611555816120c3565b82525050565b60006115678385611e26565b93508360208402850161157984611d91565b8060005b878110156115bd578484038952611594828461202e565b61159e8582611515565b94506115a983611e0c565b925060208a0199505060018101905061157d565b50829750879450505050509392505050565b60006115da82611de0565b6115e48185611e26565b9350836020820285016115f685611d9b565b8060005b8581101561163257848403895281516116138582611529565b945061161e83611e19565b925060208a019950506001810190506115fa565b50829750879550505050505092915050565b61164d816120d5565b82525050565b61165c816121be565b82525050565b600061166e8385611e37565b935061167b83858461237b565b6116848361271f565b840190509392505050565b600061169b8385611e48565b93506116a883858461237b565b6116b18361271f565b840190509392505050565b60006116c88385611e59565b93506116d583858461237b565b82840190509392505050565b60006116ec82611e01565b6116f68185611e37565b935061170681856020860161238a565b61170f8161271f565b840191505092915050565b600061172582611e01565b61172f8185611e48565b935061173f81856020860161238a565b6117488161271f565b840191505092915050565b6000611760601483611e48565b915061176b826127ab565b602082019050919050565b6000611783601583611e48565b915061178e826127d4565b602082019050919050565b60006117a6602683611e48565b91506117b1826127fd565b604082019050919050565b60006117c9601383611e48565b91506117d48261284c565b602082019050919050565b60006117ec601083611e48565b91506117f782612875565b602082019050919050565b600061180f601983611e48565b915061181a8261289e565b602082019050919050565b6000611832602e83611e48565b915061183d826128c7565b604082019050919050565b6000611855602083611e48565b915061186082612916565b602082019050919050565b6000611878602b83611e48565b91506118838261293f565b604082019050919050565b600061189b601983611e48565b91506118a68261298e565b602082019050919050565b6000604083016118c46000840184611f69565b6118d1600086018261153d565b506118df6020840184611f80565b85830360208701526118f283828461155b565b925050508091505092915050565b6000604083016000830151611918600086018261153d565b506020830151848203602086015261193082826115cf565b9150508091505092915050565b6000604083016119506000840184611fd7565b8583036000870152611963838284611662565b925050506119746020840184612052565b61198160208601826119c9565b508091505092915050565b600060408301600083015184820360008601526119a982826116e1565b91505060208301516119be60208601826119c9565b508091505092915050565b6119d281612101565b82525050565b6119e181612101565b82525050565b60006119f48284866116bc565b91508190509392505050565b6000602082019050611a15600083018461154c565b92915050565b6000602082019050611a306000830184611644565b92915050565b6000602082019050611a4b6000830184611653565b92915050565b60006020820190508181036000830152611a6b818461171a565b905092915050565b60006020820190508181036000830152611a8c81611753565b9050919050565b60006020820190508181036000830152611aac81611776565b9050919050565b60006020820190508181036000830152611acc81611799565b9050919050565b60006020820190508181036000830152611aec816117bc565b9050919050565b60006020820190508181036000830152611b0c816117df565b9050919050565b60006020820190508181036000830152611b2c81611802565b9050919050565b60006020820190508181036000830152611b4c81611825565b9050919050565b60006020820190508181036000830152611b6c81611848565b9050919050565b60006020820190508181036000830152611b8c8161186b565b9050919050565b60006020820190508181036000830152611bac8161188e565b9050919050565b60006020820190508181036000830152611bcd8184611900565b905092915050565b6000602082019050611bea60008301846119d8565b92915050565b6000604082019050611c0560008301866119d8565b8181036020830152611c1881848661168f565b9050949350505050565b6000604082019050611c3760008301856119d8565b8181036020830152611c4981846118b1565b90509392505050565b60008083356001602003843603038112611c6b57600080fd5b80840192508235915067ffffffffffffffff821115611c8957600080fd5b602083019250602082023603831315611ca157600080fd5b509250929050565b60008083356001602003843603038112611cc257600080fd5b80840192508235915067ffffffffffffffff821115611ce057600080fd5b602083019250600182023603831315611cf857600080fd5b509250929050565b600082356001604003833603038112611d1857600080fd5b80830191505092915050565b6000611d2e611d3f565b9050611d3a8282612497565b919050565b6000604051905090565b600067ffffffffffffffff821115611d6457611d636125bc565b5b611d6d8261271f565b9050602081019050919050565b6000819050611d8a826002612069565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6020841060008114611ebd57601f841160018114611e8d57611e86868561247b565b8355611eb7565b611e9683611dc0565b611eab6020601f880104820160018301612126565b611eb587856129b7565b505b50611f06565b611ec682611dc0565b6020601f8701048101601f87168015611ee757611ee681600184036125eb565b5b611ef96020601f890104840183612126565b6001886002021785555050505b5050505050565b6020831060008114611f58576020851060008114611f3657611f2f868561247b565b8355611f52565b8360ff1916935083611f4784611dc0565b556001866002020183555b50611f62565b6001856002020182555b5050505050565b6000611f7860208401846112d8565b905092915050565b60008083356001602003843603038112611f9957600080fd5b83810192508235915060208301925067ffffffffffffffff821115611fbd57600080fd5b602082023603841315611fcf57600080fd5b509250929050565b60008083356001602003843603038112611ff057600080fd5b83810192508235915060208301925067ffffffffffffffff82111561201457600080fd5b60018202360384131561202657600080fd5b509250929050565b60008235600160400383360303811261204657600080fd5b82810191505092915050565b6000612061602084018461137c565b905092915050565b600061207482612101565b915061207f83612101565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156120b8576120b761255e565b5b828202905092915050565b60006120ce826120e1565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b6121236000826126ca565b50565b5b818110156121455761213a600082612793565b600181019050612127565b5050565b5b818110156121685761215d600082612775565b60028101905061214a565b5050565b8181101561218a5761217f600082612793565b60018101905061216c565b5050565b61219b6000808301612757565b6121a9600060018301612793565b50565b60006121b7826121d0565b9050919050565b60006121c98261210b565b9050919050565b60006121db826121e2565b9050919050565b60006121ed826120e1565b9050919050565b60006121ff82612101565b9050919050565b6122108383611dd5565b61221a8183612666565b61222383611d91565b61222c83611dab565b6000805b84811015612265576122428488611d00565b61224d818486612b16565b60208501945060028401935050600181019050612230565b5050505050505050565b6122798383611df6565b67ffffffffffffffff811115612292576122916125bc565b5b61229c8254612449565b600080601f8411601f841117156122b9576122b685611dc0565b90505b601f8311156122ec576020601f850104810160208510156122d8578190505b6122ea6020601f860104830182612126565b505b601f8411600181146123195760008515612307578388013590505b612311868261247b565b875550612371565b601f1985168260005b8281101561234757858a01358255600182019150602086019550602081019050612322565b8783101561236457858a0135612360601f8a1682612511565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b838110156123a857808201518184015260208101905061238d565b838111156123b7576000848401525b50505050565b6000810160008301806123cf8161263a565b90506123db8184612aa2565b50505060018101602083016123f08185611c52565b6123fb818386612ac5565b505050505050565b60008101600083016124158185611ca9565b612420818386612ad5565b5050505060018101602083018061243681612650565b90506124428184612af3565b5050505050565b6000600282049050600182168061246157607f821691505b602082108114156124755761247461258d565b5b50919050565b60006124878383612511565b9150826002028217905092915050565b6124a08261271f565b810181811067ffffffffffffffff821117156124bf576124be6125bc565b5b80604052505050565b60006124d382612101565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156125065761250561255e565b5b600182019050919050565b60006125226000198460080261274a565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61261b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8360200360080261274a565b815481168255505050565b6000819050919050565b6000819050919050565b6000813561264781612b59565b80915050919050565b6000813561265d81612b70565b80915050919050565b680100000000000000008211156126805761267f6125bc565b5b61268981611deb565b828255808310156126c55761269d81611d7a565b6126a684611d7a565b6126af84611dab565b8181018382016126bf8183612149565b50505050505b505050565b680100000000000000008211156126e4576126e36125bc565b5b80546126ef81612449565b808411156127045761270384828486611f0d565b5b808410156127195761271884828486611e64565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b600082146127685761276761252f565b5b61277181612118565b5050565b600082146127865761278561252f565b5b61278f8161218e565b5050565b61279b612b87565b6127a6818484612b34565b505050565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f6d6967726174696f6e2069732066726f7a656e00000000000000000000000000600082015250565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b7f73747265616d20616c7265616479206861732061206450494400000000000000600082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b6129c081611dc0565b6129cb83825461247b565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff6129f884612730565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612a3a84612730565b9350801983169250808416831791505092915050565b600060088302612a807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261273d565b612a8a868361273d565b95508019841693508086168417925050509392505050565b612aab826121ac565b612abe612ab782612626565b83546129d8565b8255505050565b612ad0838383612206565b505050565b612ae083838361226f565b505050565b612aef82826123bd565b5050565b612afc826121f4565b612b0f612b0882612630565b8354612a0e565b8255505050565b8115612b2557612b2461252f565b5b612b2f8382612403565b505050565b612b3d836121f4565b612b51612b4982612630565b848454612a50565b825550505050565b612b62816120c3565b8114612b6d57600080fd5b50565b612b7981612101565b8114612b8457600080fd5b50565b60009056fea264697066735822122025321e8b3f610ad6d87a9b3497059176ff710a769edbe017d76013391f10763b64736f6c63430008040033", + "bytecode": "0x60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d3565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000127565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff161015620000ed5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e4919062000149565b60405180910390a15b565b6000620000fe60278362000166565b91506200010b8262000184565b604082019050919050565b620001218162000177565b82525050565b600060208201905081810360008301526200014281620000ef565b9050919050565b600060208201905062000160600083018462000116565b92915050565b600082825260208201905092915050565b600060ff82169050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b612b0480620001e36000396000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638129fc1c116100a2578063a5ad8ac611610071578063a5ad8ac6146102bb578063afc26911146102d7578063b724de3a146102f5578063ded8896b14610325578063f2fde38b1461034157610116565b80638129fc1c1461025957806382b7b500146102635780638456cb59146102935780638da5cb5b1461029d57610116565b80635893253c116100e95780635893253c146101a15780635c975abb146101d1578063715018a6146101ef578063788243d5146101f9578063810a9afa1461022957610116565b8063144ae8551461011b5780633f4ba83a146101375780634f896d4f14610141578063587a8cbf14610171575b600080fd5b6101356004803603810190610130919061146f565b61035d565b005b61013f6103c5565b005b61015b600480360381019061015691906113ee565b6103df565b60405161016891906119dc565b60405180910390f35b61018b600480360381019061018691906113ad565b610484565b6040516101989190611b40565b60405180910390f35b6101bb60048036038101906101b691906113ee565b6104b2565b6040516101c891906119dc565b60405180910390f35b6101d9610552565b6040516101e691906119a6565b60405180910390f35b6101f7610569565b005b610213600480360381019061020e91906113ee565b61057d565b604051610220919061198b565b60405180910390f35b610243600480360381019061023e91906113ee565b6105bb565b6040516102509190611b1e565b60405180910390f35b610261610739565b005b61027d60048036038101906102789190611368565b610887565b60405161028a9190611b40565b60405180910390f35b61029b6108b2565b005b6102a56108cc565b6040516102b2919061198b565b60405180910390f35b6102d560048036038101906102d091906113ee565b6108f6565b005b6102df610910565b6040516102ec9190611b40565b60405180910390f35b61030f600480360381019061030a9190611368565b610916565b60405161031c9190611b40565b60405180910390f35b61033f600480360381019061033a9190611417565b610a33565b005b61035b6004803603810190610356919061133f565b610caa565b005b610365610d2e565b80609a600084815260200190815260200160002081816103859190612a27565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada82826040516103b9929190611b8d565b60405180910390a15050565b6103cd610d2e565b6103d5610dac565b6103dd610df5565b565b60606098600083815260200190815260200160002080546103ff906123b4565b80601f016020809104026020016040519081016040528092919081815260200182805461042b906123b4565b80156104785780601f1061044d57610100808354040283529160200191610478565b820191906000526020600020905b81548152906001019060200180831161045b57829003601f168201915b50505050509050919050565b6099818051602081018201805184825260208301602085012081835280955050505050506000915090505481565b609860205280600052604060002060009150905080546104d1906123b4565b80601f01602080910402602001604051908101604052809291908181526020018280546104fd906123b4565b801561054a5780601f1061051f5761010080835404028352916020019161054a565b820191906000526020600020905b81548152906001019060200180831161052d57829003601f168201915b505050505081565b6000606560009054906101000a900460ff16905090565b610571610d2e565b61057b6000610e58565b565b609a6020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b6105c3611175565b609a60008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b8282101561072a578382906000526020600020906002020160405180604001604052908160008201805461068f906123b4565b80601f01602080910402602001604051908101604052809291908181526020018280546106bb906123b4565b80156107085780601f106106dd57610100808354040283529160200191610708565b820191906000526020600020905b8154815290600101906020018083116106eb57829003601f168201915b505050505081526020016001820154815250508152602001906001019061065c565b50505050815250509050919050565b60008060019054906101000a900460ff1615905080801561076a5750600160008054906101000a900460ff1660ff16105b80610797575061077930610f1e565b1580156107965750600160008054906101000a900460ff1660ff16145b5b6107d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107cd90611a9e565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015610813576001600060016101000a81548160ff0219169083151502179055505b61081b610f41565b610823610f9a565b61082b610ff3565b80156108845760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498600160405161087b91906119c1565b60405180910390a15b50565b60006099838360405161089b929190611972565b908152602001604051809103902054905092915050565b6108ba610d2e565b6108c2611056565b6108ca610ff3565b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6108fe610d2e565b610906610dac565b8060978190555050565b60975481565b6000828260006099838360405161092e929190611972565b9081526020016040518091039020541461097d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097490611a7e565b60405180910390fd5b610985611056565b6000609754905085856098600084815260200190815260200160002091906109ae9291906111a5565b5080609987876040516109c2929190611972565b9081526020016040518091039020819055507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d818787604051610a0793929190611b5b565b60405180910390a160976000815480929190610a2290612433565b919050555080935050505092915050565b8181600060998383604051610a49929190611972565b90815260200160405180910390205414610a98576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a8f90611a7e565b60405180910390fd5b610aa0611056565b6000609860008781526020019081526020016000208054610ac0906123b4565b90501480610b005750610ad16108cc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610b3f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b3690611a1e565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16609a600087815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161480610be15750610bb26108cc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610c20576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1790611afe565b60405180910390fd5b8383609860008881526020019081526020016000209190610c429291906111a5565b508460998585604051610c56929190611972565b9081526020016040518091039020819055507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c858585604051610c9b93929190611b5b565b60405180910390a15050505050565b610cb2610d2e565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610d22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d1990611a3e565b60405180910390fd5b610d2b81610e58565b50565b610d366110a0565b73ffffffffffffffffffffffffffffffffffffffff16610d546108cc565b73ffffffffffffffffffffffffffffffffffffffff1614610daa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610da190611abe565b60405180910390fd5b565b610db4610552565b610df3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dea906119fe565b60405180910390fd5b565b610dfd610dac565b6000606560006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610e416110a0565b604051610e4e919061198b565b60405180910390a1565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610f90576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8790611ade565b60405180910390fd5b610f986110a8565b565b600060019054906101000a900460ff16610fe9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fe090611ade565b60405180910390fd5b610ff1611109565b565b610ffb611056565b6001606560006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861103f6110a0565b60405161104c919061198b565b60405180910390a1565b61105e610552565b1561109e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161109590611a5e565b60405180910390fd5b565b600033905090565b600060019054906101000a900460ff166110f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110ee90611ade565b60405180910390fd5b6111076111026110a0565b610e58565b565b600060019054906101000a900460ff16611158576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161114f90611ade565b60405180910390fd5b6000606560006101000a81548160ff021916908315150217905550565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b8280546111b1906123b4565b90600052602060002090601f0160209004810192826111d3576000855561121a565b82601f106111ec57803560ff191683800117855561121a565b8280016001018555821561121a579182015b828111156112195782358255916020019190600101906111fe565b5b509050611227919061122b565b5090565b5b8082111561124457600081600090555060010161122c565b5090565b600061125b61125684611cb4565b611c8f565b90508281526020810184848401111561127357600080fd5b61127e8482856122e6565b509392505050565b60008135905061129581612a9b565b92915050565b60008083601f8401126112ad57600080fd5b8235905067ffffffffffffffff8111156112c657600080fd5b6020830191508360018202830111156112de57600080fd5b9250929050565b600082601f8301126112f657600080fd5b8135611306848260208601611248565b91505092915050565b60006040828403121561132157600080fd5b81905092915050565b60008135905061133981612ab2565b92915050565b60006020828403121561135157600080fd5b600061135f84828501611286565b91505092915050565b6000806020838503121561137b57600080fd5b600083013567ffffffffffffffff81111561139557600080fd5b6113a18582860161129b565b92509250509250929050565b6000602082840312156113bf57600080fd5b600082013567ffffffffffffffff8111156113d957600080fd5b6113e5848285016112e5565b91505092915050565b60006020828403121561140057600080fd5b600061140e8482850161132a565b91505092915050565b60008060006040848603121561142c57600080fd5b600061143a8682870161132a565b935050602084013567ffffffffffffffff81111561145757600080fd5b6114638682870161129b565b92509250509250925092565b6000806040838503121561148257600080fd5b60006114908582860161132a565b925050602083013567ffffffffffffffff8111156114ad57600080fd5b6114b98582860161130f565b9150509250929050565b60006114cf83836118c8565b905092915050565b60006114e38383611917565b905092915050565b6114f48161202e565b82525050565b6115038161202e565b82525050565b60006115158385611d91565b93508360208402850161152784611cfc565b8060005b8781101561156b5784840389526115428284611f99565b61154c85826114c3565b945061155783611d77565b925060208a0199505060018101905061152b565b50829750879450505050509392505050565b600061158882611d4b565b6115928185611d91565b9350836020820285016115a485611d06565b8060005b858110156115e057848403895281516115c185826114d7565b94506115cc83611d84565b925060208a019950506001810190506115a8565b50829750879550505050505092915050565b6115fb81612040565b82525050565b61160a81612129565b82525050565b600061161c8385611da2565b93506116298385846122e6565b6116328361268a565b840190509392505050565b60006116498385611db3565b93506116568385846122e6565b61165f8361268a565b840190509392505050565b60006116768385611dc4565b93506116838385846122e6565b82840190509392505050565b600061169a82611d6c565b6116a48185611da2565b93506116b48185602086016122f5565b6116bd8161268a565b840191505092915050565b60006116d382611d6c565b6116dd8185611db3565b93506116ed8185602086016122f5565b6116f68161268a565b840191505092915050565b600061170e601483611db3565b915061171982612716565b602082019050919050565b6000611731601583611db3565b915061173c8261273f565b602082019050919050565b6000611754602683611db3565b915061175f82612768565b604082019050919050565b6000611777601083611db3565b9150611782826127b7565b602082019050919050565b600061179a601983611db3565b91506117a5826127e0565b602082019050919050565b60006117bd602e83611db3565b91506117c882612809565b604082019050919050565b60006117e0602083611db3565b91506117eb82612858565b602082019050919050565b6000611803602b83611db3565b915061180e82612881565b604082019050919050565b6000611826601983611db3565b9150611831826128d0565b602082019050919050565b60006040830161184f6000840184611ed4565b61185c60008601826114eb565b5061186a6020840184611eeb565b858303602087015261187d838284611509565b925050508091505092915050565b60006040830160008301516118a360008601826114eb565b50602083015184820360208601526118bb828261157d565b9150508091505092915050565b6000604083016118db6000840184611f42565b85830360008701526118ee838284611610565b925050506118ff6020840184611fbd565b61190c6020860182611954565b508091505092915050565b60006040830160008301518482036000860152611934828261168f565b91505060208301516119496020860182611954565b508091505092915050565b61195d8161206c565b82525050565b61196c8161206c565b82525050565b600061197f82848661166a565b91508190509392505050565b60006020820190506119a060008301846114fa565b92915050565b60006020820190506119bb60008301846115f2565b92915050565b60006020820190506119d66000830184611601565b92915050565b600060208201905081810360008301526119f681846116c8565b905092915050565b60006020820190508181036000830152611a1781611701565b9050919050565b60006020820190508181036000830152611a3781611724565b9050919050565b60006020820190508181036000830152611a5781611747565b9050919050565b60006020820190508181036000830152611a778161176a565b9050919050565b60006020820190508181036000830152611a978161178d565b9050919050565b60006020820190508181036000830152611ab7816117b0565b9050919050565b60006020820190508181036000830152611ad7816117d3565b9050919050565b60006020820190508181036000830152611af7816117f6565b9050919050565b60006020820190508181036000830152611b1781611819565b9050919050565b60006020820190508181036000830152611b38818461188b565b905092915050565b6000602082019050611b556000830184611963565b92915050565b6000604082019050611b706000830186611963565b8181036020830152611b8381848661163d565b9050949350505050565b6000604082019050611ba26000830185611963565b8181036020830152611bb4818461183c565b90509392505050565b60008083356001602003843603038112611bd657600080fd5b80840192508235915067ffffffffffffffff821115611bf457600080fd5b602083019250602082023603831315611c0c57600080fd5b509250929050565b60008083356001602003843603038112611c2d57600080fd5b80840192508235915067ffffffffffffffff821115611c4b57600080fd5b602083019250600182023603831315611c6357600080fd5b509250929050565b600082356001604003833603038112611c8357600080fd5b80830191505092915050565b6000611c99611caa565b9050611ca58282612402565b919050565b6000604051905090565b600067ffffffffffffffff821115611ccf57611cce612527565b5b611cd88261268a565b9050602081019050919050565b6000819050611cf5826002611fd4565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6020841060008114611e2857601f841160018114611df857611df186856123e6565b8355611e22565b611e0183611d2b565b611e166020601f880104820160018301612091565b611e2087856128f9565b505b50611e71565b611e3182611d2b565b6020601f8701048101601f87168015611e5257611e518160018403612556565b5b611e646020601f890104840183612091565b6001886002021785555050505b5050505050565b6020831060008114611ec3576020851060008114611ea157611e9a86856123e6565b8355611ebd565b8360ff1916935083611eb284611d2b565b556001866002020183555b50611ecd565b6001856002020182555b5050505050565b6000611ee36020840184611286565b905092915050565b60008083356001602003843603038112611f0457600080fd5b83810192508235915060208301925067ffffffffffffffff821115611f2857600080fd5b602082023603841315611f3a57600080fd5b509250929050565b60008083356001602003843603038112611f5b57600080fd5b83810192508235915060208301925067ffffffffffffffff821115611f7f57600080fd5b600182023603841315611f9157600080fd5b509250929050565b600082356001604003833603038112611fb157600080fd5b82810191505092915050565b6000611fcc602084018461132a565b905092915050565b6000611fdf8261206c565b9150611fea8361206c565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612023576120226124c9565b5b828202905092915050565b60006120398261204c565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b61208e600082612635565b50565b5b818110156120b0576120a56000826126fe565b600181019050612092565b5050565b5b818110156120d3576120c86000826126e0565b6002810190506120b5565b5050565b818110156120f5576120ea6000826126fe565b6001810190506120d7565b5050565b61210660008083016126c2565b6121146000600183016126fe565b50565b60006121228261213b565b9050919050565b600061213482612076565b9050919050565b60006121468261214d565b9050919050565b60006121588261204c565b9050919050565b600061216a8261206c565b9050919050565b61217b8383611d40565b61218581836125d1565b61218e83611cfc565b61219783611d16565b6000805b848110156121d0576121ad8488611c6b565b6121b8818486612a58565b6020850194506002840193505060018101905061219b565b5050505050505050565b6121e48383611d61565b67ffffffffffffffff8111156121fd576121fc612527565b5b61220782546123b4565b600080601f8411601f841117156122245761222185611d2b565b90505b601f831115612257576020601f85010481016020851015612243578190505b6122556020601f860104830182612091565b505b601f8411600181146122845760008515612272578388013590505b61227c86826123e6565b8755506122dc565b601f1985168260005b828110156122b257858a0135825560018201915060208601955060208101905061228d565b878310156122cf57858a01356122cb601f8a168261247c565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b838110156123135780820151818401526020810190506122f8565b83811115612322576000848401525b50505050565b60008101600083018061233a816125a5565b905061234681846129e4565b505050600181016020830161235b8185611bbd565b612366818386612a07565b505050505050565b60008101600083016123808185611c14565b61238b818386612a17565b505050506001810160208301806123a1816125bb565b90506123ad8184612a35565b5050505050565b600060028204905060018216806123cc57607f821691505b602082108114156123e0576123df6124f8565b5b50919050565b60006123f2838361247c565b9150826002028217905092915050565b61240b8261268a565b810181811067ffffffffffffffff8211171561242a57612429612527565b5b80604052505050565b600061243e8261206c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612471576124706124c9565b5b600182019050919050565b600061248d600019846008026126b5565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6125867fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff836020036008026126b5565b815481168255505050565b6000819050919050565b6000819050919050565b600081356125b281612a9b565b80915050919050565b600081356125c881612ab2565b80915050919050565b680100000000000000008211156125eb576125ea612527565b5b6125f481611d56565b828255808310156126305761260881611ce5565b61261184611ce5565b61261a84611d16565b81810183820161262a81836120b4565b50505050505b505050565b6801000000000000000082111561264f5761264e612527565b5b805461265a816123b4565b8084111561266f5761266e84828486611e78565b5b808410156126845761268384828486611dcf565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b600082146126d3576126d261249a565b5b6126dc81612083565b5050565b600082146126f1576126f061249a565b5b6126fa816120f9565b5050565b612706612ac9565b612711818484612a76565b505050565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b7f73747265616d20616c7265616479206861732061206450494400000000000000600082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b61290281611d2b565b61290d8382546123e6565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff61293a8461269b565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61297c8461269b565b9350801983169250808416831791505092915050565b6000600883026129c27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826126a8565b6129cc86836126a8565b95508019841693508086168417925050509392505050565b6129ed82612117565b612a006129f982612591565b835461291a565b8255505050565b612a12838383612171565b505050565b612a228383836121da565b505050565b612a318282612328565b5050565b612a3e8261215f565b612a51612a4a8261259b565b8354612950565b8255505050565b8115612a6757612a6661249a565b5b612a71838261236e565b505050565b612a7f8361215f565b612a93612a8b8261259b565b848454612992565b825550505050565b612aa48161202e565b8114612aaf57600080fd5b50565b612abb8161206c565b8114612ac657600080fd5b50565b60009056fea26469706673582212204ecb8996bb39773559c74839e823c3312f16000e008595f44afba65328f7cb2464736f6c63430008040033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101165760003560e01c80638129fc1c116100a2578063a5ad8ac611610071578063a5ad8ac6146102bb578063afc26911146102d7578063b724de3a146102f5578063ded8896b14610325578063f2fde38b1461034157610116565b80638129fc1c1461025957806382b7b500146102635780638456cb59146102935780638da5cb5b1461029d57610116565b80635893253c116100e95780635893253c146101a15780635c975abb146101d1578063715018a6146101ef578063788243d5146101f9578063810a9afa1461022957610116565b8063144ae8551461011b5780633f4ba83a146101375780634f896d4f14610141578063587a8cbf14610171575b600080fd5b6101356004803603810190610130919061146f565b61035d565b005b61013f6103c5565b005b61015b600480360381019061015691906113ee565b6103df565b60405161016891906119dc565b60405180910390f35b61018b600480360381019061018691906113ad565b610484565b6040516101989190611b40565b60405180910390f35b6101bb60048036038101906101b691906113ee565b6104b2565b6040516101c891906119dc565b60405180910390f35b6101d9610552565b6040516101e691906119a6565b60405180910390f35b6101f7610569565b005b610213600480360381019061020e91906113ee565b61057d565b604051610220919061198b565b60405180910390f35b610243600480360381019061023e91906113ee565b6105bb565b6040516102509190611b1e565b60405180910390f35b610261610739565b005b61027d60048036038101906102789190611368565b610887565b60405161028a9190611b40565b60405180910390f35b61029b6108b2565b005b6102a56108cc565b6040516102b2919061198b565b60405180910390f35b6102d560048036038101906102d091906113ee565b6108f6565b005b6102df610910565b6040516102ec9190611b40565b60405180910390f35b61030f600480360381019061030a9190611368565b610916565b60405161031c9190611b40565b60405180910390f35b61033f600480360381019061033a9190611417565b610a33565b005b61035b6004803603810190610356919061133f565b610caa565b005b610365610d2e565b80609a600084815260200190815260200160002081816103859190612a27565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada82826040516103b9929190611b8d565b60405180910390a15050565b6103cd610d2e565b6103d5610dac565b6103dd610df5565b565b60606098600083815260200190815260200160002080546103ff906123b4565b80601f016020809104026020016040519081016040528092919081815260200182805461042b906123b4565b80156104785780601f1061044d57610100808354040283529160200191610478565b820191906000526020600020905b81548152906001019060200180831161045b57829003601f168201915b50505050509050919050565b6099818051602081018201805184825260208301602085012081835280955050505050506000915090505481565b609860205280600052604060002060009150905080546104d1906123b4565b80601f01602080910402602001604051908101604052809291908181526020018280546104fd906123b4565b801561054a5780601f1061051f5761010080835404028352916020019161054a565b820191906000526020600020905b81548152906001019060200180831161052d57829003601f168201915b505050505081565b6000606560009054906101000a900460ff16905090565b610571610d2e565b61057b6000610e58565b565b609a6020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b6105c3611175565b609a60008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b8282101561072a578382906000526020600020906002020160405180604001604052908160008201805461068f906123b4565b80601f01602080910402602001604051908101604052809291908181526020018280546106bb906123b4565b80156107085780601f106106dd57610100808354040283529160200191610708565b820191906000526020600020905b8154815290600101906020018083116106eb57829003601f168201915b505050505081526020016001820154815250508152602001906001019061065c565b50505050815250509050919050565b60008060019054906101000a900460ff1615905080801561076a5750600160008054906101000a900460ff1660ff16105b80610797575061077930610f1e565b1580156107965750600160008054906101000a900460ff1660ff16145b5b6107d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107cd90611a9e565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015610813576001600060016101000a81548160ff0219169083151502179055505b61081b610f41565b610823610f9a565b61082b610ff3565b80156108845760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498600160405161087b91906119c1565b60405180910390a15b50565b60006099838360405161089b929190611972565b908152602001604051809103902054905092915050565b6108ba610d2e565b6108c2611056565b6108ca610ff3565b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6108fe610d2e565b610906610dac565b8060978190555050565b60975481565b6000828260006099838360405161092e929190611972565b9081526020016040518091039020541461097d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097490611a7e565b60405180910390fd5b610985611056565b6000609754905085856098600084815260200190815260200160002091906109ae9291906111a5565b5080609987876040516109c2929190611972565b9081526020016040518091039020819055507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d818787604051610a0793929190611b5b565b60405180910390a160976000815480929190610a2290612433565b919050555080935050505092915050565b8181600060998383604051610a49929190611972565b90815260200160405180910390205414610a98576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a8f90611a7e565b60405180910390fd5b610aa0611056565b6000609860008781526020019081526020016000208054610ac0906123b4565b90501480610b005750610ad16108cc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610b3f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b3690611a1e565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16609a600087815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161480610be15750610bb26108cc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610c20576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1790611afe565b60405180910390fd5b8383609860008881526020019081526020016000209190610c429291906111a5565b508460998585604051610c56929190611972565b9081526020016040518091039020819055507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c858585604051610c9b93929190611b5b565b60405180910390a15050505050565b610cb2610d2e565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610d22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d1990611a3e565b60405180910390fd5b610d2b81610e58565b50565b610d366110a0565b73ffffffffffffffffffffffffffffffffffffffff16610d546108cc565b73ffffffffffffffffffffffffffffffffffffffff1614610daa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610da190611abe565b60405180910390fd5b565b610db4610552565b610df3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dea906119fe565b60405180910390fd5b565b610dfd610dac565b6000606560006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610e416110a0565b604051610e4e919061198b565b60405180910390a1565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610f90576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8790611ade565b60405180910390fd5b610f986110a8565b565b600060019054906101000a900460ff16610fe9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fe090611ade565b60405180910390fd5b610ff1611109565b565b610ffb611056565b6001606560006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861103f6110a0565b60405161104c919061198b565b60405180910390a1565b61105e610552565b1561109e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161109590611a5e565b60405180910390fd5b565b600033905090565b600060019054906101000a900460ff166110f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110ee90611ade565b60405180910390fd5b6111076111026110a0565b610e58565b565b600060019054906101000a900460ff16611158576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161114f90611ade565b60405180910390fd5b6000606560006101000a81548160ff021916908315150217905550565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b8280546111b1906123b4565b90600052602060002090601f0160209004810192826111d3576000855561121a565b82601f106111ec57803560ff191683800117855561121a565b8280016001018555821561121a579182015b828111156112195782358255916020019190600101906111fe565b5b509050611227919061122b565b5090565b5b8082111561124457600081600090555060010161122c565b5090565b600061125b61125684611cb4565b611c8f565b90508281526020810184848401111561127357600080fd5b61127e8482856122e6565b509392505050565b60008135905061129581612a9b565b92915050565b60008083601f8401126112ad57600080fd5b8235905067ffffffffffffffff8111156112c657600080fd5b6020830191508360018202830111156112de57600080fd5b9250929050565b600082601f8301126112f657600080fd5b8135611306848260208601611248565b91505092915050565b60006040828403121561132157600080fd5b81905092915050565b60008135905061133981612ab2565b92915050565b60006020828403121561135157600080fd5b600061135f84828501611286565b91505092915050565b6000806020838503121561137b57600080fd5b600083013567ffffffffffffffff81111561139557600080fd5b6113a18582860161129b565b92509250509250929050565b6000602082840312156113bf57600080fd5b600082013567ffffffffffffffff8111156113d957600080fd5b6113e5848285016112e5565b91505092915050565b60006020828403121561140057600080fd5b600061140e8482850161132a565b91505092915050565b60008060006040848603121561142c57600080fd5b600061143a8682870161132a565b935050602084013567ffffffffffffffff81111561145757600080fd5b6114638682870161129b565b92509250509250925092565b6000806040838503121561148257600080fd5b60006114908582860161132a565b925050602083013567ffffffffffffffff8111156114ad57600080fd5b6114b98582860161130f565b9150509250929050565b60006114cf83836118c8565b905092915050565b60006114e38383611917565b905092915050565b6114f48161202e565b82525050565b6115038161202e565b82525050565b60006115158385611d91565b93508360208402850161152784611cfc565b8060005b8781101561156b5784840389526115428284611f99565b61154c85826114c3565b945061155783611d77565b925060208a0199505060018101905061152b565b50829750879450505050509392505050565b600061158882611d4b565b6115928185611d91565b9350836020820285016115a485611d06565b8060005b858110156115e057848403895281516115c185826114d7565b94506115cc83611d84565b925060208a019950506001810190506115a8565b50829750879550505050505092915050565b6115fb81612040565b82525050565b61160a81612129565b82525050565b600061161c8385611da2565b93506116298385846122e6565b6116328361268a565b840190509392505050565b60006116498385611db3565b93506116568385846122e6565b61165f8361268a565b840190509392505050565b60006116768385611dc4565b93506116838385846122e6565b82840190509392505050565b600061169a82611d6c565b6116a48185611da2565b93506116b48185602086016122f5565b6116bd8161268a565b840191505092915050565b60006116d382611d6c565b6116dd8185611db3565b93506116ed8185602086016122f5565b6116f68161268a565b840191505092915050565b600061170e601483611db3565b915061171982612716565b602082019050919050565b6000611731601583611db3565b915061173c8261273f565b602082019050919050565b6000611754602683611db3565b915061175f82612768565b604082019050919050565b6000611777601083611db3565b9150611782826127b7565b602082019050919050565b600061179a601983611db3565b91506117a5826127e0565b602082019050919050565b60006117bd602e83611db3565b91506117c882612809565b604082019050919050565b60006117e0602083611db3565b91506117eb82612858565b602082019050919050565b6000611803602b83611db3565b915061180e82612881565b604082019050919050565b6000611826601983611db3565b9150611831826128d0565b602082019050919050565b60006040830161184f6000840184611ed4565b61185c60008601826114eb565b5061186a6020840184611eeb565b858303602087015261187d838284611509565b925050508091505092915050565b60006040830160008301516118a360008601826114eb565b50602083015184820360208601526118bb828261157d565b9150508091505092915050565b6000604083016118db6000840184611f42565b85830360008701526118ee838284611610565b925050506118ff6020840184611fbd565b61190c6020860182611954565b508091505092915050565b60006040830160008301518482036000860152611934828261168f565b91505060208301516119496020860182611954565b508091505092915050565b61195d8161206c565b82525050565b61196c8161206c565b82525050565b600061197f82848661166a565b91508190509392505050565b60006020820190506119a060008301846114fa565b92915050565b60006020820190506119bb60008301846115f2565b92915050565b60006020820190506119d66000830184611601565b92915050565b600060208201905081810360008301526119f681846116c8565b905092915050565b60006020820190508181036000830152611a1781611701565b9050919050565b60006020820190508181036000830152611a3781611724565b9050919050565b60006020820190508181036000830152611a5781611747565b9050919050565b60006020820190508181036000830152611a778161176a565b9050919050565b60006020820190508181036000830152611a978161178d565b9050919050565b60006020820190508181036000830152611ab7816117b0565b9050919050565b60006020820190508181036000830152611ad7816117d3565b9050919050565b60006020820190508181036000830152611af7816117f6565b9050919050565b60006020820190508181036000830152611b1781611819565b9050919050565b60006020820190508181036000830152611b38818461188b565b905092915050565b6000602082019050611b556000830184611963565b92915050565b6000604082019050611b706000830186611963565b8181036020830152611b8381848661163d565b9050949350505050565b6000604082019050611ba26000830185611963565b8181036020830152611bb4818461183c565b90509392505050565b60008083356001602003843603038112611bd657600080fd5b80840192508235915067ffffffffffffffff821115611bf457600080fd5b602083019250602082023603831315611c0c57600080fd5b509250929050565b60008083356001602003843603038112611c2d57600080fd5b80840192508235915067ffffffffffffffff821115611c4b57600080fd5b602083019250600182023603831315611c6357600080fd5b509250929050565b600082356001604003833603038112611c8357600080fd5b80830191505092915050565b6000611c99611caa565b9050611ca58282612402565b919050565b6000604051905090565b600067ffffffffffffffff821115611ccf57611cce612527565b5b611cd88261268a565b9050602081019050919050565b6000819050611cf5826002611fd4565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6020841060008114611e2857601f841160018114611df857611df186856123e6565b8355611e22565b611e0183611d2b565b611e166020601f880104820160018301612091565b611e2087856128f9565b505b50611e71565b611e3182611d2b565b6020601f8701048101601f87168015611e5257611e518160018403612556565b5b611e646020601f890104840183612091565b6001886002021785555050505b5050505050565b6020831060008114611ec3576020851060008114611ea157611e9a86856123e6565b8355611ebd565b8360ff1916935083611eb284611d2b565b556001866002020183555b50611ecd565b6001856002020182555b5050505050565b6000611ee36020840184611286565b905092915050565b60008083356001602003843603038112611f0457600080fd5b83810192508235915060208301925067ffffffffffffffff821115611f2857600080fd5b602082023603841315611f3a57600080fd5b509250929050565b60008083356001602003843603038112611f5b57600080fd5b83810192508235915060208301925067ffffffffffffffff821115611f7f57600080fd5b600182023603841315611f9157600080fd5b509250929050565b600082356001604003833603038112611fb157600080fd5b82810191505092915050565b6000611fcc602084018461132a565b905092915050565b6000611fdf8261206c565b9150611fea8361206c565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612023576120226124c9565b5b828202905092915050565b60006120398261204c565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b61208e600082612635565b50565b5b818110156120b0576120a56000826126fe565b600181019050612092565b5050565b5b818110156120d3576120c86000826126e0565b6002810190506120b5565b5050565b818110156120f5576120ea6000826126fe565b6001810190506120d7565b5050565b61210660008083016126c2565b6121146000600183016126fe565b50565b60006121228261213b565b9050919050565b600061213482612076565b9050919050565b60006121468261214d565b9050919050565b60006121588261204c565b9050919050565b600061216a8261206c565b9050919050565b61217b8383611d40565b61218581836125d1565b61218e83611cfc565b61219783611d16565b6000805b848110156121d0576121ad8488611c6b565b6121b8818486612a58565b6020850194506002840193505060018101905061219b565b5050505050505050565b6121e48383611d61565b67ffffffffffffffff8111156121fd576121fc612527565b5b61220782546123b4565b600080601f8411601f841117156122245761222185611d2b565b90505b601f831115612257576020601f85010481016020851015612243578190505b6122556020601f860104830182612091565b505b601f8411600181146122845760008515612272578388013590505b61227c86826123e6565b8755506122dc565b601f1985168260005b828110156122b257858a0135825560018201915060208601955060208101905061228d565b878310156122cf57858a01356122cb601f8a168261247c565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b838110156123135780820151818401526020810190506122f8565b83811115612322576000848401525b50505050565b60008101600083018061233a816125a5565b905061234681846129e4565b505050600181016020830161235b8185611bbd565b612366818386612a07565b505050505050565b60008101600083016123808185611c14565b61238b818386612a17565b505050506001810160208301806123a1816125bb565b90506123ad8184612a35565b5050505050565b600060028204905060018216806123cc57607f821691505b602082108114156123e0576123df6124f8565b5b50919050565b60006123f2838361247c565b9150826002028217905092915050565b61240b8261268a565b810181811067ffffffffffffffff8211171561242a57612429612527565b5b80604052505050565b600061243e8261206c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612471576124706124c9565b5b600182019050919050565b600061248d600019846008026126b5565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6125867fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff836020036008026126b5565b815481168255505050565b6000819050919050565b6000819050919050565b600081356125b281612a9b565b80915050919050565b600081356125c881612ab2565b80915050919050565b680100000000000000008211156125eb576125ea612527565b5b6125f481611d56565b828255808310156126305761260881611ce5565b61261184611ce5565b61261a84611d16565b81810183820161262a81836120b4565b50505050505b505050565b6801000000000000000082111561264f5761264e612527565b5b805461265a816123b4565b8084111561266f5761266e84828486611e78565b5b808410156126845761268384828486611dcf565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b600082146126d3576126d261249a565b5b6126dc81612083565b5050565b600082146126f1576126f061249a565b5b6126fa816120f9565b5050565b612706612ac9565b612711818484612a76565b505050565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b7f73747265616d20616c7265616479206861732061206450494400000000000000600082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b61290281611d2b565b61290d8382546123e6565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff61293a8461269b565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61297c8461269b565b9350801983169250808416831791505092915050565b6000600883026129c27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826126a8565b6129cc86836126a8565b95508019841693508086168417925050509392505050565b6129ed82612117565b612a006129f982612591565b835461291a565b8255505050565b612a12838383612171565b505050565b612a228383836121da565b505050565b612a318282612328565b5050565b612a3e8261215f565b612a51612a4a8261259b565b8354612950565b8255505050565b8115612a6757612a6661249a565b5b612a71838261236e565b505050565b612a7f8361215f565b612a93612a8b8261259b565b848454612992565b825550505050565b612aa48161202e565b8114612aaf57600080fd5b50565b612abb8161206c565b8114612ac657600080fd5b50565b60009056fea26469706673582212204ecb8996bb39773559c74839e823c3312f16000e008595f44afba65328f7cb2464736f6c63430008040033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/desci-contracts/contracts/DpidAliasRegistry.sol b/desci-contracts/contracts/DpidAliasRegistry.sol index fc9aa2ff..bea07ed2 100644 --- a/desci-contracts/contracts/DpidAliasRegistry.sol +++ b/desci-contracts/contracts/DpidAliasRegistry.sol @@ -9,13 +9,10 @@ contract DpidAliasRegistry is Initializable, OwnableUpgradeable, PausableUpgrade // Incremented on each dPID mint uint256 public nextDpid; - // When this is set to true, further edits of the legacy entries are blocked - bool public migrationFrozen; - // dpid => codex streamID (resolve dPID) mapping(uint256 => string) public registry; - // codex streamID => dpid (check for existing aliases) + // codex streamID => dpid (check for existing alias) mapping(string => uint256) public reverseRegistry; /// @custom:oz-upgrades-unsafe-allow constructor @@ -162,6 +159,14 @@ contract DpidAliasRegistry is Initializable, OwnableUpgradeable, PausableUpgrade * which is why the legacy entires are kept to ensure continued deterministic * resolution of versions as they were originally created. * + * Contract owner can bypass these two limitations, allowing both mending of + * incorrect upgrades and automating upgrades for legacy dPID holders. + * Associated quirk: when re-upgrading a dPID, the overwritten streamID will + * still be present in the reverse mapping, preventing it to be assigned a dPID. + * This stream is assumed to regardlessly be incorrect, because a re-upgrade + * was chosen. + * + * * @param dpid the dPID to upgrade * @param streamId the stream representing that same dPID */ @@ -169,11 +174,19 @@ contract DpidAliasRegistry is Initializable, OwnableUpgradeable, PausableUpgrade uint256 dpid, string calldata streamId ) public onlyUnaliasedStream(streamId) whenNotPaused { - // Assert that this dPID has not been set in the main registry - require(bytes(registry[dpid]).length == 0, "dpid already upgraded"); - - // Assert that the tx was made by the owner of the imported entry - require(legacy[dpid].owner == msg.sender, "unauthorized dpid upgrade"); + // Assert that this dPID has not been set in the main registry. + // Allow contract owner bypass to fix broken upgrades. + require( + bytes(registry[dpid]).length == 0 || msg.sender == owner(), + "dpid already upgraded" + ); + + // Assert that the tx was made by the owner of the imported entry. + // Allow contract owner bypass to automate upgrades. + require( + legacy[dpid].owner == msg.sender || msg.sender == owner(), + "unauthorized dpid upgrade" + ); // Reclaim old dpid registry[dpid] = streamId; @@ -211,21 +224,10 @@ contract DpidAliasRegistry is Initializable, OwnableUpgradeable, PausableUpgrade uint256 dpid, LegacyDpidEntry calldata entry ) public onlyOwner { - require(migrationFrozen == false, "migration is frozen"); legacy[dpid] = entry; emit ImportedDpid(dpid, entry); } - /** - * This permanently blocks importing/overwriting legacy dPID entries, - * effectively freezing history. - * - * Note: this is irreversible - */ - function freezeMigration() public onlyOwner { - migrationFrozen = true; - } - /** * When the contract is paused, the owner can correct the next dPID. * This is useful for making a seamless switch between new and old diff --git a/desci-contracts/hardhat.config.ts b/desci-contracts/hardhat.config.ts index 0bbe69f0..393ef0e5 100644 --- a/desci-contracts/hardhat.config.ts +++ b/desci-contracts/hardhat.config.ts @@ -41,13 +41,6 @@ module.exports = { mnemonic: process.env.MNEMONIC || DEFAULT_MNEMONIC, }, }, - optimism: { - url: "http://127.0.0.1:8545", - chainId: 17, - accounts: { - mnemonic: process.env.MNEMONIC || DEFAULT_MNEMONIC, - }, - }, ganache: { chainId: 1337, saveDeployments: true, @@ -104,6 +97,30 @@ module.exports = { }, gasPrice: "auto", }, + optimism: { + chainId: 10, + live: true, + saveDeployments: true, + url: "https://reverse-proxy-dev.desci.com/rpc_opt_mainnet", + accounts: process.env.PRIVATE_KEY + ? [ process.env.PRIVATE_KEY ] + : { + mnemonic: process.env.MNEMONIC || DEFAULT_MNEMONIC, + }, + gasPrice: "auto", + }, + optimismSepolia: { + chainId: 11155420, + live: true, + saveDeployments: true, + url: "https://opt-sepolia.g.alchemy.com/v2/vr-m5h17EAZPdtt88rpvkMy8kwo1-iig", //https://reverse-proxy-dev.desci.com/rpc_opt_sepolia", + accounts: process.env.PRIVATE_KEY + ? [ process.env.PRIVATE_KEY ] + : { + mnemonic: process.env.MNEMONIC || DEFAULT_MNEMONIC, + }, + gasPrice: "auto", + }, }, react: { providers: ["hardhat", "web3modal"], diff --git a/desci-contracts/migration-data/aliasRegistry_dev__Mon,_03_Jun_2024_11:21:28_GMT.json b/desci-contracts/migration-data/aliasRegistry_dev_Wed,_12_Jun_2024_13:23:15_GMT.json similarity index 99% rename from desci-contracts/migration-data/aliasRegistry_dev__Mon,_03_Jun_2024_11:21:28_GMT.json rename to desci-contracts/migration-data/aliasRegistry_dev_Wed,_12_Jun_2024_13:23:15_GMT.json index bfec26fc..33a9c0d2 100644 --- a/desci-contracts/migration-data/aliasRegistry_dev__Mon,_03_Jun_2024_11:21:28_GMT.json +++ b/desci-contracts/migration-data/aliasRegistry_dev_Wed,_12_Jun_2024_13:23:15_GMT.json @@ -1,5 +1,5 @@ { - "address": "0x7906AC53C2F59d0Eb36dC126336322d25Da15B62", + "address": "0x2Ea4Ee2Af79495e045EBe925aC67d755520877e7", "dpids": [ { "dpid": "0", @@ -4873,6 +4873,32 @@ } ], "validationError": false + }, + { + "dpid": "247", + "owner": "0x371e269bff1aaA342b43b74Cf1Ad9789BaF183F7", + "versions": [ + { + "cid": "bafkreiakdqljwmvvzkmwjrgkto4meyyghrl3tigocnoapejdquuiigy2si", + "time": 1718012544 + }, + { + "cid": "bafkreiehku747l4loyvugbfby55tig4qjgyj66ujbcpuohucktx6dg72k4", + "time": 1718015760 + } + ], + "validationError": false + }, + { + "dpid": "248", + "owner": "0x371e269bff1aaA342b43b74Cf1Ad9789BaF183F7", + "versions": [ + { + "cid": "bafkreic65zfq5ryxtmxtei3264qafrmcdyysxnmxl2krldoaitrjymogta", + "time": 1718017368 + } + ], + "validationError": false } ] } \ No newline at end of file diff --git a/desci-contracts/package.json b/desci-contracts/package.json index ed04dd72..f4c99c90 100644 --- a/desci-contracts/package.json +++ b/desci-contracts/package.json @@ -1,7 +1,7 @@ { "name": "@desci-labs/desci-contracts", "description": "Smart contracts implementing DeSci Nodes on-chain state and logic", - "version": "0.2.5-rc5", + "version": "0.2.5-rc6", "license": "MIT", "scripts": { "test": "hardhat clean && hardhat test", @@ -11,7 +11,7 @@ "docker:push": "docker tag desci-hardhat-node:latest 523044037273.dkr.ecr.us-east-2.amazonaws.com/desci-hardhat-node:latest && docker push 523044037273.dkr.ecr.us-east-2.amazonaws.com/desci-hardhat-node:latest", "deploy:ganache": "yarn stubHardhatAnalytics && hardhat run scripts/deployResearchObject.js --network ganache", "deploy:dpid:ganache": "yarn stubHardhatAnalytics && hardhat run scripts/deployDpidRegistry.js --network ganache", - "deploy:alias:ganache": "yarn stubHardhatAnalytics && export FIRST_DPID=500 && hardhat run scripts/deployDpidAliasRegistry.js --network ganache", + "deploy:alias:ganache": "yarn stubHardhatAnalytics && export FIRST_DPID=500 && hardhat run scripts/alias-registry/deployDpidAliasRegistry.js --network ganache", "migrate": "hardhat run scripts/migrateToNewContract.js --network ganache && touch ./.openzeppelin/migration-complete.json", "graph:codegen": "graph codegen subgraph/subgraph.yaml -o subgraph/generated", "graph:build": "graph build subgraph/subgraph.yaml", diff --git a/desci-contracts/scripts/deployDpidAliasRegistry.js b/desci-contracts/scripts/alias-registry/deployDpidAliasRegistry.js similarity index 100% rename from desci-contracts/scripts/deployDpidAliasRegistry.js rename to desci-contracts/scripts/alias-registry/deployDpidAliasRegistry.js diff --git a/desci-contracts/scripts/migrateToAliasRegistry.mjs b/desci-contracts/scripts/alias-registry/migrateToAliasRegistry.mjs similarity index 100% rename from desci-contracts/scripts/migrateToAliasRegistry.mjs rename to desci-contracts/scripts/alias-registry/migrateToAliasRegistry.mjs diff --git a/desci-contracts/scripts/syncAliasRegistryMigration.mjs b/desci-contracts/scripts/alias-registry/syncAliasRegistryMigration.mjs similarity index 100% rename from desci-contracts/scripts/syncAliasRegistryMigration.mjs rename to desci-contracts/scripts/alias-registry/syncAliasRegistryMigration.mjs diff --git a/desci-contracts/test/DpidAliasRegistry.ts b/desci-contracts/test/DpidAliasRegistry.ts index 737e7be9..74681d9c 100644 --- a/desci-contracts/test/DpidAliasRegistry.ts +++ b/desci-contracts/test/DpidAliasRegistry.ts @@ -206,8 +206,9 @@ describe("dPID", () => { describe("upgrade", () => { let successReceipt: ContractReceipt; const STREAM_C = "kjzl6kcym7w8y7i5ugaq9a3vlm7hhuaf4bpl5o5qykeh4qtsa12c6rb5ekw6ccc"; + const STREAM_D = "kjzl6kcym7w8y7i5ugaq9a3vlm7hhuaf4bpl5o5qykeh4qtsa12c6rb5ekw6ddd"; - it("can NOT be done by others", async () => { + it("can NOT be done by randos", async () => { const doUpgrade = async () => await dpidAliasRegistry .connect(user2) .upgradeDpid(0, STREAM_C); @@ -215,14 +216,6 @@ describe("dPID", () => { await expect(doUpgrade()).to.be.rejectedWith("unauthorized dpid upgrade"); }); - it("can NOT be done by contract owner", async () => { - const doUpgrade = async () => await dpidAliasRegistry - .connect(deployerAddress) - .upgradeDpid(0, STREAM_C); - - await expect(doUpgrade()).to.be.rejectedWith("unauthorized dpid upgrade"); - }); - it("can be done by dpid owner", async () => { const tx = await dpidAliasRegistry.upgradeDpid(0, STREAM_C); successReceipt = await tx.wait(); @@ -238,6 +231,14 @@ describe("dPID", () => { await expect(doSecondUpgrade()).to.be.rejectedWith("dpid already upgraded"); }); + it("can be fixed by contract owner", async () => { + const doUpgrade = async () => await dpidAliasRegistry + .connect(deployerAddress) + .upgradeDpid(0, STREAM_C); + + await expect(doUpgrade()).to.not.be.rejectedWith("unauthorized dpid upgrade"); + }); + it("emits an event", async () => { const event = successReceipt.events![0]; const [ dpid, streamId ] = event.args!; diff --git a/desci-contracts/typechain-types/DpidAliasRegistry.ts b/desci-contracts/typechain-types/DpidAliasRegistry.ts index 7c100924..0bb0599a 100644 --- a/desci-contracts/typechain-types/DpidAliasRegistry.ts +++ b/desci-contracts/typechain-types/DpidAliasRegistry.ts @@ -43,12 +43,10 @@ export interface DpidAliasRegistryInterface extends utils.Interface { contractName: "DpidAliasRegistry"; functions: { "find(string)": FunctionFragment; - "freezeMigration()": FunctionFragment; "importLegacyDpid(uint256,(address,(string,uint256)[]))": FunctionFragment; "initialize()": FunctionFragment; "legacy(uint256)": FunctionFragment; "legacyLookup(uint256)": FunctionFragment; - "migrationFrozen()": FunctionFragment; "mintDpid(string)": FunctionFragment; "nextDpid()": FunctionFragment; "owner()": FunctionFragment; @@ -65,10 +63,6 @@ export interface DpidAliasRegistryInterface extends utils.Interface { }; encodeFunctionData(functionFragment: "find", values: [string]): string; - encodeFunctionData( - functionFragment: "freezeMigration", - values?: undefined - ): string; encodeFunctionData( functionFragment: "importLegacyDpid", values: [BigNumberish, DpidAliasRegistry.LegacyDpidEntryStruct] @@ -85,10 +79,6 @@ export interface DpidAliasRegistryInterface extends utils.Interface { functionFragment: "legacyLookup", values: [BigNumberish] ): string; - encodeFunctionData( - functionFragment: "migrationFrozen", - values?: undefined - ): string; encodeFunctionData(functionFragment: "mintDpid", values: [string]): string; encodeFunctionData(functionFragment: "nextDpid", values?: undefined): string; encodeFunctionData(functionFragment: "owner", values?: undefined): string; @@ -125,10 +115,6 @@ export interface DpidAliasRegistryInterface extends utils.Interface { ): string; decodeFunctionResult(functionFragment: "find", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "freezeMigration", - data: BytesLike - ): Result; decodeFunctionResult( functionFragment: "importLegacyDpid", data: BytesLike @@ -139,10 +125,6 @@ export interface DpidAliasRegistryInterface extends utils.Interface { functionFragment: "legacyLookup", data: BytesLike ): Result; - decodeFunctionResult( - functionFragment: "migrationFrozen", - data: BytesLike - ): Result; decodeFunctionResult(functionFragment: "mintDpid", data: BytesLike): Result; decodeFunctionResult(functionFragment: "nextDpid", data: BytesLike): Result; decodeFunctionResult(functionFragment: "owner", data: BytesLike): Result; @@ -262,10 +244,6 @@ export interface DpidAliasRegistry extends BaseContract { functions: { find(streamId: string, overrides?: CallOverrides): Promise<[BigNumber]>; - freezeMigration( - overrides?: Overrides & { from?: string | Promise } - ): Promise; - importLegacyDpid( dpid: BigNumberish, entry: DpidAliasRegistry.LegacyDpidEntryStruct, @@ -286,8 +264,6 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: CallOverrides ): Promise<[DpidAliasRegistry.LegacyDpidEntryStructOutput]>; - migrationFrozen(overrides?: CallOverrides): Promise<[boolean]>; - mintDpid( streamId: string, overrides?: Overrides & { from?: string | Promise } @@ -339,10 +315,6 @@ export interface DpidAliasRegistry extends BaseContract { find(streamId: string, overrides?: CallOverrides): Promise; - freezeMigration( - overrides?: Overrides & { from?: string | Promise } - ): Promise; - importLegacyDpid( dpid: BigNumberish, entry: DpidAliasRegistry.LegacyDpidEntryStruct, @@ -360,8 +332,6 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: CallOverrides ): Promise; - migrationFrozen(overrides?: CallOverrides): Promise; - mintDpid( streamId: string, overrides?: Overrides & { from?: string | Promise } @@ -410,8 +380,6 @@ export interface DpidAliasRegistry extends BaseContract { callStatic: { find(streamId: string, overrides?: CallOverrides): Promise; - freezeMigration(overrides?: CallOverrides): Promise; - importLegacyDpid( dpid: BigNumberish, entry: DpidAliasRegistry.LegacyDpidEntryStruct, @@ -427,8 +395,6 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: CallOverrides ): Promise; - migrationFrozen(overrides?: CallOverrides): Promise; - mintDpid(streamId: string, overrides?: CallOverrides): Promise; nextDpid(overrides?: CallOverrides): Promise; @@ -510,10 +476,6 @@ export interface DpidAliasRegistry extends BaseContract { estimateGas: { find(streamId: string, overrides?: CallOverrides): Promise; - freezeMigration( - overrides?: Overrides & { from?: string | Promise } - ): Promise; - importLegacyDpid( dpid: BigNumberish, entry: DpidAliasRegistry.LegacyDpidEntryStruct, @@ -531,8 +493,6 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: CallOverrides ): Promise; - migrationFrozen(overrides?: CallOverrides): Promise; - mintDpid( streamId: string, overrides?: Overrides & { from?: string | Promise } @@ -588,10 +548,6 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: CallOverrides ): Promise; - freezeMigration( - overrides?: Overrides & { from?: string | Promise } - ): Promise; - importLegacyDpid( dpid: BigNumberish, entry: DpidAliasRegistry.LegacyDpidEntryStruct, @@ -612,8 +568,6 @@ export interface DpidAliasRegistry extends BaseContract { overrides?: CallOverrides ): Promise; - migrationFrozen(overrides?: CallOverrides): Promise; - mintDpid( streamId: string, overrides?: Overrides & { from?: string | Promise } diff --git a/desci-contracts/typechain-types/factories/DpidAliasRegistry__factory.ts b/desci-contracts/typechain-types/factories/DpidAliasRegistry__factory.ts index a3f5dca0..00181c90 100644 --- a/desci-contracts/typechain-types/factories/DpidAliasRegistry__factory.ts +++ b/desci-contracts/typechain-types/factories/DpidAliasRegistry__factory.ts @@ -172,13 +172,6 @@ const _abi = [ stateMutability: "view", type: "function", }, - { - inputs: [], - name: "freezeMigration", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, { inputs: [ { @@ -290,19 +283,6 @@ const _abi = [ stateMutability: "view", type: "function", }, - { - inputs: [], - name: "migrationFrozen", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool", - }, - ], - stateMutability: "view", - type: "function", - }, { inputs: [ { @@ -486,7 +466,7 @@ const _abi = [ ]; const _bytecode = - "0x60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d3565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000127565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff161015620000ed5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e4919062000149565b60405180910390a15b565b6000620000fe60278362000166565b91506200010b8262000184565b604082019050919050565b620001218162000177565b82525050565b600060208201905081810360008301526200014281620000ef565b9050919050565b600060208201905062000160600083018462000116565b92915050565b600082825260208201905092915050565b600060ff82169050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b612bc280620001e36000396000f3fe608060405234801561001057600080fd5b506004361061012c5760003560e01c80638129fc1c116100ad578063afc2691111610071578063afc26911146102f7578063b724de3a14610315578063b9e2924114610345578063ded8896b14610363578063f2fde38b1461037f5761012c565b80638129fc1c1461027957806382b7b500146102835780638456cb59146102b35780638da5cb5b146102bd578063a5ad8ac6146102db5761012c565b80635893253c116100f45780635893253c146101c15780635c975abb146101f1578063715018a61461020f578063788243d514610219578063810a9afa146102495761012c565b80630d70b3aa14610131578063144ae8551461013b5780633f4ba83a146101575780634f896d4f14610161578063587a8cbf14610191575b600080fd5b61013961039b565b005b610155600480360381019061015091906114c1565b6103c0565b005b61015f61047e565b005b61017b60048036038101906101769190611440565b610498565b6040516101889190611a51565b60405180910390f35b6101ab60048036038101906101a691906113ff565b61053d565b6040516101b89190611bd5565b60405180910390f35b6101db60048036038101906101d69190611440565b61056b565b6040516101e89190611a51565b60405180910390f35b6101f961060b565b6040516102069190611a1b565b60405180910390f35b610217610622565b005b610233600480360381019061022e9190611440565b610636565b6040516102409190611a00565b60405180910390f35b610263600480360381019061025e9190611440565b610674565b6040516102709190611bb3565b60405180910390f35b6102816107f2565b005b61029d600480360381019061029891906113ba565b610940565b6040516102aa9190611bd5565b60405180910390f35b6102bb61096b565b005b6102c5610985565b6040516102d29190611a00565b60405180910390f35b6102f560048036038101906102f09190611440565b6109af565b005b6102ff6109c9565b60405161030c9190611bd5565b60405180910390f35b61032f600480360381019061032a91906113ba565b6109cf565b60405161033c9190611bd5565b60405180910390f35b61034d610aec565b60405161035a9190611a1b565b60405180910390f35b61037d60048036038101906103789190611469565b610aff565b005b61039960048036038101906103949190611391565b610cfc565b005b6103a3610d80565b6001609860006101000a81548160ff021916908315150217905550565b6103c8610d80565b60001515609860009054906101000a900460ff1615151461041e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041590611ad3565b60405180910390fd5b80609b6000848152602001908152602001600020818161043e9190612ae5565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada8282604051610472929190611c22565b60405180910390a15050565b610486610d80565b61048e610dfe565b610496610e47565b565b60606099600083815260200190815260200160002080546104b890612449565b80601f01602080910402602001604051908101604052809291908181526020018280546104e490612449565b80156105315780601f1061050657610100808354040283529160200191610531565b820191906000526020600020905b81548152906001019060200180831161051457829003601f168201915b50505050509050919050565b609a818051602081018201805184825260208301602085012081835280955050505050506000915090505481565b6099602052806000526040600020600091509050805461058a90612449565b80601f01602080910402602001604051908101604052809291908181526020018280546105b690612449565b80156106035780601f106105d857610100808354040283529160200191610603565b820191906000526020600020905b8154815290600101906020018083116105e657829003601f168201915b505050505081565b6000606560009054906101000a900460ff16905090565b61062a610d80565b6106346000610eaa565b565b609b6020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b61067c6111c7565b609b60008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b828210156107e3578382906000526020600020906002020160405180604001604052908160008201805461074890612449565b80601f016020809104026020016040519081016040528092919081815260200182805461077490612449565b80156107c15780601f10610796576101008083540402835291602001916107c1565b820191906000526020600020905b8154815290600101906020018083116107a457829003601f168201915b5050505050815260200160018201548152505081526020019060010190610715565b50505050815250509050919050565b60008060019054906101000a900460ff161590508080156108235750600160008054906101000a900460ff1660ff16105b80610850575061083230610f70565b15801561084f5750600160008054906101000a900460ff1660ff16145b5b61088f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161088690611b33565b60405180910390fd5b60016000806101000a81548160ff021916908360ff16021790555080156108cc576001600060016101000a81548160ff0219169083151502179055505b6108d4610f93565b6108dc610fec565b6108e4611045565b801561093d5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516109349190611a36565b60405180910390a15b50565b6000609a83836040516109549291906119e7565b908152602001604051809103902054905092915050565b610973610d80565b61097b6110a8565b610983611045565b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6109b7610d80565b6109bf610dfe565b8060978190555050565b60975481565b600082826000609a83836040516109e79291906119e7565b90815260200160405180910390205414610a36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a2d90611b13565b60405180910390fd5b610a3e6110a8565b600060975490508585609960008481526020019081526020016000209190610a679291906111f7565b5080609a8787604051610a7b9291906119e7565b9081526020016040518091039020819055507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d818787604051610ac093929190611bf0565b60405180910390a160976000815480929190610adb906124c8565b919050555080935050505092915050565b609860009054906101000a900460ff1681565b81816000609a8383604051610b159291906119e7565b90815260200160405180910390205414610b64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b5b90611b13565b60405180910390fd5b610b6c6110a8565b6000609960008781526020019081526020016000208054610b8c90612449565b905014610bce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bc590611a93565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16609b600087815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610c72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6990611b93565b60405180910390fd5b8383609960008881526020019081526020016000209190610c949291906111f7565b5084609a8585604051610ca89291906119e7565b9081526020016040518091039020819055507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c858585604051610ced93929190611bf0565b60405180910390a15050505050565b610d04610d80565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610d74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6b90611ab3565b60405180910390fd5b610d7d81610eaa565b50565b610d886110f2565b73ffffffffffffffffffffffffffffffffffffffff16610da6610985565b73ffffffffffffffffffffffffffffffffffffffff1614610dfc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610df390611b53565b60405180910390fd5b565b610e0661060b565b610e45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e3c90611a73565b60405180910390fd5b565b610e4f610dfe565b6000606560006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610e936110f2565b604051610ea09190611a00565b60405180910390a1565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610fe2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fd990611b73565b60405180910390fd5b610fea6110fa565b565b600060019054906101000a900460ff1661103b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103290611b73565b60405180910390fd5b61104361115b565b565b61104d6110a8565b6001606560006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586110916110f2565b60405161109e9190611a00565b60405180910390a1565b6110b061060b565b156110f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110e790611af3565b60405180910390fd5b565b600033905090565b600060019054906101000a900460ff16611149576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161114090611b73565b60405180910390fd5b6111596111546110f2565b610eaa565b565b600060019054906101000a900460ff166111aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111a190611b73565b60405180910390fd5b6000606560006101000a81548160ff021916908315150217905550565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b82805461120390612449565b90600052602060002090601f016020900481019282611225576000855561126c565b82601f1061123e57803560ff191683800117855561126c565b8280016001018555821561126c579182015b8281111561126b578235825591602001919060010190611250565b5b509050611279919061127d565b5090565b5b8082111561129657600081600090555060010161127e565b5090565b60006112ad6112a884611d49565b611d24565b9050828152602081018484840111156112c557600080fd5b6112d084828561237b565b509392505050565b6000813590506112e781612b59565b92915050565b60008083601f8401126112ff57600080fd5b8235905067ffffffffffffffff81111561131857600080fd5b60208301915083600182028301111561133057600080fd5b9250929050565b600082601f83011261134857600080fd5b813561135884826020860161129a565b91505092915050565b60006040828403121561137357600080fd5b81905092915050565b60008135905061138b81612b70565b92915050565b6000602082840312156113a357600080fd5b60006113b1848285016112d8565b91505092915050565b600080602083850312156113cd57600080fd5b600083013567ffffffffffffffff8111156113e757600080fd5b6113f3858286016112ed565b92509250509250929050565b60006020828403121561141157600080fd5b600082013567ffffffffffffffff81111561142b57600080fd5b61143784828501611337565b91505092915050565b60006020828403121561145257600080fd5b60006114608482850161137c565b91505092915050565b60008060006040848603121561147e57600080fd5b600061148c8682870161137c565b935050602084013567ffffffffffffffff8111156114a957600080fd5b6114b5868287016112ed565b92509250509250925092565b600080604083850312156114d457600080fd5b60006114e28582860161137c565b925050602083013567ffffffffffffffff8111156114ff57600080fd5b61150b85828601611361565b9150509250929050565b6000611521838361193d565b905092915050565b6000611535838361198c565b905092915050565b611546816120c3565b82525050565b611555816120c3565b82525050565b60006115678385611e26565b93508360208402850161157984611d91565b8060005b878110156115bd578484038952611594828461202e565b61159e8582611515565b94506115a983611e0c565b925060208a0199505060018101905061157d565b50829750879450505050509392505050565b60006115da82611de0565b6115e48185611e26565b9350836020820285016115f685611d9b565b8060005b8581101561163257848403895281516116138582611529565b945061161e83611e19565b925060208a019950506001810190506115fa565b50829750879550505050505092915050565b61164d816120d5565b82525050565b61165c816121be565b82525050565b600061166e8385611e37565b935061167b83858461237b565b6116848361271f565b840190509392505050565b600061169b8385611e48565b93506116a883858461237b565b6116b18361271f565b840190509392505050565b60006116c88385611e59565b93506116d583858461237b565b82840190509392505050565b60006116ec82611e01565b6116f68185611e37565b935061170681856020860161238a565b61170f8161271f565b840191505092915050565b600061172582611e01565b61172f8185611e48565b935061173f81856020860161238a565b6117488161271f565b840191505092915050565b6000611760601483611e48565b915061176b826127ab565b602082019050919050565b6000611783601583611e48565b915061178e826127d4565b602082019050919050565b60006117a6602683611e48565b91506117b1826127fd565b604082019050919050565b60006117c9601383611e48565b91506117d48261284c565b602082019050919050565b60006117ec601083611e48565b91506117f782612875565b602082019050919050565b600061180f601983611e48565b915061181a8261289e565b602082019050919050565b6000611832602e83611e48565b915061183d826128c7565b604082019050919050565b6000611855602083611e48565b915061186082612916565b602082019050919050565b6000611878602b83611e48565b91506118838261293f565b604082019050919050565b600061189b601983611e48565b91506118a68261298e565b602082019050919050565b6000604083016118c46000840184611f69565b6118d1600086018261153d565b506118df6020840184611f80565b85830360208701526118f283828461155b565b925050508091505092915050565b6000604083016000830151611918600086018261153d565b506020830151848203602086015261193082826115cf565b9150508091505092915050565b6000604083016119506000840184611fd7565b8583036000870152611963838284611662565b925050506119746020840184612052565b61198160208601826119c9565b508091505092915050565b600060408301600083015184820360008601526119a982826116e1565b91505060208301516119be60208601826119c9565b508091505092915050565b6119d281612101565b82525050565b6119e181612101565b82525050565b60006119f48284866116bc565b91508190509392505050565b6000602082019050611a15600083018461154c565b92915050565b6000602082019050611a306000830184611644565b92915050565b6000602082019050611a4b6000830184611653565b92915050565b60006020820190508181036000830152611a6b818461171a565b905092915050565b60006020820190508181036000830152611a8c81611753565b9050919050565b60006020820190508181036000830152611aac81611776565b9050919050565b60006020820190508181036000830152611acc81611799565b9050919050565b60006020820190508181036000830152611aec816117bc565b9050919050565b60006020820190508181036000830152611b0c816117df565b9050919050565b60006020820190508181036000830152611b2c81611802565b9050919050565b60006020820190508181036000830152611b4c81611825565b9050919050565b60006020820190508181036000830152611b6c81611848565b9050919050565b60006020820190508181036000830152611b8c8161186b565b9050919050565b60006020820190508181036000830152611bac8161188e565b9050919050565b60006020820190508181036000830152611bcd8184611900565b905092915050565b6000602082019050611bea60008301846119d8565b92915050565b6000604082019050611c0560008301866119d8565b8181036020830152611c1881848661168f565b9050949350505050565b6000604082019050611c3760008301856119d8565b8181036020830152611c4981846118b1565b90509392505050565b60008083356001602003843603038112611c6b57600080fd5b80840192508235915067ffffffffffffffff821115611c8957600080fd5b602083019250602082023603831315611ca157600080fd5b509250929050565b60008083356001602003843603038112611cc257600080fd5b80840192508235915067ffffffffffffffff821115611ce057600080fd5b602083019250600182023603831315611cf857600080fd5b509250929050565b600082356001604003833603038112611d1857600080fd5b80830191505092915050565b6000611d2e611d3f565b9050611d3a8282612497565b919050565b6000604051905090565b600067ffffffffffffffff821115611d6457611d636125bc565b5b611d6d8261271f565b9050602081019050919050565b6000819050611d8a826002612069565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6020841060008114611ebd57601f841160018114611e8d57611e86868561247b565b8355611eb7565b611e9683611dc0565b611eab6020601f880104820160018301612126565b611eb587856129b7565b505b50611f06565b611ec682611dc0565b6020601f8701048101601f87168015611ee757611ee681600184036125eb565b5b611ef96020601f890104840183612126565b6001886002021785555050505b5050505050565b6020831060008114611f58576020851060008114611f3657611f2f868561247b565b8355611f52565b8360ff1916935083611f4784611dc0565b556001866002020183555b50611f62565b6001856002020182555b5050505050565b6000611f7860208401846112d8565b905092915050565b60008083356001602003843603038112611f9957600080fd5b83810192508235915060208301925067ffffffffffffffff821115611fbd57600080fd5b602082023603841315611fcf57600080fd5b509250929050565b60008083356001602003843603038112611ff057600080fd5b83810192508235915060208301925067ffffffffffffffff82111561201457600080fd5b60018202360384131561202657600080fd5b509250929050565b60008235600160400383360303811261204657600080fd5b82810191505092915050565b6000612061602084018461137c565b905092915050565b600061207482612101565b915061207f83612101565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156120b8576120b761255e565b5b828202905092915050565b60006120ce826120e1565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b6121236000826126ca565b50565b5b818110156121455761213a600082612793565b600181019050612127565b5050565b5b818110156121685761215d600082612775565b60028101905061214a565b5050565b8181101561218a5761217f600082612793565b60018101905061216c565b5050565b61219b6000808301612757565b6121a9600060018301612793565b50565b60006121b7826121d0565b9050919050565b60006121c98261210b565b9050919050565b60006121db826121e2565b9050919050565b60006121ed826120e1565b9050919050565b60006121ff82612101565b9050919050565b6122108383611dd5565b61221a8183612666565b61222383611d91565b61222c83611dab565b6000805b84811015612265576122428488611d00565b61224d818486612b16565b60208501945060028401935050600181019050612230565b5050505050505050565b6122798383611df6565b67ffffffffffffffff811115612292576122916125bc565b5b61229c8254612449565b600080601f8411601f841117156122b9576122b685611dc0565b90505b601f8311156122ec576020601f850104810160208510156122d8578190505b6122ea6020601f860104830182612126565b505b601f8411600181146123195760008515612307578388013590505b612311868261247b565b875550612371565b601f1985168260005b8281101561234757858a01358255600182019150602086019550602081019050612322565b8783101561236457858a0135612360601f8a1682612511565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b838110156123a857808201518184015260208101905061238d565b838111156123b7576000848401525b50505050565b6000810160008301806123cf8161263a565b90506123db8184612aa2565b50505060018101602083016123f08185611c52565b6123fb818386612ac5565b505050505050565b60008101600083016124158185611ca9565b612420818386612ad5565b5050505060018101602083018061243681612650565b90506124428184612af3565b5050505050565b6000600282049050600182168061246157607f821691505b602082108114156124755761247461258d565b5b50919050565b60006124878383612511565b9150826002028217905092915050565b6124a08261271f565b810181811067ffffffffffffffff821117156124bf576124be6125bc565b5b80604052505050565b60006124d382612101565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156125065761250561255e565b5b600182019050919050565b60006125226000198460080261274a565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61261b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8360200360080261274a565b815481168255505050565b6000819050919050565b6000819050919050565b6000813561264781612b59565b80915050919050565b6000813561265d81612b70565b80915050919050565b680100000000000000008211156126805761267f6125bc565b5b61268981611deb565b828255808310156126c55761269d81611d7a565b6126a684611d7a565b6126af84611dab565b8181018382016126bf8183612149565b50505050505b505050565b680100000000000000008211156126e4576126e36125bc565b5b80546126ef81612449565b808411156127045761270384828486611f0d565b5b808410156127195761271884828486611e64565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b600082146127685761276761252f565b5b61277181612118565b5050565b600082146127865761278561252f565b5b61278f8161218e565b5050565b61279b612b87565b6127a6818484612b34565b505050565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f6d6967726174696f6e2069732066726f7a656e00000000000000000000000000600082015250565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b7f73747265616d20616c7265616479206861732061206450494400000000000000600082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b6129c081611dc0565b6129cb83825461247b565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff6129f884612730565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612a3a84612730565b9350801983169250808416831791505092915050565b600060088302612a807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261273d565b612a8a868361273d565b95508019841693508086168417925050509392505050565b612aab826121ac565b612abe612ab782612626565b83546129d8565b8255505050565b612ad0838383612206565b505050565b612ae083838361226f565b505050565b612aef82826123bd565b5050565b612afc826121f4565b612b0f612b0882612630565b8354612a0e565b8255505050565b8115612b2557612b2461252f565b5b612b2f8382612403565b505050565b612b3d836121f4565b612b51612b4982612630565b848454612a50565b825550505050565b612b62816120c3565b8114612b6d57600080fd5b50565b612b7981612101565b8114612b8457600080fd5b50565b60009056fea264697066735822122025321e8b3f610ad6d87a9b3497059176ff710a769edbe017d76013391f10763b64736f6c63430008040033"; + "0x60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d3565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000127565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff161015620000ed5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e4919062000149565b60405180910390a15b565b6000620000fe60278362000166565b91506200010b8262000184565b604082019050919050565b620001218162000177565b82525050565b600060208201905081810360008301526200014281620000ef565b9050919050565b600060208201905062000160600083018462000116565b92915050565b600082825260208201905092915050565b600060ff82169050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b612b0480620001e36000396000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638129fc1c116100a2578063a5ad8ac611610071578063a5ad8ac6146102bb578063afc26911146102d7578063b724de3a146102f5578063ded8896b14610325578063f2fde38b1461034157610116565b80638129fc1c1461025957806382b7b500146102635780638456cb59146102935780638da5cb5b1461029d57610116565b80635893253c116100e95780635893253c146101a15780635c975abb146101d1578063715018a6146101ef578063788243d5146101f9578063810a9afa1461022957610116565b8063144ae8551461011b5780633f4ba83a146101375780634f896d4f14610141578063587a8cbf14610171575b600080fd5b6101356004803603810190610130919061146f565b61035d565b005b61013f6103c5565b005b61015b600480360381019061015691906113ee565b6103df565b60405161016891906119dc565b60405180910390f35b61018b600480360381019061018691906113ad565b610484565b6040516101989190611b40565b60405180910390f35b6101bb60048036038101906101b691906113ee565b6104b2565b6040516101c891906119dc565b60405180910390f35b6101d9610552565b6040516101e691906119a6565b60405180910390f35b6101f7610569565b005b610213600480360381019061020e91906113ee565b61057d565b604051610220919061198b565b60405180910390f35b610243600480360381019061023e91906113ee565b6105bb565b6040516102509190611b1e565b60405180910390f35b610261610739565b005b61027d60048036038101906102789190611368565b610887565b60405161028a9190611b40565b60405180910390f35b61029b6108b2565b005b6102a56108cc565b6040516102b2919061198b565b60405180910390f35b6102d560048036038101906102d091906113ee565b6108f6565b005b6102df610910565b6040516102ec9190611b40565b60405180910390f35b61030f600480360381019061030a9190611368565b610916565b60405161031c9190611b40565b60405180910390f35b61033f600480360381019061033a9190611417565b610a33565b005b61035b6004803603810190610356919061133f565b610caa565b005b610365610d2e565b80609a600084815260200190815260200160002081816103859190612a27565b9050507fa9c55ebaa1fada408bd72c2f0ea7c27f5444b105bcff12c5381baac912156ada82826040516103b9929190611b8d565b60405180910390a15050565b6103cd610d2e565b6103d5610dac565b6103dd610df5565b565b60606098600083815260200190815260200160002080546103ff906123b4565b80601f016020809104026020016040519081016040528092919081815260200182805461042b906123b4565b80156104785780601f1061044d57610100808354040283529160200191610478565b820191906000526020600020905b81548152906001019060200180831161045b57829003601f168201915b50505050509050919050565b6099818051602081018201805184825260208301602085012081835280955050505050506000915090505481565b609860205280600052604060002060009150905080546104d1906123b4565b80601f01602080910402602001604051908101604052809291908181526020018280546104fd906123b4565b801561054a5780601f1061051f5761010080835404028352916020019161054a565b820191906000526020600020905b81548152906001019060200180831161052d57829003601f168201915b505050505081565b6000606560009054906101000a900460ff16905090565b610571610d2e565b61057b6000610e58565b565b609a6020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081565b6105c3611175565b609a60008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805480602002602001604051908101604052809291908181526020016000905b8282101561072a578382906000526020600020906002020160405180604001604052908160008201805461068f906123b4565b80601f01602080910402602001604051908101604052809291908181526020018280546106bb906123b4565b80156107085780601f106106dd57610100808354040283529160200191610708565b820191906000526020600020905b8154815290600101906020018083116106eb57829003601f168201915b505050505081526020016001820154815250508152602001906001019061065c565b50505050815250509050919050565b60008060019054906101000a900460ff1615905080801561076a5750600160008054906101000a900460ff1660ff16105b80610797575061077930610f1e565b1580156107965750600160008054906101000a900460ff1660ff16145b5b6107d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107cd90611a9e565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015610813576001600060016101000a81548160ff0219169083151502179055505b61081b610f41565b610823610f9a565b61082b610ff3565b80156108845760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498600160405161087b91906119c1565b60405180910390a15b50565b60006099838360405161089b929190611972565b908152602001604051809103902054905092915050565b6108ba610d2e565b6108c2611056565b6108ca610ff3565b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6108fe610d2e565b610906610dac565b8060978190555050565b60975481565b6000828260006099838360405161092e929190611972565b9081526020016040518091039020541461097d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097490611a7e565b60405180910390fd5b610985611056565b6000609754905085856098600084815260200190815260200160002091906109ae9291906111a5565b5080609987876040516109c2929190611972565b9081526020016040518091039020819055507f96a65efbb6991f67fc8a4c7550fcfd08f1968737d2f5adcded5cd937b3cc0f3d818787604051610a0793929190611b5b565b60405180910390a160976000815480929190610a2290612433565b919050555080935050505092915050565b8181600060998383604051610a49929190611972565b90815260200160405180910390205414610a98576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a8f90611a7e565b60405180910390fd5b610aa0611056565b6000609860008781526020019081526020016000208054610ac0906123b4565b90501480610b005750610ad16108cc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610b3f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b3690611a1e565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16609a600087815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161480610be15750610bb26108cc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610c20576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1790611afe565b60405180910390fd5b8383609860008881526020019081526020016000209190610c429291906111a5565b508460998585604051610c56929190611972565b9081526020016040518091039020819055507f442b41840a10393534508176faee6f70b1870707dc24573b67d49f28cbac7f1c858585604051610c9b93929190611b5b565b60405180910390a15050505050565b610cb2610d2e565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610d22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d1990611a3e565b60405180910390fd5b610d2b81610e58565b50565b610d366110a0565b73ffffffffffffffffffffffffffffffffffffffff16610d546108cc565b73ffffffffffffffffffffffffffffffffffffffff1614610daa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610da190611abe565b60405180910390fd5b565b610db4610552565b610df3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dea906119fe565b60405180910390fd5b565b610dfd610dac565b6000606560006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610e416110a0565b604051610e4e919061198b565b60405180910390a1565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16610f90576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8790611ade565b60405180910390fd5b610f986110a8565b565b600060019054906101000a900460ff16610fe9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fe090611ade565b60405180910390fd5b610ff1611109565b565b610ffb611056565b6001606560006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861103f6110a0565b60405161104c919061198b565b60405180910390a1565b61105e610552565b1561109e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161109590611a5e565b60405180910390fd5b565b600033905090565b600060019054906101000a900460ff166110f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110ee90611ade565b60405180910390fd5b6111076111026110a0565b610e58565b565b600060019054906101000a900460ff16611158576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161114f90611ade565b60405180910390fd5b6000606560006101000a81548160ff021916908315150217905550565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b8280546111b1906123b4565b90600052602060002090601f0160209004810192826111d3576000855561121a565b82601f106111ec57803560ff191683800117855561121a565b8280016001018555821561121a579182015b828111156112195782358255916020019190600101906111fe565b5b509050611227919061122b565b5090565b5b8082111561124457600081600090555060010161122c565b5090565b600061125b61125684611cb4565b611c8f565b90508281526020810184848401111561127357600080fd5b61127e8482856122e6565b509392505050565b60008135905061129581612a9b565b92915050565b60008083601f8401126112ad57600080fd5b8235905067ffffffffffffffff8111156112c657600080fd5b6020830191508360018202830111156112de57600080fd5b9250929050565b600082601f8301126112f657600080fd5b8135611306848260208601611248565b91505092915050565b60006040828403121561132157600080fd5b81905092915050565b60008135905061133981612ab2565b92915050565b60006020828403121561135157600080fd5b600061135f84828501611286565b91505092915050565b6000806020838503121561137b57600080fd5b600083013567ffffffffffffffff81111561139557600080fd5b6113a18582860161129b565b92509250509250929050565b6000602082840312156113bf57600080fd5b600082013567ffffffffffffffff8111156113d957600080fd5b6113e5848285016112e5565b91505092915050565b60006020828403121561140057600080fd5b600061140e8482850161132a565b91505092915050565b60008060006040848603121561142c57600080fd5b600061143a8682870161132a565b935050602084013567ffffffffffffffff81111561145757600080fd5b6114638682870161129b565b92509250509250925092565b6000806040838503121561148257600080fd5b60006114908582860161132a565b925050602083013567ffffffffffffffff8111156114ad57600080fd5b6114b98582860161130f565b9150509250929050565b60006114cf83836118c8565b905092915050565b60006114e38383611917565b905092915050565b6114f48161202e565b82525050565b6115038161202e565b82525050565b60006115158385611d91565b93508360208402850161152784611cfc565b8060005b8781101561156b5784840389526115428284611f99565b61154c85826114c3565b945061155783611d77565b925060208a0199505060018101905061152b565b50829750879450505050509392505050565b600061158882611d4b565b6115928185611d91565b9350836020820285016115a485611d06565b8060005b858110156115e057848403895281516115c185826114d7565b94506115cc83611d84565b925060208a019950506001810190506115a8565b50829750879550505050505092915050565b6115fb81612040565b82525050565b61160a81612129565b82525050565b600061161c8385611da2565b93506116298385846122e6565b6116328361268a565b840190509392505050565b60006116498385611db3565b93506116568385846122e6565b61165f8361268a565b840190509392505050565b60006116768385611dc4565b93506116838385846122e6565b82840190509392505050565b600061169a82611d6c565b6116a48185611da2565b93506116b48185602086016122f5565b6116bd8161268a565b840191505092915050565b60006116d382611d6c565b6116dd8185611db3565b93506116ed8185602086016122f5565b6116f68161268a565b840191505092915050565b600061170e601483611db3565b915061171982612716565b602082019050919050565b6000611731601583611db3565b915061173c8261273f565b602082019050919050565b6000611754602683611db3565b915061175f82612768565b604082019050919050565b6000611777601083611db3565b9150611782826127b7565b602082019050919050565b600061179a601983611db3565b91506117a5826127e0565b602082019050919050565b60006117bd602e83611db3565b91506117c882612809565b604082019050919050565b60006117e0602083611db3565b91506117eb82612858565b602082019050919050565b6000611803602b83611db3565b915061180e82612881565b604082019050919050565b6000611826601983611db3565b9150611831826128d0565b602082019050919050565b60006040830161184f6000840184611ed4565b61185c60008601826114eb565b5061186a6020840184611eeb565b858303602087015261187d838284611509565b925050508091505092915050565b60006040830160008301516118a360008601826114eb565b50602083015184820360208601526118bb828261157d565b9150508091505092915050565b6000604083016118db6000840184611f42565b85830360008701526118ee838284611610565b925050506118ff6020840184611fbd565b61190c6020860182611954565b508091505092915050565b60006040830160008301518482036000860152611934828261168f565b91505060208301516119496020860182611954565b508091505092915050565b61195d8161206c565b82525050565b61196c8161206c565b82525050565b600061197f82848661166a565b91508190509392505050565b60006020820190506119a060008301846114fa565b92915050565b60006020820190506119bb60008301846115f2565b92915050565b60006020820190506119d66000830184611601565b92915050565b600060208201905081810360008301526119f681846116c8565b905092915050565b60006020820190508181036000830152611a1781611701565b9050919050565b60006020820190508181036000830152611a3781611724565b9050919050565b60006020820190508181036000830152611a5781611747565b9050919050565b60006020820190508181036000830152611a778161176a565b9050919050565b60006020820190508181036000830152611a978161178d565b9050919050565b60006020820190508181036000830152611ab7816117b0565b9050919050565b60006020820190508181036000830152611ad7816117d3565b9050919050565b60006020820190508181036000830152611af7816117f6565b9050919050565b60006020820190508181036000830152611b1781611819565b9050919050565b60006020820190508181036000830152611b38818461188b565b905092915050565b6000602082019050611b556000830184611963565b92915050565b6000604082019050611b706000830186611963565b8181036020830152611b8381848661163d565b9050949350505050565b6000604082019050611ba26000830185611963565b8181036020830152611bb4818461183c565b90509392505050565b60008083356001602003843603038112611bd657600080fd5b80840192508235915067ffffffffffffffff821115611bf457600080fd5b602083019250602082023603831315611c0c57600080fd5b509250929050565b60008083356001602003843603038112611c2d57600080fd5b80840192508235915067ffffffffffffffff821115611c4b57600080fd5b602083019250600182023603831315611c6357600080fd5b509250929050565b600082356001604003833603038112611c8357600080fd5b80830191505092915050565b6000611c99611caa565b9050611ca58282612402565b919050565b6000604051905090565b600067ffffffffffffffff821115611ccf57611cce612527565b5b611cd88261268a565b9050602081019050919050565b6000819050611cf5826002611fd4565b9050919050565b6000819050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600082905092915050565b600081519050919050565b600081549050919050565b600082905092915050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6020841060008114611e2857601f841160018114611df857611df186856123e6565b8355611e22565b611e0183611d2b565b611e166020601f880104820160018301612091565b611e2087856128f9565b505b50611e71565b611e3182611d2b565b6020601f8701048101601f87168015611e5257611e518160018403612556565b5b611e646020601f890104840183612091565b6001886002021785555050505b5050505050565b6020831060008114611ec3576020851060008114611ea157611e9a86856123e6565b8355611ebd565b8360ff1916935083611eb284611d2b565b556001866002020183555b50611ecd565b6001856002020182555b5050505050565b6000611ee36020840184611286565b905092915050565b60008083356001602003843603038112611f0457600080fd5b83810192508235915060208301925067ffffffffffffffff821115611f2857600080fd5b602082023603841315611f3a57600080fd5b509250929050565b60008083356001602003843603038112611f5b57600080fd5b83810192508235915060208301925067ffffffffffffffff821115611f7f57600080fd5b600182023603841315611f9157600080fd5b509250929050565b600082356001604003833603038112611fb157600080fd5b82810191505092915050565b6000611fcc602084018461132a565b905092915050565b6000611fdf8261206c565b9150611fea8361206c565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612023576120226124c9565b5b828202905092915050565b60006120398261204c565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b61208e600082612635565b50565b5b818110156120b0576120a56000826126fe565b600181019050612092565b5050565b5b818110156120d3576120c86000826126e0565b6002810190506120b5565b5050565b818110156120f5576120ea6000826126fe565b6001810190506120d7565b5050565b61210660008083016126c2565b6121146000600183016126fe565b50565b60006121228261213b565b9050919050565b600061213482612076565b9050919050565b60006121468261214d565b9050919050565b60006121588261204c565b9050919050565b600061216a8261206c565b9050919050565b61217b8383611d40565b61218581836125d1565b61218e83611cfc565b61219783611d16565b6000805b848110156121d0576121ad8488611c6b565b6121b8818486612a58565b6020850194506002840193505060018101905061219b565b5050505050505050565b6121e48383611d61565b67ffffffffffffffff8111156121fd576121fc612527565b5b61220782546123b4565b600080601f8411601f841117156122245761222185611d2b565b90505b601f831115612257576020601f85010481016020851015612243578190505b6122556020601f860104830182612091565b505b601f8411600181146122845760008515612272578388013590505b61227c86826123e6565b8755506122dc565b601f1985168260005b828110156122b257858a0135825560018201915060208601955060208101905061228d565b878310156122cf57858a01356122cb601f8a168261247c565b8355505b6001600289020189555050505b5050505050505050565b82818337600083830152505050565b60005b838110156123135780820151818401526020810190506122f8565b83811115612322576000848401525b50505050565b60008101600083018061233a816125a5565b905061234681846129e4565b505050600181016020830161235b8185611bbd565b612366818386612a07565b505050505050565b60008101600083016123808185611c14565b61238b818386612a17565b505050506001810160208301806123a1816125bb565b90506123ad8184612a35565b5050505050565b600060028204905060018216806123cc57607f821691505b602082108114156123e0576123df6124f8565b5b50919050565b60006123f2838361247c565b9150826002028217905092915050565b61240b8261268a565b810181811067ffffffffffffffff8211171561242a57612429612527565b5b80604052505050565b600061243e8261206c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612471576124706124c9565b5b600182019050919050565b600061248d600019846008026126b5565b1980831691505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6125867fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff836020036008026126b5565b815481168255505050565b6000819050919050565b6000819050919050565b600081356125b281612a9b565b80915050919050565b600081356125c881612ab2565b80915050919050565b680100000000000000008211156125eb576125ea612527565b5b6125f481611d56565b828255808310156126305761260881611ce5565b61261184611ce5565b61261a84611d16565b81810183820161262a81836120b4565b50505050505b505050565b6801000000000000000082111561264f5761264e612527565b5b805461265a816123b4565b8084111561266f5761266e84828486611e78565b5b808410156126845761268384828486611dcf565b5b50505050565b6000601f19601f8301169050919050565b60008160001b9050919050565b600082821b905092915050565b600082821c905092915050565b600082146126d3576126d261249a565b5b6126dc81612083565b5050565b600082146126f1576126f061249a565b5b6126fa816120f9565b5050565b612706612ac9565b612711818484612a76565b505050565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b7f6470696420616c72656164792075706772616465640000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b7f73747265616d20616c7265616479206861732061206450494400000000000000600082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f756e617574686f72697a65642064706964207570677261646500000000000000600082015250565b61290281611d2b565b61290d8382546123e6565b8083556000825550505050565b600073ffffffffffffffffffffffffffffffffffffffff61293a8461269b565b9350801983169250808416831791505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61297c8461269b565b9350801983169250808416831791505092915050565b6000600883026129c27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826126a8565b6129cc86836126a8565b95508019841693508086168417925050509392505050565b6129ed82612117565b612a006129f982612591565b835461291a565b8255505050565b612a12838383612171565b505050565b612a228383836121da565b505050565b612a318282612328565b5050565b612a3e8261215f565b612a51612a4a8261259b565b8354612950565b8255505050565b8115612a6757612a6661249a565b5b612a71838261236e565b505050565b612a7f8361215f565b612a93612a8b8261259b565b848454612992565b825550505050565b612aa48161202e565b8114612aaf57600080fd5b50565b612abb8161206c565b8114612ac657600080fd5b50565b60009056fea26469706673582212204ecb8996bb39773559c74839e823c3312f16000e008595f44afba65328f7cb2464736f6c63430008040033"; type DpidAliasRegistryConstructorParams = | [signer?: Signer] From bd265ad0a060c6419ab8ba414f806868bdc28449 Mon Sep 17 00:00:00 2001 From: m0ar Date: Thu, 6 Jun 2024 16:10:46 +0200 Subject: [PATCH 128/278] prisma: add dpidAlias field to node table --- desci-server/prisma/schema.prisma | 1 + 1 file changed, 1 insertion(+) diff --git a/desci-server/prisma/schema.prisma b/desci-server/prisma/schema.prisma index 9890e9c0..a0d8f88d 100755 --- a/desci-server/prisma/schema.prisma +++ b/desci-server/prisma/schema.prisma @@ -46,6 +46,7 @@ model Node { DistributionPdfs DistributionPdfs[] PdfPreviews PdfPreviews[] DoiRecord DoiRecord[] + dpidAlias Int? @@index([ownerId]) @@index([uuid]) From a60ebe9663bdf32e7cc0fe03bca34ad1711dfe15 Mon Sep 17 00:00:00 2001 From: m0ar Date: Fri, 7 Jun 2024 15:04:18 +0200 Subject: [PATCH 129/278] add REGISTRY_OWNER_PKEY to env example --- .env.example | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.env.example b/.env.example index 37ff994f..3bddd15a 100755 --- a/.env.example +++ b/.env.example @@ -69,6 +69,10 @@ AWS_SECRET_ACCESS_KEY= # for faucet HOT_WALLET_KEY= + +# for upgrading legacy dPID's (default is ganache account #1 for local dev) +REGISTRY_OWNER_PKEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 + # https://cso-classifier.internal CSO_CLASSIFIER_API= # vscode runnable From 29b79006def03a6751928e5cee29652620c9c651 Mon Sep 17 00:00:00 2001 From: m0ar Date: Mon, 10 Jun 2024 15:40:50 +0200 Subject: [PATCH 130/278] nodeslib: add getters for contract functions (resolve/find/owner/legacy etc) --- nodes-lib/src/chain.ts | 52 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/nodes-lib/src/chain.ts b/nodes-lib/src/chain.ts index 35d0294e..4fe6501d 100644 --- a/nodes-lib/src/chain.ts +++ b/nodes-lib/src/chain.ts @@ -1,4 +1,4 @@ -import { BigNumber, ContractReceipt, Signer, providers, utils } from "ethers"; +import { BigNumber, ContractReceipt, Signer, ethers, providers, utils } from "ethers"; import { convertUUIDToHex, convertCidTo0xHex} from "./util/converting.js"; import { changeManifest, prePublishDraftNode, type PrepublishResponse } from "./api.js" import { getNodesLibInternalConfig } from "./config/index.js"; @@ -46,7 +46,7 @@ export const dpidPublish = async ( if (dpidExists) { console.log(`${LOG_CTX} dpid exists for ${uuid}, checking token ownership`); const signingAddress = (await signer.getAddress()).toLowerCase(); - const researchObjectOwner = await getResearchObjectOwner(uuid, signer); + const researchObjectOwner = await getTokenOwner(uuid, signer); if (signingAddress !== researchObjectOwner) { throw new WrongOwnerError({ @@ -109,6 +109,16 @@ export const createDpidAlias = async ( return { dpid, receipt }; }; +export const upgradeDpidAlias = async ( + streamId: string, + dpid: number, + signer: Signer, +): Promise => { + const tx = await dpidAliasRegistryWriter(signer) + .upgradeDpid(BigNumber.from(dpid), streamId); + return await tx.wait(); +}; + /** * Lookup the history of a legacy dPID in the new alias registry. */ @@ -121,6 +131,31 @@ export const lookupLegacyDpid = async ( return await dpidAliasRegistryReader(provider).legacyLookup(dpid); }; +/** + * Resolve codex streamID for a dPID alias. +*/ +export const lookupDpid = async ( + dpid: number +): Promise => { + const provider = new providers.JsonRpcProvider( + getNodesLibInternalConfig().chainConfig.rpcUrl + ); + return await dpidAliasRegistryReader(provider).resolve(dpid); +}; + +/** + * Find the dPID alias of a given streamID, a reverse lookup. +*/ +export const findDpid = async ( + streamId: string, +): Promise => { + const provider = new providers.JsonRpcProvider( + getNodesLibInternalConfig().chainConfig.rpcUrl + ); + const dpidBn = await dpidAliasRegistryReader(provider).find(streamId); + return ethers.BigNumber.from(dpidBn).toNumber(); +}; + /** * Update an existing dPID with a new version of the manifest. * @deprecated @@ -141,7 +176,7 @@ const updateExistingDpid = async ( * Optimistically create a manifest with the next available dPID, * and try to register it as such. * @throws on dpid registration failure. - * @deprecated + * @deprecated use createDpidAlias */ const registerNewDpid = async ( uuid: string, @@ -210,8 +245,17 @@ export const hasDpid = async ( /** * @deprecated */ -export const getResearchObjectOwner = async ( +export const getTokenOwner = async ( uuid: string, signer: Signer, ): Promise => (await researchObjectWriter(signer).ownerOf(convertUUIDToHex(uuid))).toLowerCase();; + + +/** + * Get the research object token ID for a given (legacy) dPID +*/ +export const getTokenId = async ( + dpid: number, + signer: Signer, +): Promise => await dpidRegistryWriter(signer).get("beta", dpid); From 0c1fc0d2521892656e1a927d8097ff0fd3728d72 Mon Sep 17 00:00:00 2001 From: m0ar Date: Tue, 11 Jun 2024 15:44:56 +0200 Subject: [PATCH 131/278] server: generate migration & support fetching dpidAlias --- .../migration.sql | 2 ++ desci-server/src/services/nodeManager.ts | 13 +++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 desci-server/prisma/migrations/20240613093337_add_dpid_alias_field_to_node/migration.sql diff --git a/desci-server/prisma/migrations/20240613093337_add_dpid_alias_field_to_node/migration.sql b/desci-server/prisma/migrations/20240613093337_add_dpid_alias_field_to_node/migration.sql new file mode 100644 index 00000000..16ba436e --- /dev/null +++ b/desci-server/prisma/migrations/20240613093337_add_dpid_alias_field_to_node/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "Node" ADD COLUMN "dpidAlias" INTEGER; diff --git a/desci-server/src/services/nodeManager.ts b/desci-server/src/services/nodeManager.ts index 36b53b80..e932fa29 100644 --- a/desci-server/src/services/nodeManager.ts +++ b/desci-server/src/services/nodeManager.ts @@ -66,6 +66,19 @@ export const setCeramicStream = async (uuid: string, ceramicStream: string) => { }); }; +export const setDpidAlias = async (uuid: string, dpidAlias: number) => { + logger.debug({ fn: 'setDpidAlias', uuid, dpidAlias }, 'node::setDpidAlias'); + uuid = ensureUuidEndsWithDot(uuid); + return await prisma.node.update({ + data: { + dpidAlias, + }, + where: { + uuid, + }, + }); +}; + export const createPublicDataRefs = async ( data: Prisma.PublicDataReferenceCreateManyInput[], userId: number | undefined, From 09d4c1b7f0bf4c05e02c22a198619d8b0fae44dc Mon Sep 17 00:00:00 2001 From: m0ar Date: Wed, 12 Jun 2024 15:53:43 +0200 Subject: [PATCH 132/278] nodeslib: enable getting backfill history from contract legacy entries --- nodes-lib/src/api.ts | 60 ++++++++----- nodes-lib/src/errors.ts | 5 +- nodes-lib/src/publish.ts | 66 ++++++++++---- nodes-lib/test/convert.spec.ts | 22 +++-- nodes-lib/test/root.spec.ts | 160 +++++++++++++++++++++++++++++++-- 5 files changed, 259 insertions(+), 54 deletions(-) diff --git a/nodes-lib/src/api.ts b/nodes-lib/src/api.ts index 188f9c76..28ba9374 100644 --- a/nodes-lib/src/api.ts +++ b/nodes-lib/src/api.ts @@ -30,7 +30,9 @@ import { makeRequest } from "./routes.js"; import { Signer } from "ethers"; import { type DID } from "dids"; import { getFullState } from "./codex.js"; -import { convertUUIDToDecimal } from "./util/converting.js"; +import { bnToString, convertUUIDToDecimal } from "./util/converting.js"; +import { lookupLegacyDpid } from "./chain.js"; +import { NoSuchEntryError } from "./errors.js"; export const ENDPOINTS = { deleteData: { @@ -255,6 +257,7 @@ export type NodeResponse = { isDeleted: boolean, manifestDocumentId: string, ceramicStream?: string, + dpidAlias?: number, }; /** @@ -289,7 +292,7 @@ export type PrepublishResponse = { updatedManifestCid: string; updatedManifest: ResearchObjectV1; version?: NodeVersion; - ceramicStream?: string; + ceramicStream: string | null; }; export type PublishConfiguration = { @@ -353,8 +356,6 @@ export const publishNode = async ( manifest: publishResult.manifest, ceramicStream: publishResult.ceramicIDs.streamID, commitId: publishResult.ceramicIDs.commitID, - // required in DB & this string is used to detect non-tx's in publish worker - transactionId: "ceramic", }; try { @@ -364,20 +365,6 @@ export const publishNode = async ( throw e; }; - let dpid; - try { - dpid = await createDpid(uuid); - await changeManifest( - uuid, - [{ - type: "Publish Dpid", - dpid: { prefix: "", id: dpid.toString() } - }], - ); - } catch (e) { - console.log(`Failed to create dPID alias for node ${uuid}...`); - }; - return { ceramicIDs: publishResult.ceramicIDs, updatedManifest: publishResult.manifest, @@ -754,13 +741,17 @@ export type IndexedNode = { versions: IndexedNodeVersion[]; }; +/** + * Get the codex publish history for a given node. + * Note: calling this right after publish may fail + * since the publish operation may not have finished. +*/ export const getPublishHistory = async ( uuid: string, ): Promise => { - const { ceramicStream,} = await getDraftNode(uuid); - + const { ceramicStream } = await getDraftNode(uuid); if (!ceramicStream) { - return await getDpidHistory(uuid); + throw new Error(`No known stream for node ${uuid}`); }; const resolved = await getFullState(ceramicStream); @@ -772,7 +763,7 @@ export const getPublishHistory = async ( const indexedNode: IndexedNode = { id: uuid, id10: convertUUIDToDecimal(uuid), - owner: resolved.owner, + owner: resolved.owner.id, recentCid: resolved.manifest, versions, }; @@ -780,9 +771,32 @@ export const getPublishHistory = async ( return indexedNode; }; +/** + * Lookup the history of a legacy dPID in the alias registry. + * @throws (@link NoSuchEntryError) if no such legacy entry exists +*/ +export const getLegacyHistory = async ( + dpid: number, +): Promise => { + const legacyEntry = await lookupLegacyDpid(dpid); + + if (legacyEntry.versions.length === 0) { + throw new NoSuchEntryError({ + name: "NO_SUCH_ENTRY_ERROR", + message: "No legacy history exists for this dPID", + }); + }; + + const nodeVersions = legacyEntry.versions.map( + ({ cid, time }) => ({ cid, time: bnToString(time) }) + ); + + return nodeVersions; +}; + /** * Get the dPID publish history for a node. - * @deprecated use getPublishHistory + * @deprecated use getPublishHistory or getLegacyHistory when using new contracts */ export const getDpidHistory = async ( uuid: string, diff --git a/nodes-lib/src/errors.ts b/nodes-lib/src/errors.ts index fc8f7dc4..f88a52c1 100644 --- a/nodes-lib/src/errors.ts +++ b/nodes-lib/src/errors.ts @@ -1,14 +1,14 @@ class BaseError extends Error { name: Name; message: string; - cause: Cause; + cause?: Cause; constructor({ name, message, cause }: { name: Name, message: string, - cause: Cause, + cause?: Cause, }) { super(); this.name = name; @@ -22,3 +22,4 @@ export class DpidRegistrationError extends BaseError<"DPID_REGISTRATION_ERROR", export class WrongOwnerError extends BaseError< "WRONG_OWNER_ERROR", { expected: string, actual: string } > {}; +export class NoSuchEntryError extends BaseError<"NO_SUCH_ENTRY_ERROR", Error> {}; diff --git a/nodes-lib/src/publish.ts b/nodes-lib/src/publish.ts index 1ad693e7..f46cb6fe 100644 --- a/nodes-lib/src/publish.ts +++ b/nodes-lib/src/publish.ts @@ -1,10 +1,19 @@ import { type NodeIDs } from "@desci-labs/desci-codex-lib"; -import { IndexedNodeVersion, getDpidHistory, getDraftNode, prePublishDraftNode } from "./api.js"; -import { dpidPublish, hasDpid, lookupLegacyDpid } from "./chain.js"; +import { + IndexedNodeVersion, + getDpidHistory, + getDraftNode, + getLegacyHistory, + prePublishDraftNode, +} from "./api.js"; +import { + dpidPublish, + hasDpid, +} from "./chain.js"; import { codexPublish } from "./codex.js"; import { Signer } from "ethers"; import { type DID } from "dids"; -import { bnToString } from "./util/converting.js"; +import { NoSuchEntryError } from "./errors.js"; /** * Publish node to Codex, potentially migrating history from dPID token. @@ -16,24 +25,24 @@ export const publish = async ( ) => { const node = await getDraftNode(uuid); const prepubResult = await prePublishDraftNode(uuid); - const dpid = node.manifestData.dpid?.id; + const manifestDpid = node.manifestData.dpid?.id; - // We know about a dPID, but not about a stream => should backfill history - const hasHistory = - (dpid !== undefined) && (prepubResult.ceramicStream === undefined); + const hasDpidInManifest = manifestDpid !== undefined; + const hasStreamOnRecord = prepubResult.ceramicStream !== null; + const shouldDoMigration = hasDpidInManifest && !hasStreamOnRecord; - let history: IndexedNodeVersion[] = []; - if (hasHistory) { - const legacyEntry = await lookupLegacyDpid(parseInt(dpid)); - // Wrangle BigNumber timestamp to string epoch - history = legacyEntry.versions.map( - ({ cid, time }) => ({ cid, time: bnToString(time) }) - ); + let legacyHistory: IndexedNodeVersion[] = []; + if (shouldDoMigration) { + legacyHistory = await findLegacyHistory(uuid, parseInt(manifestDpid)); }; // Performs backfill migration if there is no stream on record, otherwise // we can send the empty history array and avoid the history query - const ceramicIDs = await codexPublish(prepubResult, history, didOrSigner); + const ceramicIDs = await codexPublish( + prepubResult, + legacyHistory, + didOrSigner + ); return { cid: prepubResult.updatedManifestCid, @@ -87,3 +96,30 @@ export const legacyPublish = async ( ceramicIDs, }; }; + +/** + * Looks for legacy history for a dPID, starting with the new contract's + * legacy mapping, falling back to querying the nodes backend for subgraph + * indexed updates. + * + * For public environments, the former should always be enough, but it + * doesn't work for testing migration etc because that logic relies on + * looking up things only published in the legacy registry. + * + * This fallback logic can be cleaned up when the old contracts are paused, + * since the data migration to the alias registry can be made final. +*/ +const findLegacyHistory = async ( + uuid: string, + dpid: number, +): Promise => { + try { + return await getLegacyHistory(dpid); + } catch (e) { + if (!(e instanceof NoSuchEntryError)) { + throw e; + }; + }; + + return (await getDpidHistory(uuid)).versions; +}; diff --git a/nodes-lib/test/convert.spec.ts b/nodes-lib/test/convert.spec.ts index 6f03088e..72d9e8ec 100644 --- a/nodes-lib/test/convert.spec.ts +++ b/nodes-lib/test/convert.spec.ts @@ -1,27 +1,37 @@ import { test, describe, expect } from "vitest"; -import { convertCidTo0xHex, convert0xHexToCid, convertUUIDToHex } from "../src/util/converting.js"; +import { convertCidTo0xHex, convert0xHexToCid, convertUUIDToHex, convertUUIDToDecimal } from "../src/util/converting.js"; -describe("conversion", async () => { - describe("between UUID and hex", async () => { +describe("conversion", () => { + describe("between UUID and hex", () => { const uuid = "pOV6-0ZN8k8Nlb3iJ7BHgbHt4V_xt-H-dUbRQCLKl78"; const expectedHex = "0xa4e57afb464df24f0d95bde227b04781b1ede15ff1b7e1fe7546d14022ca97bf"; - test("works", async () => { + test("works", () => { const actualHex = convertUUIDToHex(uuid) expect(actualHex).toEqual(expectedHex); }); }); + describe("between UUID and decimal", () => { + const uuid = "pOV6-0ZN8k8Nlb3iJ7BHgbHt4V_xt-H-dUbRQCLKl78"; + const expectedDecimal = "74584763932894785363050678437902601468178104400434333322549483008347345688511"; + + test("works", () => { + const uuid10 = convertUUIDToDecimal(uuid); + expect(uuid10).toEqual(expectedDecimal); + }); + }); + describe("between CID and hex", async () => { const exampleCid = "bafkreihge5qw7sc3mqc4wkf4cgpv6udtvrgipfxwyph7dhlyu6bkkt7tfq"; const expectedHex = "0x0f01551220e627616fc85b6405cb28bc119f5f5073ac4c8796f6c3cff19d78a782a54ff32c"; - test("works one way", async () => { + test("works one way", () => { const cidAsHex = convertCidTo0xHex(exampleCid); expect(cidAsHex).toEqual(expectedHex); }); - test("works the other way", async () => { + test("works the other way", () => { const hexAsCid = convert0xHexToCid(expectedHex); expect(hexAsCid).toEqual(exampleCid); }); diff --git a/nodes-lib/test/root.spec.ts b/nodes-lib/test/root.spec.ts index b099c38f..60af7ce2 100644 --- a/nodes-lib/test/root.spec.ts +++ b/nodes-lib/test/root.spec.ts @@ -2,7 +2,7 @@ import { test, describe, beforeAll, expect } from "vitest"; import type { AddCodeComponentParams, AddLinkComponentParams, AddPdfComponentParams, - CreateDraftParams, ExternalUrl, PublishResponse, RetrieveResponse, + CreateDraftParams, ExternalUrl, NodeResponse, PublishResponse, RetrieveResponse, UploadFilesResponse, } from "../src/api.js" import { @@ -13,10 +13,12 @@ import { deleteComponent, updateComponent, changeManifest, updateTitle, updateDescription, updateLicense, updateResearchFields, addContributor, removeContributor, addExternalCid, updateCoverImage, + publishNode, + getPublishHistory, } from "../src/api.js"; import axios from "axios"; -import { getCodexHistory, getPublishedFromCodex, getRawState } from "../src/codex.js"; -import { dpidPublish } from "../src/chain.js"; +import { getCodexHistory, getCurrentState, getRawState } from "../src/codex.js"; +import { dpidPublish, findDpid, lookupLegacyDpid } from "../src/chain.js"; import { sleep } from "./util.js"; import { convert0xHexToCid } from "../src/util/converting.js"; import { @@ -56,7 +58,7 @@ describe("nodes-lib", () => { "Failed to connect to desci-server; is the service running?", ); process.exit(1); - } + }; }); describe("draft nodes", async () => { test("can be created", async () => { @@ -268,7 +270,7 @@ describe("nodes-lib", () => { }); }); - describe("publishing ", async () => { + describe("legacy publishing ", async () => { let uuid: string; let publishResult: PublishResponse; const did = await authorizedSessionDidFromSigner(testSigner, getResources()); @@ -298,7 +300,7 @@ describe("nodes-lib", () => { test("to codex", async () => { expect(publishResult.ceramicIDs).not.toBeUndefined(); - const ceramicObject = await getPublishedFromCodex(publishResult.ceramicIDs!.streamID); + const ceramicObject = await getCurrentState(publishResult.ceramicIDs!.streamID); expect(ceramicObject?.manifest).toEqual(publishResult.updatedManifestCid); }); @@ -340,7 +342,7 @@ describe("nodes-lib", () => { test("publishes to codex stream", async () => { expect(publishResult.ceramicIDs).not.toBeUndefined(); - const ceramicObject = await getPublishedFromCodex(publishResult.ceramicIDs!.streamID); + const ceramicObject = await getCurrentState(publishResult.ceramicIDs!.streamID); expect(ceramicObject?.manifest).toEqual(publishResult.updatedManifestCid); const ceramicHistory = await getCodexHistory(publishResult.ceramicIDs!.streamID); @@ -361,7 +363,7 @@ describe("nodes-lib", () => { const pubResult = await publishDraftNode(uuid, testSigner, did); // Allow graph node to index - await sleep(1_500); + await sleep(2_500); // make sure codex history is of equal length const dpidHistory = await getDpidHistory(uuid); @@ -381,6 +383,148 @@ describe("nodes-lib", () => { }); + describe.only("publishing ", async () => { + let uuid: string; + let publishResult: PublishResponse; + const did = await authorizedSessionDidFromSigner(testSigner, getResources()); + + beforeAll(async () => { + const { node } = await createBoilerplateNode(); + uuid = node.uuid; + publishResult = await publishNode(uuid, did); + }); + + describe("new node", async () => { + test("to codex", async () => { + expect(publishResult.ceramicIDs).not.toBeUndefined(); + const ceramicObject = await getCurrentState(publishResult.ceramicIDs!.streamID); + expect(ceramicObject?.manifest).toEqual(publishResult.updatedManifestCid); + }); + + test("has a new version", async () => { + const history = await getCodexHistory(publishResult.ceramicIDs!.streamID); + expect(history.length).toEqual(1); + }); + + test("does NOT set dPID in manifest", async () => { + const node = await getDraftNode(uuid); + expect(node.manifestData.dpid).toBeUndefined(); + }); + + test("has a CACAO from the passed DID", async () => { + const streamState = await getRawState(publishResult.ceramicIDs!.streamID); + const controller = streamState.state.metadata.controllers.at(0); + const signerAddress = (await testSigner.getAddress()).toLowerCase(); + + expect(controller).toEqual(did.parent); + expect(controller!.replace("did:pkh:eip155:1337:", "")).toEqual(signerAddress); + }); + + test("can optionally derive DID from just a signer", async () => { + const { node } = await createBoilerplateNode(); + const result = await publishNode(node.uuid, testSigner); + const streamState = await getRawState(result.ceramicIDs!.streamID); + const controller = streamState.state.metadata.controllers.at(0); + const signerAddress = (await testSigner.getAddress()).toLowerCase(); + expect(controller!.replace("did:pkh:eip155:1337:", "")).toEqual(signerAddress); + }); + + test("tracks streamID with node state", async () => { + const node = await getDraftNode(uuid); + expect(node.ceramicStream).toEqual(publishResult.ceramicIDs?.streamID); + }); + + test("tracks new dpid alias with node state", async () => { + const node = await getDraftNode(uuid); + const dpidAlias = await findDpid(node.ceramicStream!); + expect(node.dpidAlias).toEqual(dpidAlias); + }); + }); + + describe("node update", async () => { + let updateResult: PublishResponse; + let nodeStateBefore: NodeResponse; + + beforeAll(async () => { + nodeStateBefore = await getDraftNode(uuid); + updateResult = await publishNode(uuid, did); + }); + + test("updates most recent state", async () => { + const ceramicObject = await getCurrentState(updateResult.ceramicIDs!.streamID); + expect(ceramicObject?.manifest).toEqual(updateResult.updatedManifestCid); + }); + + test("adds a new version", async () => { + const ceramicHistory = await getCodexHistory(updateResult.ceramicIDs!.streamID); + expect(ceramicHistory.length).toEqual(2); + }); + + test("does not change the tracked streamID", async () => { + const node = await getDraftNode(uuid); + expect(node.ceramicStream).toEqual(nodeStateBefore.ceramicStream); + }); + + test("does not mint a new dPID alias", async () => { + const node = await getDraftNode(uuid); + expect(node.dpidAlias).toEqual(nodeStateBefore.dpidAlias); + }); + }); + + describe("node with legacy history", async () => { + let uuid: string; + let pubResult: PublishResponse; + let legacyDpid: number; + + beforeAll(async () => { + const { node } = await createBoilerplateNode(); + uuid = node.uuid; + + // make a dpid-only publish + const { prepubResult: { updatedManifest }} = await dpidPublish(uuid, false, testSigner); + + legacyDpid = parseInt(updatedManifest.dpid!.id); + + // Allow graph node to index + await sleep(2_500); + + // make a regular publish + pubResult = await publishNode(uuid, did); + }); + + test("migrates history to new stream", async () => { + // legacy registry only knows about the first update + const dpidHistory = await getDpidHistory(uuid); + expect(dpidHistory.versions.length).toEqual(1); + + // codex history has the legacy and the new update + const codexHistory = await getCodexHistory(pubResult.ceramicIDs!.streamID); + expect (codexHistory.length).toEqual(2); + }); + + test("tracks streamID with node state", async () => { + const node = await getDraftNode(uuid); + expect(node.ceramicStream).toEqual(pubResult.ceramicIDs?.streamID); + }); + + test("tracks upgraded dpid alias with node state", async () => { + const node = await getDraftNode(uuid); + const dpidAlias = await findDpid(node.ceramicStream!); + expect(dpidAlias).toEqual(legacyDpid); + }); + }); + + /** This is not an user feature, but part of error handling during legacy publish */ + test("can remove dPID from manifest", async () => { + await changeManifest( + uuid, [{ type: "Remove Dpid" }] + ); + const node = await getDraftNode(uuid); + expect(node.manifestData.dpid).toBeUndefined(); + }); + + }); + describe("data management", async () => { describe("trees", async () => { test("can be retrieved by owner", async () => { From 3859c7fe9c1a75cdf25b7d3a9e71c90612f7ba71 Mon Sep 17 00:00:00 2001 From: m0ar Date: Wed, 12 Jun 2024 15:58:28 +0200 Subject: [PATCH 133/278] server: add createDpid endpoint/controller --- .../src/controllers/nodes/createDpid.ts | 132 +++++++++++++----- 1 file changed, 96 insertions(+), 36 deletions(-) diff --git a/desci-server/src/controllers/nodes/createDpid.ts b/desci-server/src/controllers/nodes/createDpid.ts index 84c82808..fbc6daea 100644 --- a/desci-server/src/controllers/nodes/createDpid.ts +++ b/desci-server/src/controllers/nodes/createDpid.ts @@ -3,7 +3,8 @@ import { ethers } from "ethers"; import { logger as parentLogger } from '../../logger.js'; import { RequestWithNode } from "../../middleware/authorisation.js"; import { contracts, typechain as tc } from "@desci-labs/desci-contracts"; -import { DpidMintedEvent } from "@desci-labs/desci-contracts/dist/typechain-types/DpidAliasRegistry.js"; +import { DpidMintedEvent, UpgradedDpidEvent } from "@desci-labs/desci-contracts/dist/typechain-types/DpidAliasRegistry.js"; +import { setDpidAlias } from "../../services/nodeManager.js"; type DpidResponse = DpidSuccessResponse | DpidErrorResponse; export type DpidSuccessResponse = { @@ -15,7 +16,7 @@ export type DpidErrorResponse = { }; /** Not secret: pre-seeded ganache account for local dev */ -const GANACHE_PKEY = "59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d"; +const GANACHE_PKEY = "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; let aliasRegistryAddress: string; const url = process.env.SERVER_URL; @@ -56,44 +57,103 @@ export const createDpid = async (req: RequestWithNode, res: Response => { + const logger = parentLogger.child({ + module: "NODE::mintDpid", + ceramicStream: streamId, + }); + + const provider = new ethers.providers.JsonRpcProvider( + process.env.ETHEREUM_RPC_URL + ); + + await provider.ready; + const wallet = new ethers.Wallet( + url.includes("localhost") ? GANACHE_PKEY : process.env.HOT_WALLET_KEY, + provider, + ); + + const dpidAliasRegistry = tc.DpidAliasRegistry__factory.connect( + aliasRegistryAddress, + wallet, + ); + + const checkDpid = await dpidAliasRegistry.find(streamId); + const existingDpid = ethers.BigNumber.from(checkDpid).toNumber(); + + if (existingDpid !== 0) { + logger.info(`Skipping alias creation, stream ${streamId} already bound to ${existingDpid}`); + return existingDpid; + }; + + const tx = await dpidAliasRegistry.mintDpid(streamId); + const receipt = await tx.wait(); + const { args: [ dpidBn ] } = receipt.events[0] as DpidMintedEvent; + const dpid = ethers.BigNumber.from(dpidBn).toNumber(); + + logger.info( + `Created dPID alias ${dpid} for stream ${streamId}`, + ); + + return dpid; +}; + +/** + * Related, but not directly API exposed, functionality to upgrade a legacy + * dPID. Neither this function nor the contract can do any validation that + * this stream represents the history of that dPID, so this needs to be + * verified before this function is called. + * + * Note: this method in the registry contract is only callable by contract + * owner, so this is not generally available. +*/ +export const upgradeDpid = async ( + dpid: number, + ceramicStream: string, +): Promise => { + const logger = parentLogger.child({ + module: "NODE::upgradeDpid", + ceramicStream, + }); + + const provider = new ethers.providers.JsonRpcProvider( + process.env.ETHEREUM_RPC_URL + ); + + if (!process.env.REGISTRY_OWNER_PKEY) { + throw new Error("REGISTRY_OWNER_PKEY missing, cannot upgrade dpid"); + }; + + await provider.ready; + const wallet = new ethers.Wallet( + url.includes("localhost") ? GANACHE_PKEY : process.env.REGISTRY_OWNER_PKEY, + provider, + ); + + const dpidAliasRegistry = tc.DpidAliasRegistry__factory.connect( + aliasRegistryAddress, + wallet, + ); + + const tx = await dpidAliasRegistry.upgradeDpid(dpid, ceramicStream); + await tx.wait(); + + logger.info( + `Upgraded dPID ${dpid} to track stream ${ceramicStream}`, + ); + + return dpid; +}; From 8c9f83d466d019f07614e92daa10b03a18e8ad66 Mon Sep 17 00:00:00 2001 From: m0ar Date: Thu, 13 Jun 2024 15:59:19 +0200 Subject: [PATCH 134/278] server: fix raw/versions not checking dot UUID suffix --- desci-server/src/controllers/raw/versions.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/desci-server/src/controllers/raw/versions.ts b/desci-server/src/controllers/raw/versions.ts index 42299199..914e2f6e 100644 --- a/desci-server/src/controllers/raw/versions.ts +++ b/desci-server/src/controllers/raw/versions.ts @@ -2,12 +2,13 @@ import { Request, Response, NextFunction } from 'express'; import { logger } from '../../logger.js'; import { getIndexedResearchObjects } from '../../theGraph.js'; +import { ensureUuidEndsWithDot } from '../../utils.js'; /** * Get all versions of research object from index (publicView) */ export const versions = async (req: Request, res: Response, next: NextFunction) => { - const uuid = req.params.uuid; + const uuid = ensureUuidEndsWithDot(req.params.uuid); let graphOk = false; let result; try { From 47626533005872e891f48313f55e4859932df1a7 Mon Sep 17 00:00:00 2001 From: m0ar Date: Thu, 13 Jun 2024 16:01:12 +0200 Subject: [PATCH 135/278] server: refactor publish flow, default to dpid alias registry unless overridden --- .env.example | 3 + desci-server/package.json | 2 +- desci-server/src/controllers/nodes/publish.ts | 375 ++++++++++++------ desci-server/src/workers/publish.ts | 7 +- desci-server/yarn.lock | 8 +- 5 files changed, 266 insertions(+), 129 deletions(-) diff --git a/.env.example b/.env.example index 3bddd15a..4856b89f 100755 --- a/.env.example +++ b/.env.example @@ -134,3 +134,6 @@ DOI_PREFIX=https://doi.org/10.62891 CROSSREF_API=https://api.crossref.org CROSSREF_API_KEY= CROSSREF_EMAIL= + +# Set this truthy to use legacy dPID publish +FALLBACK_LEGACY_DPID= diff --git a/desci-server/package.json b/desci-server/package.json index d346ff25..4a47a9ae 100755 --- a/desci-server/package.json +++ b/desci-server/package.json @@ -56,7 +56,7 @@ "@automerge/automerge-repo-network-websocket": "^1.0.19", "@aws-sdk/client-s3": "^3.537.0", "@desci-labs/desci-models": "0.2.7-rc3", - "@desci-labs/desci-contracts": "0.2.5-rc3", + "@desci-labs/desci-contracts": "0.2.5-rc6", "@honeycombio/opentelemetry-node": "^0.3.2", "@ipld/dag-pb": "^4.0.0", "@opentelemetry/api": "^1.8.0", diff --git a/desci-server/src/controllers/nodes/publish.ts b/desci-server/src/controllers/nodes/publish.ts index 47e5c18e..e4b03fba 100644 --- a/desci-server/src/controllers/nodes/publish.ts +++ b/desci-server/src/controllers/nodes/publish.ts @@ -1,24 +1,27 @@ import { ResearchObjectV1 } from '@desci-labs/desci-models'; -import { ActionType, Prisma, PublishTaskQueueStatus, User } from '@prisma/client'; +import { ActionType, Node, Prisma, PublishTaskQueue, PublishTaskQueueStatus, User } from '@prisma/client'; import { Request, Response, NextFunction } from 'express'; import { prisma } from '../../client.js'; import { logger as parentLogger } from '../../logger.js'; import { getManifestByCid } from '../../services/data/processing.js'; -import { fixDpid, getTargetDpidUrl } from '../../services/fixDpid.js'; +import { getTargetDpidUrl } from '../../services/fixDpid.js'; import { saveInteraction, saveInteractionWithoutReq } from '../../services/interactionLog.js'; import { - publishResearchObject, cacheNodeMetadata, getAllCidsRequiredForPublish, createPublicDataRefs, - createDataMirrorJobs, setCeramicStream, + setDpidAlias, } from '../../services/nodeManager.js'; +<<<<<<< HEAD import orcidApiService from '../../services/orcid.js'; import { publishServices } from '../../services/PublishServices.js'; +======= +>>>>>>> a91865b (server: refactor publish flow, default to dpid alias registry unless overridden) import { discordNotify } from '../../utils/discordUtils.js'; import { ensureUuidEndsWithDot } from '../../utils.js'; +import { getOrCreateDpid, upgradeDpid } from './createDpid.js'; export type PublishReqBody = { uuid: string; @@ -36,7 +39,7 @@ export type PublishRequest = Request & { export type PublishResBody = | { ok: boolean; - taskId: number; + taskId?: number; } | { error: string; @@ -98,44 +101,60 @@ export const publish = async (req: PublishRequest, res: Response return res.status(400).json({ error: 'failed' }); } + // Check if there is already an ongoing publish job in the queue const task = await prisma.publishTaskQueue.findFirst({ where: { uuid: ensureUuidEndsWithDot(uuid), status: { not: PublishTaskQueueStatus.FAILED } }, }); if (task) return res.status(400).json({ error: 'Node publishing in progress' }); + let publishTask: PublishTaskQueue | undefined; + + // Do synchronous publish if the caller passed stream information + if (!process.env.FALLBACK_LEGACY_DPID) { + await syncPublish( + ceramicStream, + commitId, + node, + owner, + cid, + uuid, + manifest, + ); + } else { + publishTask = await prisma.publishTaskQueue.create({ + data: { + cid, + dpid: manifest.dpid?.id, + userId: owner.id, + transactionId, + ceramicStream, + commitId, + uuid: ensureUuidEndsWithDot(uuid), + status: PublishTaskQueueStatus.WAITING, + }, + }); + }; + saveInteraction( req, ActionType.PUBLISH_NODE, { cid, - dpid: manifest.dpid.id, + dpid: manifest.dpid?.id, userId: owner.id, transactionId, - ceramicStream: ceramicStream ?? '', - commitId: commitId ?? '', + ceramicStream, + commitId, uuid: ensureUuidEndsWithDot(uuid), status: PublishTaskQueueStatus.WAITING, }, owner.id, ); - const publishTask = await prisma.publishTaskQueue.create({ - data: { - cid, - dpid: manifest.dpid.id, - userId: owner.id, - transactionId, - ceramicStream: ceramicStream ?? '', - commitId: commitId ?? '', - uuid: ensureUuidEndsWithDot(uuid), - status: PublishTaskQueueStatus.WAITING, - }, - }); - return res.send({ ok: true, - taskId: publishTask.id, + taskId: publishTask?.id, }); } catch (err) { logger.error({ err }, '[publish::publish] node-publish-err'); @@ -143,6 +162,212 @@ export const publish = async (req: PublishRequest, res: Response } }; +/** + * Synchronously perform publish steps before returning. + * + * This is generally fast because the ceramic update is already done, + * but two cases are a bit slower: + * 1. first time publish (wait on backend tx) + * 2. dpid upgrade (wait on backend tx) + * + * Semantically, these can both be made fire-and-forget promises if we can + * manage without instantly having the dPID alias available in this function. +*/ +const syncPublish = async ( + ceramicStream: string, + commitId: string, + node: Node, + owner: User, + cid: string, + uuid: string, + manifest: ResearchObjectV1, +): Promise => { + const logger = parentLogger.child({ + module: 'NODE::syncPublish', + uuid, + cid, + ceramicStream, + commitId, + }); + + const latestNodeVersion = await prisma.nodeVersion.findFirst({ + where: { + id: -1, + nodeId: node.id, + }, + orderBy: { + id: "desc", + }, + }); + + // Prevent duplicating the NodeVersion entry if the latest version is the same as the one we're trying to publish, as a draft save is triggered before publishing + const latestNodeVersionId = latestNodeVersion?.manifestUrl === cid + ? latestNodeVersion.id + : -1; + + const nodeVersion = await prisma.nodeVersion.upsert({ + where: { + id: latestNodeVersionId, + }, + update: { + commitId, + }, + create: { + nodeId: node.id, + manifestUrl: cid, + commitId, + }, + }); + + // first time we see a stream for this node, make sure we bind it in the db + if (!node.ceramicStream) { + logger.trace(`[publish:publish] setting streamID ${ceramicStream} on node ${uuid}`); + await setCeramicStream(uuid, ceramicStream); + } else if (node.ceramicStream !== ceramicStream) { + logger.warn( + // This is unexpected and weird, but important to know if it occurs + `[publish:publish] stream on record does not match passed streamID`, + { database: node.ceramicStream, ceramicStream }, + ); + }; + + const legacyDpid = manifest.dpid?.id ? parseInt(manifest.dpid.id) : undefined; + let dpidAlias: number = node.dpidAlias; + + // Do dataRef and dPID registration operations concurrently + const promises = []; + + if (!dpidAlias) { + // The only reason this isn't just fire-and-forget is that we want the dpid + // for the discord notification, which won't be available otherwise for + // first time publishes. + promises.push( + createOrUpgradeDpidAlias(legacyDpid, ceramicStream, uuid) + .then(dpid => dpidAlias = dpid) + ); + }; + + promises.push( + handlePublicDataRefs({ + nodeId: node.id, + userId: owner.id, + manifestCid: cid, + nodeVersionId: nodeVersion.id, + nodeUuid: node.uuid, + }) + ); + + await Promise.all(promises); + + // TODO: different resolver url for codex? :thinking: + const targetDpidUrl = getTargetDpidUrl(); + + discordNotify(`${targetDpidUrl}/${dpidAlias}`); + + /** + * Save the cover art for this Node for later sharing: PDF -> JPG for this version + */ + cacheNodeMetadata(node.uuid, cid); +}; + +/** + * Creates new dPID if legacyDpid is falsy, otherwise tries to upgrade + * the dPID by binding the stream in the alias registry for that dPID. +*/ +const createOrUpgradeDpidAlias = async ( + legacyDpid: number | undefined, + ceramicStream: string, + uuid: string, +): Promise => { + let dpidAlias: number; + if (legacyDpid) { + // Requires the REGISTRY_OWNER_PKEY to be set in env + dpidAlias = await upgradeDpid(legacyDpid, ceramicStream); + } else { + // Will nicely return the existing dpid if this is called multiple times + dpidAlias = await getOrCreateDpid(ceramicStream); + }; + await setDpidAlias(uuid, dpidAlias); + return dpidAlias; +}; + +type PublishData = { + nodeId: number, + nodeUuid: string, + userId: number, + manifestCid: string, + nodeVersionId: number, +}; + +const handlePublicDataRefs = async ( + params: PublishData, +): Promise => { + const { + nodeId, + nodeUuid, + userId, + manifestCid, + nodeVersionId, + } = params; + + const logger = parentLogger.child({ + module: 'NODE::handlePublicDataRefs', + uuid: nodeUuid, + cid: manifestCid, + }); + + /** + * Publish Step 1: + * Create public data refs and data mirror jobs from the CIDs in the manifest + */ + let cidsRequiredForPublish: Prisma.PublicDataReferenceCreateManyInput[] = []; + try { + /*** + * Traverse the DAG structure to find all relevant CIDs and get relevant info for indexing + */ + cidsRequiredForPublish = await getAllCidsRequiredForPublish( + manifestCid, + nodeUuid, + userId, + nodeId, + nodeVersionId + ); + + /** + * Index the DAGs from IPFS in order to avoid recurrent IPFS calls when requesting data in the future + */ + const newPublicDataRefs = await createPublicDataRefs( + cidsRequiredForPublish, + userId, + nodeVersionId, + ); + + /** + * Save a success for configurable service quality tracking purposes + */ + await saveInteractionWithoutReq( + ActionType.PUBLISH_NODE_CID_SUCCESS, + { + params, + result: { newPublicDataRefs }, + } + ); + } catch (error) { + logger.error({ error }, `[publish::publish] error=${error}`); + /** + * Save a failure for configurable service quality tracking purposes + */ + await saveInteractionWithoutReq( + ActionType.PUBLISH_NODE_CID_FAIL, + { + params, + error + } + ); + throw error; + }; +}; + export const publishHandler = async ({ transactionId, userId, @@ -232,107 +457,17 @@ export const publishHandler = async ({ logger.trace(`[publish::publish] nodeUuid=${node.uuid}, manifestCid=${cid}, transaction=${transactionId}`); - const cidsPayload = { - nodeId: node.id, - userId: owner.id, - manifestCid: cid, - nodeVersionId: nodeVersion.id, - nodeUuid: node.uuid, - }; - - /** - * Publish Step 1: - * Create public data refs and data mirror jobs from the CIDs in the manifest - */ - let cidsRequiredForPublish: Prisma.PublicDataReferenceCreateManyInput[] = []; - // debugger; - try { - /*** - * Traverse the DAG structure to find all relevant CIDs and get relevant info for indexing - */ - cidsRequiredForPublish = await getAllCidsRequiredForPublish(cid, node.uuid, owner.id, node.id, nodeVersion.id); - - /** - * Index the DAGs from IPFS in order to avoid recurrent IPFS calls when requesting data in the future - */ - const newPublicDataRefs = await createPublicDataRefs(cidsRequiredForPublish, owner.id, nodeVersion.id); - - /** - * Create a job per mirror in order to track the status of the upload - * There can be multiple mirrors per node, right now there is just Estuary - * - * NOTE: uncomment when reactivating public ref mirroring - const dataMirrorJobs = await createDataMirrorJobs(cidsRequiredForPublish, owner.id); - */ - - // TODO: update public data refs to link versionId - - /** - * Save a success for configurable service quality tracking purposes - */ - await saveInteractionWithoutReq(ActionType.PUBLISH_NODE_CID_SUCCESS, { - cidsPayload, - result: { newPublicDataRefs }, - }); - } catch (error) { - logger.error({ error }, `[publish::publish] error=${error}`); - /** - * Save a failure for configurable service quality tracking purposes - */ - await saveInteractionWithoutReq(ActionType.PUBLISH_NODE_CID_FAIL, { cidsPayload, error }); - throw error; - } + await handlePublicDataRefs({ + nodeId: node.id, + nodeUuid: node.uuid, + userId: owner.id, + manifestCid: cid, + nodeVersionId: nodeVersion.id, + }); - /** - * Publish Step 2: - * Initiate IPFS storage upload using Estuary - */ const manifest = await getManifestByCid(cid); - const targetDpidUrl = getTargetDpidUrl(); - - // const researchObjectToPublish = { uuid, cid, manifest, ownerId: owner.id }; - const sendDiscordNotification = (error: boolean) => { - const manifestSource = manifest as ResearchObjectV1; - discordNotify(`${targetDpidUrl}/${manifestSource.dpid?.id}${error ? ' (note: estuary-err)' : ''}`); - }; - - // Send an email update to all contributors - // await publishServices.sendVersionUpdateEmailToAllContributors({ node }); - - /** - * NOTE: uncomment when reactivating public ref mirroring - const handleMirrorSuccess = async (publishedResearchObjectResult) => { - await saveInteractionWithoutReq(ActionType.PUBLISH_NODE_RESEARCH_OBJECT_SUCCESS, { - researchObjectToPublish, - result: publishedResearchObjectResult, - }); - - sendDiscordNotification(false); - }; - const handleMirrorFail = async (error) => { - await saveInteractionWithoutReq(ActionType.PUBLISH_NODE_RESEARCH_OBJECT_FAIL, { - researchObjectToPublish, - error, - }); - - sendDiscordNotification(true); - }; - - const publicDataReferences = await prisma.publicDataReference.findMany({ - where: { - versionId: nodeVersion.id, - }, - }); - logger.debug( - { publicDataReferences }, - `[publish::publish] publicDataReferences=${JSON.stringify(publicDataReferences)}`, - ); - - // trigger ipfs storage upload, but don't wait for it to finish, will happen async - publishResearchObject(publicDataReferences).then(handleMirrorSuccess).catch(handleMirrorFail); - */ - sendDiscordNotification(false); + discordNotify(`${targetDpidUrl}/${manifest.dpid?.id}`); /** * Save the cover art for this Node for later sharing: PDF -> JPG for this version diff --git a/desci-server/src/workers/publish.ts b/desci-server/src/workers/publish.ts index 8d20eaad..d78b1484 100644 --- a/desci-server/src/workers/publish.ts +++ b/desci-server/src/workers/publish.ts @@ -7,7 +7,6 @@ import { prisma } from '../client.js'; import { publishHandler } from '../controllers/nodes/publish.js'; import { logger as parentLogger } from '../logger.js'; import { lockService } from '../redisClient.js'; -import { getManifestByCid } from '../services/data/processing.js'; import { fixDpid, getTargetDpidUrl } from '../services/fixDpid.js'; enum ProcessOutcome { @@ -25,7 +24,7 @@ const logger = parentLogger.child({ module: 'PUBLISH WORKER', hostname }); const checkTransaction = async (transactionId: string, uuid: string) => { const provider = ethers.getDefaultProvider(ETHEREUM_RPC_URL); - if (!process.env.MUTE_PUBLISH_WORKER) + if (!process.env.MUTE_PUBLISH_WORKER) { logger.info( { uuid, @@ -34,6 +33,7 @@ const checkTransaction = async (transactionId: string, uuid: string) => { }, 'TX::check transaction', ); + }; const tx = await provider.getTransactionReceipt(transactionId); logger.info({ tx, uuid, transactionId, ETHEREUM_RPC_URL, network: await provider.getNetwork() }, 'TX::Receipt'); @@ -58,8 +58,7 @@ async function processPublishQueue() { await fixDpid(task.dpid); } else { logger.warn('DPID URL not set, skipping dpid fix'); - } - + }; lockService.freeLock(task.transactionId); }) .catch((err) => { diff --git a/desci-server/yarn.lock b/desci-server/yarn.lock index 68750092..4db13310 100644 --- a/desci-server/yarn.lock +++ b/desci-server/yarn.lock @@ -1635,10 +1635,10 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@desci-labs/desci-contracts@0.2.5-rc3": - version "0.2.5-rc3" - resolved "https://registry.yarnpkg.com/@desci-labs/desci-contracts/-/desci-contracts-0.2.5-rc3.tgz#bd9f0b221bf4df295855a50853f35161ce6d066e" - integrity sha512-+b0TTZCZjceCw5DuVqCxu9LlkHBMvF5PHw2Q/5N+cuveb2YMtPcj+TlVAEfsi+HcgAiagqaUKWI9903Kf8X1IA== +"@desci-labs/desci-contracts@0.2.5-rc6": + version "0.2.5-rc6" + resolved "https://registry.yarnpkg.com/@desci-labs/desci-contracts/-/desci-contracts-0.2.5-rc6.tgz#5c95b517865beeed45630c40c389a9b28d89f39a" + integrity sha512-SoPFZ6RnhtlqISuV5fJ+YbiTbmuIMwYxm4Htg+ePj8flTe6iWbW9Ddj1Bo9y0XmRasgfrR8DTnbdNAnyX95Pdw== "@desci-labs/desci-models@0.2.7-rc3": version "0.2.7-rc3" From fc22f75e3040aaaba1c7b68b4cca698967035155 Mon Sep 17 00:00:00 2001 From: m0ar Date: Thu, 13 Jun 2024 16:44:46 +0200 Subject: [PATCH 136/278] server: fix leftover conflict marker --- desci-server/src/controllers/nodes/publish.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/desci-server/src/controllers/nodes/publish.ts b/desci-server/src/controllers/nodes/publish.ts index e4b03fba..70548c18 100644 --- a/desci-server/src/controllers/nodes/publish.ts +++ b/desci-server/src/controllers/nodes/publish.ts @@ -14,11 +14,6 @@ import { setCeramicStream, setDpidAlias, } from '../../services/nodeManager.js'; -<<<<<<< HEAD -import orcidApiService from '../../services/orcid.js'; -import { publishServices } from '../../services/PublishServices.js'; -======= ->>>>>>> a91865b (server: refactor publish flow, default to dpid alias registry unless overridden) import { discordNotify } from '../../utils/discordUtils.js'; import { ensureUuidEndsWithDot } from '../../utils.js'; import { getOrCreateDpid, upgradeDpid } from './createDpid.js'; From d9cdb6dc980658f022a5ab63a6d6207ab02828d6 Mon Sep 17 00:00:00 2001 From: m0ar Date: Fri, 14 Jun 2024 09:25:24 +0200 Subject: [PATCH 137/278] server: switch publish function with payload instead of env --- .env.example | 3 --- desci-server/src/controllers/nodes/publish.ts | 15 ++++++++++----- nodes-lib/src/api.ts | 3 +++ nodes-lib/test/root.spec.ts | 3 ++- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/.env.example b/.env.example index 4856b89f..3bddd15a 100755 --- a/.env.example +++ b/.env.example @@ -134,6 +134,3 @@ DOI_PREFIX=https://doi.org/10.62891 CROSSREF_API=https://api.crossref.org CROSSREF_API_KEY= CROSSREF_EMAIL= - -# Set this truthy to use legacy dPID publish -FALLBACK_LEGACY_DPID= diff --git a/desci-server/src/controllers/nodes/publish.ts b/desci-server/src/controllers/nodes/publish.ts index 70548c18..51743c33 100644 --- a/desci-server/src/controllers/nodes/publish.ts +++ b/desci-server/src/controllers/nodes/publish.ts @@ -25,6 +25,7 @@ export type PublishReqBody = { transactionId: string; ceramicStream?: string; commitId?: string; + useNewPublish: boolean; }; export type PublishRequest = Request & { @@ -41,8 +42,12 @@ export type PublishResBody = }; // call node publish service and add job to queue -export const publish = async (req: PublishRequest, res: Response, _next: NextFunction) => { - const { uuid, cid, manifest, transactionId, ceramicStream, commitId } = req.body; +export const publish = async ( + req: PublishRequest, + res: Response, + _next: NextFunction +) => { + const { uuid, cid, manifest, transactionId, ceramicStream, commitId, useNewPublish } = req.body; // debugger; const email = req.user.email; const logger = parentLogger.child({ @@ -57,6 +62,7 @@ export const publish = async (req: PublishRequest, res: Response commitId, email, user: req.user, + useNewPublish, }); if (!uuid || !cid || !manifest) { @@ -105,8 +111,7 @@ export const publish = async (req: PublishRequest, res: Response let publishTask: PublishTaskQueue | undefined; - // Do synchronous publish if the caller passed stream information - if (!process.env.FALLBACK_LEGACY_DPID) { + if (useNewPublish) { await syncPublish( ceramicStream, commitId, @@ -154,7 +159,7 @@ export const publish = async (req: PublishRequest, res: Response } catch (err) { logger.error({ err }, '[publish::publish] node-publish-err'); return res.status(400).send({ ok: false, error: err.message }); - } + }; }; /** diff --git a/nodes-lib/src/api.ts b/nodes-lib/src/api.ts index 28ba9374..0385a80f 100644 --- a/nodes-lib/src/api.ts +++ b/nodes-lib/src/api.ts @@ -323,6 +323,7 @@ type PublishParams = { nodeVersionId?: string, ceramicStream?: string, commitId?: string, + useNewPublish: boolean, }; /** Result of publishing a draft node */ @@ -356,6 +357,7 @@ export const publishNode = async ( manifest: publishResult.manifest, ceramicStream: publishResult.ceramicIDs.streamID, commitId: publishResult.ceramicIDs.commitID, + useNewPublish: true, }; try { @@ -417,6 +419,7 @@ export const publishDraftNode = async ( transactionId: publishResult.transactionId, ceramicStream: publishResult.ceramicIDs?.streamID, commitId: publishResult.ceramicIDs?.commitID, + useNewPublish: false, }; try { diff --git a/nodes-lib/test/root.spec.ts b/nodes-lib/test/root.spec.ts index 60af7ce2..b9efa213 100644 --- a/nodes-lib/test/root.spec.ts +++ b/nodes-lib/test/root.spec.ts @@ -383,7 +383,7 @@ describe("nodes-lib", () => { }); - describe.only("publishing ", async () => { + describe("publishing ", async () => { let uuid: string; let publishResult: PublishResponse; const did = await authorizedSessionDidFromSigner(testSigner, getResources()); @@ -490,6 +490,7 @@ describe("nodes-lib", () => { // make a regular publish pubResult = await publishNode(uuid, did); + await sleep(1000); }); test("migrates history to new stream", async () => { From d490ed94dc6c03506fbde753548d976f4bb843be Mon Sep 17 00:00:00 2001 From: m0ar Date: Fri, 14 Jun 2024 09:55:54 +0200 Subject: [PATCH 138/278] nodeslib: tweak test timeouts to reduce flakiness --- nodes-lib/test/root.spec.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/nodes-lib/test/root.spec.ts b/nodes-lib/test/root.spec.ts index b9efa213..8d43cdc1 100644 --- a/nodes-lib/test/root.spec.ts +++ b/nodes-lib/test/root.spec.ts @@ -329,7 +329,7 @@ describe("nodes-lib", () => { await sleep(5_000); await publishDraftNode(uuid, testSigner, did); // Allow graph node to index - await sleep(1_500); + await sleep(2_500); }); test("updates entry in dpid registry", async () => { @@ -370,7 +370,7 @@ describe("nodes-lib", () => { const codexHistory = await getCodexHistory(pubResult.ceramicIDs!.streamID); expect(dpidHistory.versions.length).toEqual(2); expect (codexHistory.length).toEqual(2); - }); + }, { timeout: 10_000}); /** This is not an user feature, but part of error handling during publish */ test("can remove dPID from manifest", async () => { @@ -448,6 +448,7 @@ describe("nodes-lib", () => { beforeAll(async () => { nodeStateBefore = await getDraftNode(uuid); updateResult = await publishNode(uuid, did); + await sleep(1000); }); test("updates most recent state", async () => { From be8bf3bc10d4e1d4916de6f527b8dabef2c7ead8 Mon Sep 17 00:00:00 2001 From: m0ar Date: Fri, 14 Jun 2024 10:07:53 +0200 Subject: [PATCH 139/278] unlink local deps in server and nodes-lib --- desci-server/package.json | 2 +- desci-server/yarn.lock | 8 ++++---- nodes-lib/package-lock.json | 14 +++++++------- nodes-lib/package.json | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/desci-server/package.json b/desci-server/package.json index 4a47a9ae..5ee83cb9 100755 --- a/desci-server/package.json +++ b/desci-server/package.json @@ -55,8 +55,8 @@ "@automerge/automerge-repo": "^1.0.19", "@automerge/automerge-repo-network-websocket": "^1.0.19", "@aws-sdk/client-s3": "^3.537.0", - "@desci-labs/desci-models": "0.2.7-rc3", "@desci-labs/desci-contracts": "0.2.5-rc6", + "@desci-labs/desci-models": "0.2.7-rc5", "@honeycombio/opentelemetry-node": "^0.3.2", "@ipld/dag-pb": "^4.0.0", "@opentelemetry/api": "^1.8.0", diff --git a/desci-server/yarn.lock b/desci-server/yarn.lock index 4db13310..087a09cf 100644 --- a/desci-server/yarn.lock +++ b/desci-server/yarn.lock @@ -1640,10 +1640,10 @@ resolved "https://registry.yarnpkg.com/@desci-labs/desci-contracts/-/desci-contracts-0.2.5-rc6.tgz#5c95b517865beeed45630c40c389a9b28d89f39a" integrity sha512-SoPFZ6RnhtlqISuV5fJ+YbiTbmuIMwYxm4Htg+ePj8flTe6iWbW9Ddj1Bo9y0XmRasgfrR8DTnbdNAnyX95Pdw== -"@desci-labs/desci-models@0.2.7-rc3": - version "0.2.7-rc3" - resolved "https://registry.yarnpkg.com/@desci-labs/desci-models/-/desci-models-0.2.7-rc3.tgz#b033073e6b77edde85491731d5c03469f443aaa1" - integrity sha512-RL1vwUHTumpmj7goX6+AcSVt0MGpdm4QWZ20gkmE9+BlL1eIxX+oQzQFmW92XXHWUQOETIaL1YnHsGCVz4gJNw== +"@desci-labs/desci-models@0.2.7-rc5": + version "0.2.7-rc5" + resolved "https://registry.yarnpkg.com/@desci-labs/desci-models/-/desci-models-0.2.7-rc5.tgz#fec8cd3372eaa22fd727d87fa8967a7c093e6d5f" + integrity sha512-mA3rpgaWfDAxO6BXejijP+mvmzvVTHPQ/vEyWkzeZ/V8DGUHzcScYAa6W5RD5mWRmFIAXGAg/zQuwaxw7PaOSg== dependencies: jsonld "^8.1.1" schema-dts "^1.1.2" diff --git a/nodes-lib/package-lock.json b/nodes-lib/package-lock.json index 38a0798b..f6908d89 100644 --- a/nodes-lib/package-lock.json +++ b/nodes-lib/package-lock.json @@ -10,7 +10,7 @@ "license": "MIT", "dependencies": { "@desci-labs/desci-codex-lib": "^1.1.7", - "@desci-labs/desci-contracts": "^0.2.5-rc1", + "@desci-labs/desci-contracts": "^0.2.5-rc6", "@desci-labs/desci-models": "^0.2.3-rc1", "@didtools/cacao": "^3.0.1", "@didtools/pkh-ethereum": "^0.5.0", @@ -1010,9 +1010,9 @@ } }, "node_modules/@desci-labs/desci-contracts": { - "version": "0.2.5-rc1", - "resolved": "https://registry.npmjs.org/@desci-labs/desci-contracts/-/desci-contracts-0.2.5-rc1.tgz", - "integrity": "sha512-wA4zDRp3GT3ZKo0/qFT2fKuLElQFXgycBnuaa2RPCOEfxQXFOqDYOyaqnhbklnutjit1MjwitiO6E6SFWzk6zg==" + "version": "0.2.5-rc6", + "resolved": "https://registry.npmjs.org/@desci-labs/desci-contracts/-/desci-contracts-0.2.5-rc6.tgz", + "integrity": "sha512-SoPFZ6RnhtlqISuV5fJ+YbiTbmuIMwYxm4Htg+ePj8flTe6iWbW9Ddj1Bo9y0XmRasgfrR8DTnbdNAnyX95Pdw==" }, "node_modules/@desci-labs/desci-models": { "version": "0.2.3-rc1", @@ -10840,9 +10840,9 @@ } }, "@desci-labs/desci-contracts": { - "version": "0.2.5-rc1", - "resolved": "https://registry.npmjs.org/@desci-labs/desci-contracts/-/desci-contracts-0.2.5-rc1.tgz", - "integrity": "sha512-wA4zDRp3GT3ZKo0/qFT2fKuLElQFXgycBnuaa2RPCOEfxQXFOqDYOyaqnhbklnutjit1MjwitiO6E6SFWzk6zg==" + "version": "0.2.5-rc6", + "resolved": "https://registry.npmjs.org/@desci-labs/desci-contracts/-/desci-contracts-0.2.5-rc6.tgz", + "integrity": "sha512-SoPFZ6RnhtlqISuV5fJ+YbiTbmuIMwYxm4Htg+ePj8flTe6iWbW9Ddj1Bo9y0XmRasgfrR8DTnbdNAnyX95Pdw==" }, "@desci-labs/desci-models": { "version": "0.2.3-rc1", diff --git a/nodes-lib/package.json b/nodes-lib/package.json index 1d4017f2..5cfeb804 100644 --- a/nodes-lib/package.json +++ b/nodes-lib/package.json @@ -27,7 +27,7 @@ }, "dependencies": { "@desci-labs/desci-codex-lib": "^1.1.7", - "@desci-labs/desci-contracts": "^0.2.5-rc5", + "@desci-labs/desci-contracts": "^0.2.5-rc6", "@desci-labs/desci-models": "^0.2.3-rc1", "@didtools/cacao": "^3.0.1", "@didtools/pkh-ethereum": "^0.5.0", From 2496773e24eb52e9aed4d7de303d5e9df5c4ad08 Mon Sep 17 00:00:00 2001 From: m0ar Date: Fri, 14 Jun 2024 10:13:36 +0200 Subject: [PATCH 140/278] contracts: cleanup hardhat config --- desci-contracts/hardhat.config.ts | 29 +++-------------------------- 1 file changed, 3 insertions(+), 26 deletions(-) diff --git a/desci-contracts/hardhat.config.ts b/desci-contracts/hardhat.config.ts index 393ef0e5..f088d2ec 100644 --- a/desci-contracts/hardhat.config.ts +++ b/desci-contracts/hardhat.config.ts @@ -50,34 +50,11 @@ module.exports = { mnemonic: process.env.MNEMONIC || DEFAULT_MNEMONIC, }, }, - rinkeby: { - chainId: 4, - saveDeployments: true, - providerType: "WebSocketProvider", - url: "http://eth-rinkeby.alchemyapi.io/v2/X6CiiZczzALlTM2mAIm_cJnpnFWKTu0l", - accounts: process.env.PRIVATE_KEY - ? [process.env.PRIVATE_KEY] - : { - mnemonic: process.env.MNEMONIC || DEFAULT_MNEMONIC, - }, - }, - goerli: { - chainId: 5, - live: true, - saveDeployments: true, - url: "https://eth-goerli.g.alchemy.com/v2/ZeIzCAJyPpRnTtPNSmddHGF-q2yp-2Uy", - accounts: process.env.PRIVATE_KEY - ? [process.env.PRIVATE_KEY] - : { - mnemonic: process.env.MNEMONIC || DEFAULT_MNEMONIC, - }, - gasPrice: 35000000000, - }, sepoliaDev: { chainId: 11155111, live: true, saveDeployments: true, - url: "https://eth-sepolia.g.alchemy.com/v2/Dg4eT90opKOFZ7w-YCxVwX9O-sriKn0N", + url: "https://reverse-proxy-dev.desci.com/rpc_sepolia", accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] : { @@ -89,7 +66,7 @@ module.exports = { chainId: 11155111, live: true, saveDeployments: true, - url: "https://eth-sepolia.g.alchemy.com/v2/Dg4eT90opKOFZ7w-YCxVwX9O-sriKn0N", + url: "https://reverse-proxy-dev.desci.com/rpc_sepolia", accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] : { @@ -113,7 +90,7 @@ module.exports = { chainId: 11155420, live: true, saveDeployments: true, - url: "https://opt-sepolia.g.alchemy.com/v2/vr-m5h17EAZPdtt88rpvkMy8kwo1-iig", //https://reverse-proxy-dev.desci.com/rpc_opt_sepolia", + url: "https://reverse-proxy-dev.desci.com/rpc_opt_sepolia", accounts: process.env.PRIVATE_KEY ? [ process.env.PRIVATE_KEY ] : { From 9ca0a93f53a67880555c8eda625119936392e81d Mon Sep 17 00:00:00 2001 From: m0ar Date: Fri, 14 Jun 2024 13:29:45 +0200 Subject: [PATCH 141/278] contracts: make it harder to accidentally run production env against new dev contracts --- desci-contracts/index.ts | 4 ++-- desci-contracts/package.json | 2 +- desci-server/package.json | 2 +- desci-server/yarn.lock | 8 ++++---- nodes-lib/package-lock.json | 14 +++++++------- nodes-lib/package.json | 2 +- nodes-lib/src/config/chain.ts | 2 +- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/desci-contracts/index.ts b/desci-contracts/index.ts index 960d0e4d..4f5d0fb8 100644 --- a/desci-contracts/index.ts +++ b/desci-contracts/index.ts @@ -17,6 +17,6 @@ export const contracts = { prodDpidInfo, localDpidAliasInfo, devDpidAliasInfo, - // TODO update as soon as deployment is done - prodDpidAliasInfo: localDpidAliasInfo, + // TODO update when opt mainnet contracts are deployed + prodDpidAliasInfo: { proxies: [ { address: "NOT_DEPLOYED" }]}, }; diff --git a/desci-contracts/package.json b/desci-contracts/package.json index f4c99c90..1ead0e72 100644 --- a/desci-contracts/package.json +++ b/desci-contracts/package.json @@ -1,7 +1,7 @@ { "name": "@desci-labs/desci-contracts", "description": "Smart contracts implementing DeSci Nodes on-chain state and logic", - "version": "0.2.5-rc6", + "version": "0.2.5-rc7", "license": "MIT", "scripts": { "test": "hardhat clean && hardhat test", diff --git a/desci-server/package.json b/desci-server/package.json index 5ee83cb9..11d8d5fb 100755 --- a/desci-server/package.json +++ b/desci-server/package.json @@ -55,7 +55,7 @@ "@automerge/automerge-repo": "^1.0.19", "@automerge/automerge-repo-network-websocket": "^1.0.19", "@aws-sdk/client-s3": "^3.537.0", - "@desci-labs/desci-contracts": "0.2.5-rc6", + "@desci-labs/desci-contracts": "0.2.5-rc7", "@desci-labs/desci-models": "0.2.7-rc5", "@honeycombio/opentelemetry-node": "^0.3.2", "@ipld/dag-pb": "^4.0.0", diff --git a/desci-server/yarn.lock b/desci-server/yarn.lock index 087a09cf..c13101e3 100644 --- a/desci-server/yarn.lock +++ b/desci-server/yarn.lock @@ -1635,10 +1635,10 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@desci-labs/desci-contracts@0.2.5-rc6": - version "0.2.5-rc6" - resolved "https://registry.yarnpkg.com/@desci-labs/desci-contracts/-/desci-contracts-0.2.5-rc6.tgz#5c95b517865beeed45630c40c389a9b28d89f39a" - integrity sha512-SoPFZ6RnhtlqISuV5fJ+YbiTbmuIMwYxm4Htg+ePj8flTe6iWbW9Ddj1Bo9y0XmRasgfrR8DTnbdNAnyX95Pdw== +"@desci-labs/desci-contracts@0.2.5-rc7": + version "0.2.5-rc7" + resolved "https://registry.yarnpkg.com/@desci-labs/desci-contracts/-/desci-contracts-0.2.5-rc7.tgz#a8a49c9518107305be712bcbdbb352faa4057a44" + integrity sha512-W1hf+mv5KWnqCuXX3uBiBsll+iMD82GJbsGs3huzH6qY2TySVFUCLov017B0RGz2Ap1WRB9w7h3o9CEwDuV5lQ== "@desci-labs/desci-models@0.2.7-rc5": version "0.2.7-rc5" diff --git a/nodes-lib/package-lock.json b/nodes-lib/package-lock.json index f6908d89..84fd74ba 100644 --- a/nodes-lib/package-lock.json +++ b/nodes-lib/package-lock.json @@ -10,7 +10,7 @@ "license": "MIT", "dependencies": { "@desci-labs/desci-codex-lib": "^1.1.7", - "@desci-labs/desci-contracts": "^0.2.5-rc6", + "@desci-labs/desci-contracts": "^0.2.5-rc7", "@desci-labs/desci-models": "^0.2.3-rc1", "@didtools/cacao": "^3.0.1", "@didtools/pkh-ethereum": "^0.5.0", @@ -1010,9 +1010,9 @@ } }, "node_modules/@desci-labs/desci-contracts": { - "version": "0.2.5-rc6", - "resolved": "https://registry.npmjs.org/@desci-labs/desci-contracts/-/desci-contracts-0.2.5-rc6.tgz", - "integrity": "sha512-SoPFZ6RnhtlqISuV5fJ+YbiTbmuIMwYxm4Htg+ePj8flTe6iWbW9Ddj1Bo9y0XmRasgfrR8DTnbdNAnyX95Pdw==" + "version": "0.2.5-rc7", + "resolved": "https://registry.npmjs.org/@desci-labs/desci-contracts/-/desci-contracts-0.2.5-rc7.tgz", + "integrity": "sha512-W1hf+mv5KWnqCuXX3uBiBsll+iMD82GJbsGs3huzH6qY2TySVFUCLov017B0RGz2Ap1WRB9w7h3o9CEwDuV5lQ==" }, "node_modules/@desci-labs/desci-models": { "version": "0.2.3-rc1", @@ -10840,9 +10840,9 @@ } }, "@desci-labs/desci-contracts": { - "version": "0.2.5-rc6", - "resolved": "https://registry.npmjs.org/@desci-labs/desci-contracts/-/desci-contracts-0.2.5-rc6.tgz", - "integrity": "sha512-SoPFZ6RnhtlqISuV5fJ+YbiTbmuIMwYxm4Htg+ePj8flTe6iWbW9Ddj1Bo9y0XmRasgfrR8DTnbdNAnyX95Pdw==" + "version": "0.2.5-rc7", + "resolved": "https://registry.npmjs.org/@desci-labs/desci-contracts/-/desci-contracts-0.2.5-rc7.tgz", + "integrity": "sha512-W1hf+mv5KWnqCuXX3uBiBsll+iMD82GJbsGs3huzH6qY2TySVFUCLov017B0RGz2Ap1WRB9w7h3o9CEwDuV5lQ==" }, "@desci-labs/desci-models": { "version": "0.2.3-rc1", diff --git a/nodes-lib/package.json b/nodes-lib/package.json index 5cfeb804..9a6fa008 100644 --- a/nodes-lib/package.json +++ b/nodes-lib/package.json @@ -27,7 +27,7 @@ }, "dependencies": { "@desci-labs/desci-codex-lib": "^1.1.7", - "@desci-labs/desci-contracts": "^0.2.5-rc6", + "@desci-labs/desci-contracts": "^0.2.5-rc7", "@desci-labs/desci-models": "^0.2.3-rc1", "@didtools/cacao": "^3.0.1", "@didtools/pkh-ethereum": "^0.5.0", diff --git a/nodes-lib/src/config/chain.ts b/nodes-lib/src/config/chain.ts index 3f1c72b0..d11da6fc 100644 --- a/nodes-lib/src/config/chain.ts +++ b/nodes-lib/src/config/chain.ts @@ -117,7 +117,7 @@ export const CHAIN_CONFIGS = { chainId: "10", rpcUrl: "https://reverse-proxy-prod.desci.com/rpc_opt_mainnet", dpidAliasRegistryConnector: signerOrProvider => tc.DpidAliasRegistry__factory.connect( - "NOT_DEPLOYED",//contracts.prodDpidAliasInfo.proxies.at(0)!.address, + contracts.prodDpidAliasInfo.proxies.at(0)!.address, signerOrProvider, ), } From e15b288dfbb61e49301a12b10b45cdeb4125fd85 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Sat, 15 Jun 2024 12:08:21 +0200 Subject: [PATCH 142/278] implement cross ref post metadata api --- .env.example | 6 +- .env.test | 8 +- desci-server/kubernetes/deployment_dev.yaml | 4 + desci-server/kubernetes/deployment_prod.yaml | 4 + .../kubernetes/deployment_staging.yaml | 4 + desci-server/package.json | 3 +- desci-server/src/core/doi/error.ts | 7 + desci-server/src/services/Doi.ts | 17 ++- desci-server/src/services/crossRef/client.ts | 132 +++++++++++++++++- desci-server/src/types/ProcessEnv.d.ts | 5 + desci-server/yarn.lock | 36 ++--- 11 files changed, 187 insertions(+), 39 deletions(-) diff --git a/.env.example b/.env.example index 37ff994f..7b0d9920 100755 --- a/.env.example +++ b/.env.example @@ -124,9 +124,13 @@ MUTE_PUBLISH_WORKER=false # SingleNodeLockServce MAX_LOCK_TIME=3600 # 1 hour -DOI_PREFIX=https://doi.org/10.62891 +DOI_PREFIX=10.62891 +CROSSREF_DOI_URL=https://doi.org # Cross ref api CROSSREF_API=https://api.crossref.org +CROSSREF_METADATA_API=https://test.crossref.org/servlet/deposit CROSSREF_API_KEY= CROSSREF_EMAIL= +CROSSREF_LOGIN= +CROSSREF_PASSWORD= \ No newline at end of file diff --git a/.env.test b/.env.test index 8e78ffe8..bf9f406f 100644 --- a/.env.test +++ b/.env.test @@ -74,9 +74,13 @@ NODES_MEDIA_SERVER_URL=http://host.docker.internal:5454 REPO_SERVICE_SECRET_KEY="m8sIy5BPygBcX3+ZmMVuAA10k6w59BSCZd+Z5+VLYm4=" REPO_SERVER_URL=http://host.docker.internal:5485 -DOI_PREFIX=https://doi.org/10.62891 +DOI_PREFIX=10.62891 +CROSSREF_DOI_URL=https://doi.org # Cross ref api CROSSREF_API=https://api.crossref.org +CROSSREF_METADATA_API=https://test.crossref.org/servlet/deposit CROSSREF_API_KEY= -CROSSREF_EMAIL= \ No newline at end of file +CROSSREF_EMAIL= +CROSSREF_LOGIN= +CROSSREF_PASSWORD= \ No newline at end of file diff --git a/desci-server/kubernetes/deployment_dev.yaml b/desci-server/kubernetes/deployment_dev.yaml index a9dec132..bb2df633 100644 --- a/desci-server/kubernetes/deployment_dev.yaml +++ b/desci-server/kubernetes/deployment_dev.yaml @@ -83,6 +83,10 @@ spec: export CROSSREF_API={{ .Data.CROSSREF_API }} export CROSSREF_API_KEY={{ .Data.CROSSREF_API_KEY }} export CROSSREF_EMAIL={{ .Data.CROSSREF_EMAIL }} + export CROSSREF_DOI_URL={{ .Data.CROSSREF_DOI_URL }} + export CROSSREF_LOGIN={{ .Data.CROSSREF_LOGIN }} + export CROSSREF_PASSWORD={{ .Data.CROSSREF_PASSWORD }} + export CROSSREF_METADATA_API={{ .Data.CROSSREF_METADATA_API }} export DEBUG_TEST=0; echo "appfinish"; {{- end -}} diff --git a/desci-server/kubernetes/deployment_prod.yaml b/desci-server/kubernetes/deployment_prod.yaml index 433c06e9..4c45df14 100755 --- a/desci-server/kubernetes/deployment_prod.yaml +++ b/desci-server/kubernetes/deployment_prod.yaml @@ -83,6 +83,10 @@ spec: export CROSSREF_API={{ .Data.CROSSREF_API }} export CROSSREF_API_KEY={{ .Data.CROSSREF_API_KEY }} export CROSSREF_EMAIL={{ .Data.CROSSREF_EMAIL }} + export CROSSREF_DOI_URL={{ .Data.CROSSREF_DOI_URL }} + export CROSSREF_LOGIN={{ .Data.CROSSREF_LOGIN }} + export CROSSREF_PASSWORD={{ .Data.CROSSREF_PASSWORD }} + export CROSSREF_METADATA_API={{ .Data.CROSSREF_METADATA_API }} export IGNORE_LINE=0; export DEBUG_TEST=0; echo "appfinish"; diff --git a/desci-server/kubernetes/deployment_staging.yaml b/desci-server/kubernetes/deployment_staging.yaml index 37f173ed..cd445f19 100644 --- a/desci-server/kubernetes/deployment_staging.yaml +++ b/desci-server/kubernetes/deployment_staging.yaml @@ -95,6 +95,10 @@ spec: export CROSSREF_API={{ .Data.CROSSREF_API }} export CROSSREF_API_KEY={{ .Data.CROSSREF_API_KEY }} export CROSSREF_EMAIL={{ .Data.CROSSREF_EMAIL }} + export CROSSREF_DOI_URL={{ .Data.CROSSREF_DOI_URL }} + export CROSSREF_LOGIN={{ .Data.CROSSREF_LOGIN }} + export CROSSREF_PASSWORD={{ .Data.CROSSREF_PASSWORD }} + export CROSSREF_METADATA_API={{ .Data.CROSSREF_METADATA_API }} export DEBUG_TEST=0; echo "appfinish"; {{- end -}} diff --git a/desci-server/package.json b/desci-server/package.json index bf462d4f..a9b090a2 100755 --- a/desci-server/package.json +++ b/desci-server/package.json @@ -105,6 +105,7 @@ "react-email": "2.1.0", "redis": "^4.6.7", "reflect-metadata": "^0.1.13", + "remixml": "^7.0.5", "request": "^2.88.2", "rimraf": "^5.0.1", "short-unique-id": "^4.4.4", @@ -174,4 +175,4 @@ "prisma": { "seed": "node --no-warnings=ExperimentalWarning --loader ts-node/esm prisma/seed.ts" } -} \ No newline at end of file +} diff --git a/desci-server/src/core/doi/error.ts b/desci-server/src/core/doi/error.ts index 613079f2..ef8b1830 100644 --- a/desci-server/src/core/doi/error.ts +++ b/desci-server/src/core/doi/error.ts @@ -3,6 +3,7 @@ export enum DoiErrorType { NO_MANUSCRIPT = 'NoManuscriptError', BAD_METADATA = 'InvalidManifestError', INCOMPLETE_ATTESTATIONS = 'ForbiddenError', + REGISTRATION_ERROR = 'RegistrationError', } export class DoiError extends Error { @@ -39,3 +40,9 @@ export class DuplicateMintError extends DoiError { super(DoiErrorType.DUPLICATE_MINT, message); } } + +export class MintError extends DoiError { + constructor(message = 'An Error occurred while registring a new DOI') { + super(DoiErrorType.DUPLICATE_MINT, message); + } +} diff --git a/desci-server/src/services/Doi.ts b/desci-server/src/services/Doi.ts index b31c9191..cacc1569 100644 --- a/desci-server/src/services/Doi.ts +++ b/desci-server/src/services/Doi.ts @@ -2,7 +2,7 @@ import { PdfComponent, ResearchObjectComponentType, ResearchObjectV1 } from '@de import { PrismaClient } from '@prisma/client'; import { v4 } from 'uuid'; -import { DuplicateMintError, BadManifestError, AttestationsError } from '../core/doi/error.js'; +import { DuplicateMintError, BadManifestError, AttestationsError, MintError } from '../core/doi/error.js'; import { logger } from '../logger.js'; import { IndexedResearchObject, getIndexedResearchObjects } from '../theGraph.js'; import { asyncMap, ensureUuidEndsWithDot, hexToCid } from '../utils.js'; @@ -72,7 +72,7 @@ export class DoiService { assertValidManifest(manifest: ResearchObjectV1) { const hasTitle = manifest.title.trim().length > 0; - const hasAbstract = manifest.description.trim().length > 0; + const hasAbstract = manifest?.description.trim().length > 0; const hasContributors = manifest.authors.length > 0; if (!hasTitle || !hasAbstract || !hasContributors) throw new BadManifestError(); } @@ -118,16 +118,21 @@ export class DoiService { // validate title, abstract and contributors this.assertValidManifest(latestManifest); - return { dpid: latestManifest.dpid.id, uuid }; + return { dpid: latestManifest.dpid.id, uuid, manifest: latestManifest }; } async mintDoi(nodeUuid: string) { - const { dpid, uuid } = await this.checkMintability(nodeUuid); - // todo: handle over logic to cross-ref api service for minting DOIs + const { dpid, uuid, manifest } = await this.checkMintability(nodeUuid); // mint new doi const doiSuffix = v4().substring(0, 8); const doi = `${DOI_PREFIX}/${doiSuffix}`; - logger.info({ doiSuffix, doi, uuid }, 'MINT DOI'); + // todo: handle over logic to cross-ref api service for minting DOIs + const metadataResponse = await crossRefClient.postMetadata({ manifest, doi }); + if (!metadataResponse.ok) { + throw new MintError(metadataResponse.message || 'A doi could not be registered for this node'); + } + + logger.info({ doiSuffix, doi, uuid, metadataResponse }, 'MINT DOI'); return await this.dbClient.doiRecord.create({ data: { uuid, diff --git a/desci-server/src/services/crossRef/client.ts b/desci-server/src/services/crossRef/client.ts index deb362ff..6f154b91 100644 --- a/desci-server/src/services/crossRef/client.ts +++ b/desci-server/src/services/crossRef/client.ts @@ -1,3 +1,8 @@ +import { ResearchObjectV1 } from '@desci-labs/desci-models'; +import FormData from 'form-data'; +import fetch from 'node-fetch'; +import { default as Remixml } from 'remixml'; + import { logger as parentLogger } from '../../logger.js'; import { ONE_DAY_TTL, getFromCache, setToCache } from '../../redisClient.js'; @@ -10,6 +15,70 @@ export const delay = async (timeMs: number) => { return new Promise((resolve) => setTimeout(resolve, timeMs)); }; +const metadataTemplate = ` + + + none + &_.timestamp; + + &depositor.name; + &depositor.email; + + &_.registrant; + + + + &_.title; + + + + &_.name; + &_.surname; + &_.orcid; + + + + + &_.title; + + + &publishedDate.month; + &publishedDate.day; + &publishedDate.year; + + + &publishedDate.month; + &publishedDate.day; + &publishedDate.year; + + + Crossref + https://ror.org/02twcfp32 + https://www.isni.org/0000000405062673 + https://www.wikidata.org/entity/Q5188229 + + CR + Lynnfield, MA + Feline Outreach + + &_.dpid; + + + http://example.org/license_page.html + + + &_.doi; + &_.doiResource; + + + + +`; + /** * A wrapper http client for querying, caching and parsing requests * from the CrossRef Rest Api https://www.crossref.org/documentation/retrieve-metadata/rest-api/ @@ -98,12 +167,73 @@ class CrossRefClient { } } + async postMetadata(query: { manifest: ResearchObjectV1; doi: string }) { + const param = { + _: { + timestamp: Date.now(), + dpid: query.manifest.dpid.id, + doi: query.doi, + doiResource: `https://dev-beta.dpid.org/${query.manifest.dpid.id}`, + title: query.manifest.title, + registrant: 'Desci Labs', + contributors: query.manifest.authors.map((author) => ({ + name: author.name.split(' ')[0], + surname: author.name.split(' ').slice(1)?.join(' ') || '-', + orcid: `https://${process.env.ORCID_API_DOMAIN}/${author.orcid}`, + })), + }, + depositor: { + name: 'Desci Labs', + email: 'admin@desci.com', + }, + publishedDate: { + day: 25, + month: '06', + year: 2024, + startDate: '2024-06-05', + }, + }; + + const metadata = Remixml.parse2txt(metadataTemplate, param); + + const url = `${process.env.CROSSREF_METADATA_API}?operation=doMDUpload&login_id=${process.env.CROSSREF_LOGIN || 'dslb'}&login_passwd=${process.env.CROSSREF_PASSWORD || 'pgz6wze1fmg-RPN_qkv'}`; + logger.info({ param, metadata, url }, 'METADATA TO POST'); + const buffer = Buffer.from(metadata, 'utf8'); + const filename = `dpid_${param._.dpid}_upload_xml.xml`; + // save file for debugging purposes + // await fs.writeFile(path.join(process.cwd(), filename), buffer); + const form = new FormData(); + form.append('fname', filename); + form.append('file', buffer, { filename }); + + try { + const response = await fetch(url, { + method: 'POST', + body: form, + headers: { + Accept: '*/*', + }, + }); + logger.info({ STATUS: response.status, message: response.statusText }, 'Response'); + const body = await response.text(); + logger.info({ body }, 'BODY'); + + if (!response.ok || response.status !== 200) { + return { ok: false, message: body }; + } + return { ok: true }; + } catch (error) { + logger.error(error, 'Post metadata Api Error'); + return { ok: false }; + } + } + async performFetch(request: Request) { const responseFromCache = await getFromCache(request.url); logger.info(responseFromCache, 'DOI From Cache'); if (responseFromCache) return { ok: true, status: 200, data: responseFromCache }; - const response = (await fetch(request)) as CrossRefHttpResponse; + const response = (await global.fetch(request)) as CrossRefHttpResponse; response.data = undefined; if (response.ok && response.status === 200) { if (response.headers.get('content-type').includes('application/json')) { diff --git a/desci-server/src/types/ProcessEnv.d.ts b/desci-server/src/types/ProcessEnv.d.ts index b7bbcda1..84e6a17f 100755 --- a/desci-server/src/types/ProcessEnv.d.ts +++ b/desci-server/src/types/ProcessEnv.d.ts @@ -12,6 +12,11 @@ declare namespace NodeJS { MAX_LOCK_TIME: string; CROSSREF_API: string; CROSSREF_EMAIL: string; + CROSSREF_DOI_URL: string; CROSSREF_API_KEY: string; + CROSSREF_METADATA_API: string; + ORCID_API_DOMAIN: string; + CROSSREF_LOGIN: string; + CROSSREF_PASSWORD: string; } } diff --git a/desci-server/yarn.lock b/desci-server/yarn.lock index 7357a32d..d8597d15 100644 --- a/desci-server/yarn.lock +++ b/desci-server/yarn.lock @@ -12204,6 +12204,11 @@ release-zalgo@^1.0.0: dependencies: es6-error "^4.0.1" +remixml@^7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/remixml/-/remixml-7.0.5.tgz#9efef9940ab8b210ff4860571b54707001a32a13" + integrity sha512-fmCQNur7ozfm6cDcMrKnuWm6sh4RDcAWTCXf5sRCj7MATcuG02mZ10iOx1uzOmsO6xlaRMFbaKk7MYSzBncaag== + request@^2.88.2: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" @@ -12850,16 +12855,7 @@ string-template@~0.2.1: resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" integrity sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw== -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -12932,7 +12928,7 @@ stringify-object@3.3.0: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -12946,13 +12942,6 @@ strip-ansi@^3.0.0: dependencies: ansi-regex "^2.0.0" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^7.0.1: version "7.1.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" @@ -13832,7 +13821,7 @@ workerpool@6.2.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -13850,15 +13839,6 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" From 3bac6ee0d01b783b198fa2490ce619995616cbcc Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Sun, 16 Jun 2024 22:17:40 +0200 Subject: [PATCH 143/278] make cookie auth isolated per environment, preventing collisions across nodes-api-dev nodes-api-staging and nodes-api --- desci-repo/.env.example | 1 + desci-repo/kubernetes/deployment_dev.yaml | 1 + desci-repo/kubernetes/deployment_prod.yaml | 1 + desci-repo/kubernetes/deployment_staging.yaml | 1 + desci-repo/src/middleware/permissions.ts | 12 +++++++++++- desci-server/src/controllers/auth/logout.ts | 8 +++++--- desci-server/src/middleware/permissions.ts | 3 ++- desci-server/src/utils/sendCookie.ts | 16 +++++++++++++--- 8 files changed, 35 insertions(+), 8 deletions(-) diff --git a/desci-repo/.env.example b/desci-repo/.env.example index 2e202f8b..2fea7a89 100644 --- a/desci-repo/.env.example +++ b/desci-repo/.env.example @@ -3,3 +3,4 @@ NODE_ENV=dev JWT_SECRET=secretshhh DATABASE_URL=postgresql://walter:white@db_boilerplate:5432/boilerplate IPFS_RESOLVER_OVERRIDE=http://host.docker.internal:8089/ipfs +# DESCI_SERVER_URL= \ No newline at end of file diff --git a/desci-repo/kubernetes/deployment_dev.yaml b/desci-repo/kubernetes/deployment_dev.yaml index 7bf69344..376fb258 100644 --- a/desci-repo/kubernetes/deployment_dev.yaml +++ b/desci-repo/kubernetes/deployment_dev.yaml @@ -48,6 +48,7 @@ spec: export JWT_SECRET={{ .Data.JWT_SECRET }} export DATABASE_URL={{ .Data.DATABASE_URL }} export IPFS_RESOLVER_OVERRIDE={{ .Data.IPFS_RESOLVER_OVERRIDE }} + export DESCI_SERVER_URL={{ .Data.DESCI_SERVER_URL }} {{- end -}} labels: diff --git a/desci-repo/kubernetes/deployment_prod.yaml b/desci-repo/kubernetes/deployment_prod.yaml index a222ee37..a48e23ca 100755 --- a/desci-repo/kubernetes/deployment_prod.yaml +++ b/desci-repo/kubernetes/deployment_prod.yaml @@ -49,6 +49,7 @@ spec: export JWT_SECRET={{ .Data.JWT_SECRET }} export DATABASE_URL={{ .Data.DATABASE_URL }} export IPFS_RESOLVER_OVERRIDE={{ .Data.IPFS_RESOLVER_OVERRIDE }} + export DESCI_SERVER_URL={{ .Data.DESCI_SERVER_URL }} {{- end -}} labels: diff --git a/desci-repo/kubernetes/deployment_staging.yaml b/desci-repo/kubernetes/deployment_staging.yaml index d6081ed1..caa89543 100644 --- a/desci-repo/kubernetes/deployment_staging.yaml +++ b/desci-repo/kubernetes/deployment_staging.yaml @@ -49,6 +49,7 @@ spec: export JWT_SECRET={{ .Data.JWT_SECRET }} export DATABASE_URL={{ .Data.DATABASE_URL }} export IPFS_RESOLVER_OVERRIDE={{ .Data.IPFS_RESOLVER_OVERRIDE }} + export DESCI_SERVER_URL={{ .Data.DESCI_SERVER_URL }} {{- end -}} labels: diff --git a/desci-repo/src/middleware/permissions.ts b/desci-repo/src/middleware/permissions.ts index 06d7334b..87cce971 100644 --- a/desci-repo/src/middleware/permissions.ts +++ b/desci-repo/src/middleware/permissions.ts @@ -25,6 +25,16 @@ export const ensureUser = async (req: ExpressRequest, res: Response, next: NextF } }; +const AUTH_COOKIE_DOMAIN_MAPPING = { + 'https://nodes-api.desci.com': 'auth', + 'https://nodes-api-dev.desci.com': 'auth-dev', + 'https://nodes-api-stage.desci.com': 'auth-stage', +}; + +// auth, auth-stage, auth-dev +export const AUTH_COOKIE_FIELDNAME = + AUTH_COOKIE_DOMAIN_MAPPING[process.env.DESCI_SERVER_URL || 'https://nodes-api.desci.com'] || 'auth'; + /** * Extract JWT Authorisation token from IncommingRequest */ @@ -43,7 +53,7 @@ export const extractAuthToken = async (request: ExpressRequest | Request) => { // If auth token wasn't found in the header, try retrieve from cookies if (!token && request['cookies']) { - token = request['cookies']['auth']; + token = request['cookies'][AUTH_COOKIE_FIELDNAME]; } // If Auth token is null and request.headers.cookie is valid, attempt to parse auth token from cookie diff --git a/desci-server/src/controllers/auth/logout.ts b/desci-server/src/controllers/auth/logout.ts index 1ddc0e93..92e32a15 100755 --- a/desci-server/src/controllers/auth/logout.ts +++ b/desci-server/src/controllers/auth/logout.ts @@ -1,10 +1,12 @@ import { Request, Response, NextFunction } from 'express'; +import { AUTH_COOKIE_FIELDNAME } from '../../utils/sendCookie.js'; + export const logout = async (req: Request, res: Response, next: NextFunction) => { // req.session.destroy((err) => { // if you send data here it gives an error and kills the process lol // }); - res.cookie('auth', 'unset', { + res.cookie(AUTH_COOKIE_FIELDNAME, 'unset', { maxAge: 0, httpOnly: true, // Ineffective whilst we still return the bearer token to the client in the response secure: process.env.NODE_ENV === 'production', @@ -14,7 +16,7 @@ export const logout = async (req: Request, res: Response, next: NextFunction) => }); (process.env.COOKIE_DOMAIN?.split(',') || [undefined]).map((domain) => { - res.cookie('auth', 'unset', { + res.cookie(AUTH_COOKIE_FIELDNAME, 'unset', { maxAge: 0, httpOnly: true, // Ineffective whilst we still return the bearer token to the client in the response secure: process.env.NODE_ENV === 'production', @@ -26,7 +28,7 @@ export const logout = async (req: Request, res: Response, next: NextFunction) => if (process.env.SERVER_URL === 'https://nodes-api-dev.desci.com') { // insecure cookie for local dev, should only be used for testing - res.cookie('auth', 'unset', { + res.cookie(AUTH_COOKIE_FIELDNAME, 'unset', { maxAge: 0, httpOnly: true, sameSite: 'strict', diff --git a/desci-server/src/middleware/permissions.ts b/desci-server/src/middleware/permissions.ts index 1e9b33c1..112f2e5c 100644 --- a/desci-server/src/middleware/permissions.ts +++ b/desci-server/src/middleware/permissions.ts @@ -6,6 +6,7 @@ import { prisma } from '../client.js'; import { hashApiKey } from '../controllers/auth/utils.js'; import { logger } from '../logger.js'; import { getUserByEmail, getUserByOrcId } from '../services/user.js'; +import { AUTH_COOKIE_FIELDNAME } from '../utils/sendCookie.js'; export enum AuthMethods { AUTH_TOKEN = 'AUTH_TOKEN', @@ -32,7 +33,7 @@ export const ensureUser = async (req: ExpressRequest, res: Response, next: NextF * Extract JWT Authorisation token from IncommingRequest */ export const extractAuthToken = async (request: ExpressRequest | Request) => { - let token = await extractTokenFromCookie(request, 'auth'); + let token = await extractTokenFromCookie(request, AUTH_COOKIE_FIELDNAME); if (!token) { // Try to retrieve the token from the header diff --git a/desci-server/src/utils/sendCookie.ts b/desci-server/src/utils/sendCookie.ts index 18428d72..f2efdcf9 100644 --- a/desci-server/src/utils/sendCookie.ts +++ b/desci-server/src/utils/sendCookie.ts @@ -2,12 +2,22 @@ import { type Response } from 'express'; import { oneDay, oneMinute, oneYear } from '../controllers/auth/magic.js'; import { logger } from '../logger.js'; -export const sendCookie = (res: Response, token: string, isDevMode: boolean, cookieName = 'auth') => { + +const AUTH_COOKIE_DOMAIN_MAPPING = { + 'https://nodes-api.desci.com': 'auth', + 'https://nodes-api-dev.desci.com': 'auth-dev', + 'https://nodes-api-staging.desci.com': 'auth-stage', +}; + +// auth, auth-stage, auth-dev +export const AUTH_COOKIE_FIELDNAME = AUTH_COOKIE_DOMAIN_MAPPING[process.env.SERVER_URL] || 'auth'; + +export const sendCookie = (res: Response, token: string, isDevMode: boolean, cookieName = AUTH_COOKIE_FIELDNAME) => { if (isDevMode && process.env.SERVER_URL === 'https://nodes-api-dev.desci.com') { // insecure cookie for local dev, should only be used for testing logger.info({ fn: 'sendCookie' }, `insecure dev cookie set`); res.cookie(cookieName, token, { - maxAge: cookieName === 'auth' ? oneDay : oneMinute, + maxAge: cookieName === AUTH_COOKIE_FIELDNAME ? oneDay : oneMinute, httpOnly: true, sameSite: 'strict', }); @@ -16,7 +26,7 @@ export const sendCookie = (res: Response, token: string, isDevMode: boolean, coo (process.env.COOKIE_DOMAIN?.split(',') || [undefined]).map((domain) => { logger.info({ fn: 'sendCookie', domain, env: process.env.NODE_ENV }, `cookie set`); res.cookie(cookieName, token, { - maxAge: cookieName === 'auth' ? oneYear : oneMinute, + maxAge: cookieName === AUTH_COOKIE_FIELDNAME ? oneYear : oneMinute, httpOnly: true, // Ineffective whilst we still return the bearer token to the client in the response secure: process.env.NODE_ENV === 'production', domain: process.env.NODE_ENV === 'production' ? domain || '.desci.com' : 'localhost', From 2cfd0b3ccb16856f56c4a8957d1d7378f8f2bf9d Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Sun, 16 Jun 2024 22:35:01 +0200 Subject: [PATCH 144/278] comment --- desci-server/src/utils/sendCookie.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/desci-server/src/utils/sendCookie.ts b/desci-server/src/utils/sendCookie.ts index f2efdcf9..f7e759ab 100644 --- a/desci-server/src/utils/sendCookie.ts +++ b/desci-server/src/utils/sendCookie.ts @@ -3,6 +3,10 @@ import { type Response } from 'express'; import { oneDay, oneMinute, oneYear } from '../controllers/auth/magic.js'; import { logger } from '../logger.js'; +/** + * To enable a wildcard auth cookie that works across all subdomains, we need to modify the auth cookie name for each domain. + */ + const AUTH_COOKIE_DOMAIN_MAPPING = { 'https://nodes-api.desci.com': 'auth', 'https://nodes-api-dev.desci.com': 'auth-dev', From 5be71e33f4310491e1f9956b012c68aafef4e079 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Mon, 17 Jun 2024 16:55:14 +0000 Subject: [PATCH 145/278] fix broken test causing tests to hang --- desci-server/test/integration/Attestation.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desci-server/test/integration/Attestation.test.ts b/desci-server/test/integration/Attestation.test.ts index 71a9cbc7..05966d43 100644 --- a/desci-server/test/integration/Attestation.test.ts +++ b/desci-server/test/integration/Attestation.test.ts @@ -1508,7 +1508,7 @@ describe('Attestations Service', async () => { it('should show DPID 1 node attestations(API)', async () => { const JwtToken = jwt.sign({ email: users[0].email }, process.env.JWT_SECRET!, { expiresIn: '1y' }); const authHeaderVal = `Bearer ${JwtToken}`; - const res = await request(app).get(`/v1/attestations/${node1.uuid}`).set('authorization', authHeaderVal); + const res = await request(app).get(`/v1/attestations/${node.uuid}`).set('authorization', authHeaderVal); const attestations: NodeAttestationFragment[] = res.body.data; console.log(attestations); expect(attestations.length).to.be.equal(3); From 1b8986d591b4cc1568fcafaf6af79be9aefe833d Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Mon, 17 Jun 2024 17:06:54 +0000 Subject: [PATCH 146/278] fix last test for uuid changes --- desci-server/test/integration/Attestation.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desci-server/test/integration/Attestation.test.ts b/desci-server/test/integration/Attestation.test.ts index 05966d43..45a484d8 100644 --- a/desci-server/test/integration/Attestation.test.ts +++ b/desci-server/test/integration/Attestation.test.ts @@ -2080,7 +2080,7 @@ describe('Attestations Service', async () => { const attestations = await attestationService.getAllNodeAttestations(node.uuid); expect(attestations.length).to.equal(2); - res = await request(app).get(`/v1/attestations/${1}`).set('authorization', authHeaderVal); + res = await request(app).get(`/v1/attestations/${node.uuid}`).set('authorization', authHeaderVal); const claims = res.body.data as NodeClaim[]; const revoked = claims.find((c) => c.id === claim.id); expect(revoked?.revoked).to.be.false; From 50e7d8f67d220eb877f261285598f92a47a43cb3 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Tue, 18 Jun 2024 00:52:43 +0200 Subject: [PATCH 147/278] update crossref metadata client, env var and more --- .env.example | 1 + .env.test | 1 + desci-server/kubernetes/deployment_dev.yaml | 1 + desci-server/kubernetes/deployment_prod.yaml | 1 + .../kubernetes/deployment_staging.yaml | 1 + desci-server/src/services/Doi.ts | 19 +++- desci-server/src/services/crossRef/client.ts | 103 ++++++++++++------ desci-server/src/services/orcid.ts | 4 +- desci-server/src/utils/manifest.ts | 2 + 9 files changed, 91 insertions(+), 42 deletions(-) diff --git a/.env.example b/.env.example index 7b0d9920..990377c3 100755 --- a/.env.example +++ b/.env.example @@ -130,6 +130,7 @@ CROSSREF_DOI_URL=https://doi.org # Cross ref api CROSSREF_API=https://api.crossref.org CROSSREF_METADATA_API=https://test.crossref.org/servlet/deposit +CROSSREF_ADMIN_API=https://test.crossref.org CROSSREF_API_KEY= CROSSREF_EMAIL= CROSSREF_LOGIN= diff --git a/.env.test b/.env.test index bf9f406f..a20b6959 100644 --- a/.env.test +++ b/.env.test @@ -80,6 +80,7 @@ CROSSREF_DOI_URL=https://doi.org # Cross ref api CROSSREF_API=https://api.crossref.org CROSSREF_METADATA_API=https://test.crossref.org/servlet/deposit +CROSSREF_ADMIN_API=https://test.crossref.org CROSSREF_API_KEY= CROSSREF_EMAIL= CROSSREF_LOGIN= diff --git a/desci-server/kubernetes/deployment_dev.yaml b/desci-server/kubernetes/deployment_dev.yaml index bb2df633..310af9ac 100644 --- a/desci-server/kubernetes/deployment_dev.yaml +++ b/desci-server/kubernetes/deployment_dev.yaml @@ -87,6 +87,7 @@ spec: export CROSSREF_LOGIN={{ .Data.CROSSREF_LOGIN }} export CROSSREF_PASSWORD={{ .Data.CROSSREF_PASSWORD }} export CROSSREF_METADATA_API={{ .Data.CROSSREF_METADATA_API }} + export CROSSREF_ADMIN_API={{ .Data.CROSSREF_ADMIN_API }} export DEBUG_TEST=0; echo "appfinish"; {{- end -}} diff --git a/desci-server/kubernetes/deployment_prod.yaml b/desci-server/kubernetes/deployment_prod.yaml index 4c45df14..881f1ce7 100755 --- a/desci-server/kubernetes/deployment_prod.yaml +++ b/desci-server/kubernetes/deployment_prod.yaml @@ -87,6 +87,7 @@ spec: export CROSSREF_LOGIN={{ .Data.CROSSREF_LOGIN }} export CROSSREF_PASSWORD={{ .Data.CROSSREF_PASSWORD }} export CROSSREF_METADATA_API={{ .Data.CROSSREF_METADATA_API }} + export CROSSREF_ADMIN_API={{ .Data.CROSSREF_ADMIN_API }} export IGNORE_LINE=0; export DEBUG_TEST=0; echo "appfinish"; diff --git a/desci-server/kubernetes/deployment_staging.yaml b/desci-server/kubernetes/deployment_staging.yaml index cd445f19..ae799615 100644 --- a/desci-server/kubernetes/deployment_staging.yaml +++ b/desci-server/kubernetes/deployment_staging.yaml @@ -99,6 +99,7 @@ spec: export CROSSREF_LOGIN={{ .Data.CROSSREF_LOGIN }} export CROSSREF_PASSWORD={{ .Data.CROSSREF_PASSWORD }} export CROSSREF_METADATA_API={{ .Data.CROSSREF_METADATA_API }} + export CROSSREF_ADMIN_API={{ .Data.CROSSREF_ADMIN_API }} export DEBUG_TEST=0; echo "appfinish"; {{- end -}} diff --git a/desci-server/src/services/Doi.ts b/desci-server/src/services/Doi.ts index cacc1569..e5eb2970 100644 --- a/desci-server/src/services/Doi.ts +++ b/desci-server/src/services/Doi.ts @@ -118,20 +118,31 @@ export class DoiService { // validate title, abstract and contributors this.assertValidManifest(latestManifest); - return { dpid: latestManifest.dpid.id, uuid, manifest: latestManifest }; + return { dpid: latestManifest.dpid.id, uuid, manifest: latestManifest, researchObject }; } async mintDoi(nodeUuid: string) { - const { dpid, uuid, manifest } = await this.checkMintability(nodeUuid); + const { dpid, uuid, manifest, researchObject } = await this.checkMintability(nodeUuid); // mint new doi const doiSuffix = v4().substring(0, 8); const doi = `${DOI_PREFIX}/${doiSuffix}`; - // todo: handle over logic to cross-ref api service for minting DOIs - const metadataResponse = await crossRefClient.postMetadata({ manifest, doi }); + + const latestVersion = researchObject.versions[researchObject.versions.length - 1]; + const publicationDate = new Date(parseInt(latestVersion.time) * 1000).toLocaleDateString().replaceAll('/', '-'); + + const [month, day, year] = publicationDate.split('-'); + + const metadataResponse = await crossRefClient.postMetadata({ + manifest, + doi, + publicationDate: { day, month, year }, + }); + if (!metadataResponse.ok) { throw new MintError(metadataResponse.message || 'A doi could not be registered for this node'); } + // todo: add submissionId and doi to DoiSubmissionLog table to keep track of status logger.info({ doiSuffix, doi, uuid, metadataResponse }, 'MINT DOI'); return await this.dbClient.doiRecord.create({ data: { diff --git a/desci-server/src/services/crossRef/client.ts b/desci-server/src/services/crossRef/client.ts index 6f154b91..930e8dd6 100644 --- a/desci-server/src/services/crossRef/client.ts +++ b/desci-server/src/services/crossRef/client.ts @@ -2,9 +2,12 @@ import { ResearchObjectV1 } from '@desci-labs/desci-models'; import FormData from 'form-data'; import fetch from 'node-fetch'; import { default as Remixml } from 'remixml'; +import { v4 } from 'uuid'; +import { prisma } from '../../client.js'; import { logger as parentLogger } from '../../logger.js'; import { ONE_DAY_TTL, getFromCache, setToCache } from '../../redisClient.js'; +import { asyncMap } from '../../utils.js'; import { CrossRefHttpResponse, Items, QueryWorkParams, Work } from './definitions.js'; import { keysToDotsAndDashses } from './utils.js'; @@ -22,7 +25,7 @@ const metadataTemplate = ` xmlns:fr="http://www.crossref.org/fundref.xsd" xmlns:mml="http://www.w3.org/1998/Math/MathML" version="5.3.1"> - none + &_.submissionId; &_.timestamp; &depositor.name; @@ -38,7 +41,26 @@ const metadataTemplate = ` &_.name; &_.surname; - &_.orcid; + + + + + &_.id; + + + &_.name; + + + + + + + &_.orcid; + + + &_.orcid; + + @@ -55,21 +77,7 @@ const metadataTemplate = ` &publishedDate.day; &publishedDate.year; - - Crossref - https://ror.org/02twcfp32 - https://www.isni.org/0000000405062673 - https://www.wikidata.org/entity/Q5188229 - - CR - Lynnfield, MA - Feline Outreach - &_.dpid; - - - http://example.org/license_page.html - &_.doi; &_.doiResource; @@ -79,6 +87,11 @@ const metadataTemplate = ` `; +type PublicationDate = { + day: string; + month: string; + year: string; +}; /** * A wrapper http client for querying, caching and parsing requests * from the CrossRef Rest Api https://www.crossref.org/documentation/retrieve-metadata/rest-api/ @@ -167,31 +180,48 @@ class CrossRefClient { } } - async postMetadata(query: { manifest: ResearchObjectV1; doi: string }) { + async postMetadata(query: { manifest: ResearchObjectV1; doi: string; publicationDate: PublicationDate }) { + const contributors = await asyncMap(query.manifest.authors ?? [], async (author) => { + const user = author.orcid ? await prisma.user.findUnique({ where: { orcid: author.orcid } }) : null; + logger.info({ user: { orcid: user?.orcid } }); + const affiliations = user + ? ( + await prisma.userOrganizations.findMany({ where: { userId: user.id }, include: { organization: true } }) + )?.map((org) => ({ name: org.organization.name, id: org.organization.id })) + : author?.organizations?.map((org) => ({ name: org.name })); + + return { + name: author.name.split(' ')[0], + surname: author.name.split(' ').slice(1)?.join(' ') || '-', + + // don't substitute with `sandbox.orcid.org`, the submission will be rejected + // due to schema errors + orcid: `https://orcid.org/${author.orcid}`, + + isAuthenticated: !!user, + // crossref schema only allows a maximum of one affiliation per contributor + ...(affiliations?.length > 0 && { affiliations: affiliations.slice(0, 1) }), + }; + }); + + const submissionId = v4(); + const param = { _: { + submissionId, timestamp: Date.now(), dpid: query.manifest.dpid.id, doi: query.doi, - doiResource: `https://dev-beta.dpid.org/${query.manifest.dpid.id}`, + doiResource: `${process.env.DPID_URL_OVERRIDE}/${query.manifest.dpid.id}`, title: query.manifest.title, - registrant: 'Desci Labs', - contributors: query.manifest.authors.map((author) => ({ - name: author.name.split(' ')[0], - surname: author.name.split(' ').slice(1)?.join(' ') || '-', - orcid: `https://${process.env.ORCID_API_DOMAIN}/${author.orcid}`, - })), + registrant: 'DeSci Labs AG', + contributors, }, depositor: { - name: 'Desci Labs', - email: 'admin@desci.com', - }, - publishedDate: { - day: 25, - month: '06', - year: 2024, - startDate: '2024-06-05', + name: 'DeSci Labs AG', + email: process.env.CROSSREF_EMAIL, }, + publishedDate: query.publicationDate, }; const metadata = Remixml.parse2txt(metadataTemplate, param); @@ -199,7 +229,10 @@ class CrossRefClient { const url = `${process.env.CROSSREF_METADATA_API}?operation=doMDUpload&login_id=${process.env.CROSSREF_LOGIN || 'dslb'}&login_passwd=${process.env.CROSSREF_PASSWORD || 'pgz6wze1fmg-RPN_qkv'}`; logger.info({ param, metadata, url }, 'METADATA TO POST'); const buffer = Buffer.from(metadata, 'utf8'); - const filename = `dpid_${param._.dpid}_upload_xml.xml`; + + // prefix filename with `@` as seen from the crossref documentation + // https://www.crossref.org/documentation/register-maintain-records/direct-deposit-xml/https-post/#00230 + const filename = `@dpid_${param._.dpid}_upload_xml.xml`; // save file for debugging purposes // await fs.writeFile(path.join(process.cwd(), filename), buffer); const form = new FormData(); @@ -221,10 +254,10 @@ class CrossRefClient { if (!response.ok || response.status !== 200) { return { ok: false, message: body }; } - return { ok: true }; + return { ok: true, submissionId }; } catch (error) { logger.error(error, 'Post metadata Api Error'); - return { ok: false }; + return { ok: false, submissionId }; } } diff --git a/desci-server/src/services/orcid.ts b/desci-server/src/services/orcid.ts index 55f8acec..8b037722 100644 --- a/desci-server/src/services/orcid.ts +++ b/desci-server/src/services/orcid.ts @@ -1,7 +1,7 @@ import { ResearchObjectV1, ResearchObjectV1Author } from '@desci-labs/desci-models'; import { ActionType, AuthTokenSource, ORCIDRecord, OrcidPutCodes, PutcodeReference } from '@prisma/client'; -import { logger as parentLogger, prisma } from '../internal.js'; +import { logger as parentLogger, prisma, zeropad } from '../internal.js'; import { IndexedResearchObject, getIndexedResearchObjects } from '../theGraph.js'; import { hexToCid } from '../utils.js'; @@ -636,8 +636,6 @@ const generateClaimWorkRecord = ({ ); }; -const zeropad = (data: string) => (data.length < 2 ? `0${data}` : data); - /** * Generate an ORCID work summary xml string based for a research Node * Model Reference https://github.com/ORCID/orcid-model/blob/master/src/main/resources/record_3.0/work-3.0.xsd diff --git a/desci-server/src/utils/manifest.ts b/desci-server/src/utils/manifest.ts index 1b191670..1c359e98 100644 --- a/desci-server/src/utils/manifest.ts +++ b/desci-server/src/utils/manifest.ts @@ -45,3 +45,5 @@ export const resolveNodeManifest = async (targetCid: string, query?: string) => return null; } }; + +export const zeropad = (data: string) => (data.length < 2 ? `0${data}` : data); From 2654a8456dc1db6c71265e9b0f8bc7f33d5b50ce Mon Sep 17 00:00:00 2001 From: m0ar Date: Mon, 17 Jun 2024 12:15:15 +0200 Subject: [PATCH 148/278] server: enforce history validation before upgrading dpid --- Dockerfile | 3 +- desci-server/package.json | 1 + .../src/controllers/nodes/createDpid.ts | 78 +- desci-server/src/controllers/nodes/publish.ts | 4 + desci-server/yarn.lock | 3087 ++++++++++++++++- 5 files changed, 3124 insertions(+), 49 deletions(-) diff --git a/Dockerfile b/Dockerfile index 147c5a5d..4ae02c58 100755 --- a/Dockerfile +++ b/Dockerfile @@ -46,7 +46,8 @@ COPY --chown=node:node ./desci-contracts/artifacts ./src/desci-contracts-artifac RUN mv package.json package.json.old RUN sed 's/link:/file:/' package.json.old > package.json -RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn yarn install +# Remove ignore-engines flag after bump to node 20, composedb CLI blocks installing meanwhile +RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn yarn install --ignore-engines RUN chown -R node /app/node_modules/.prisma RUN chown -R node /root/.cache/prisma/master diff --git a/desci-server/package.json b/desci-server/package.json index 11d8d5fb..d30ffece 100755 --- a/desci-server/package.json +++ b/desci-server/package.json @@ -55,6 +55,7 @@ "@automerge/automerge-repo": "^1.0.19", "@automerge/automerge-repo-network-websocket": "^1.0.19", "@aws-sdk/client-s3": "^3.537.0", + "@desci-labs/desci-codex-lib": "^1.1.7", "@desci-labs/desci-contracts": "0.2.5-rc7", "@desci-labs/desci-models": "0.2.7-rc5", "@honeycombio/opentelemetry-node": "^0.3.2", diff --git a/desci-server/src/controllers/nodes/createDpid.ts b/desci-server/src/controllers/nodes/createDpid.ts index fbc6daea..8dd498d7 100644 --- a/desci-server/src/controllers/nodes/createDpid.ts +++ b/desci-server/src/controllers/nodes/createDpid.ts @@ -3,8 +3,10 @@ import { ethers } from "ethers"; import { logger as parentLogger } from '../../logger.js'; import { RequestWithNode } from "../../middleware/authorisation.js"; import { contracts, typechain as tc } from "@desci-labs/desci-contracts"; -import { DpidMintedEvent, UpgradedDpidEvent } from "@desci-labs/desci-contracts/dist/typechain-types/DpidAliasRegistry.js"; +import { DpidAliasRegistry, type DpidMintedEvent } from "@desci-labs/desci-contracts/dist/typechain-types/DpidAliasRegistry.js"; import { setDpidAlias } from "../../services/nodeManager.js"; +import { newCeramicClient, resolveHistory } from "@desci-labs/desci-codex-lib"; +import { Logger } from "pino"; type DpidResponse = DpidSuccessResponse | DpidErrorResponse; export type DpidSuccessResponse = { @@ -15,15 +17,17 @@ export type DpidErrorResponse = { error: string; }; +const CERAMIC_API = process.env.CERAMIC_API; + /** Not secret: pre-seeded ganache account for local dev */ const GANACHE_PKEY = "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; let aliasRegistryAddress: string; -const url = process.env.SERVER_URL; +const apiServerUrl = process.env.SERVER_URL; -if (url.includes("localhost")) { +if (apiServerUrl.includes("localhost")) { aliasRegistryAddress = contracts.localDpidAliasInfo.proxies.at(0).address; -} else if (url.includes("dev") || url.includes("staging")) { +} else if (apiServerUrl.includes("dev") || apiServerUrl.includes("staging")) { aliasRegistryAddress = contracts.devDpidAliasInfo.proxies.at(0).address; } else if (process.env.NODE_ENV === "production") { aliasRegistryAddress = contracts.prodDpidAliasInfo.proxies.at(0).address; @@ -48,12 +52,12 @@ export const createDpid = async (req: RequestWithNode, res: Response { + if (!CERAMIC_API) { + throw new Error("CERAMIC_API not configured"); + }; + + const client = newCeramicClient(CERAMIC_API); + const [_owner, legacyVersions] = await registry.legacyLookup(dpid); + + const streamEvents = await resolveHistory(client, ceramicStream) + const streamStates = await Promise.all(streamEvents + .map(s => s.commit) + .map(c => client.loadStream(c)) + ); + + // Stream could have one or more additional entries + if (legacyVersions.length < streamStates.length) { + logger.error( + "Stream history shorter than legacy history", + { legacyVersions, streamStates} + ); + return false; + }; + + for (const [i, streamState] of streamStates.entries()) { + // Cant compare timestamp because anchor time WILL differ + const expectedCid = legacyVersions[i][0]; + if (expectedCid !== streamState.content.manifest) { + logger.error( + "Manifest CID mismatch between legacy and stream history", + { legacyVersions, streamStates} + ); + return false; + }; + }; + + return true; +} diff --git a/desci-server/src/controllers/nodes/publish.ts b/desci-server/src/controllers/nodes/publish.ts index 51743c33..f6d61796 100644 --- a/desci-server/src/controllers/nodes/publish.ts +++ b/desci-server/src/controllers/nodes/publish.ts @@ -112,6 +112,10 @@ export const publish = async ( let publishTask: PublishTaskQueue | undefined; if (useNewPublish) { + logger.info( + {ceramicStream, commitId, uuid, owner: owner.id}, + "Triggering new publish flow" + ); await syncPublish( ceramicStream, commitId, diff --git a/desci-server/yarn.lock b/desci-server/yarn.lock index c13101e3..f0a507ed 100644 --- a/desci-server/yarn.lock +++ b/desci-server/yarn.lock @@ -7,6 +7,11 @@ resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== +"@adraffy/ens-normalize@1.10.0": + version "1.10.0" + resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz#d2a39395c587e092d77cbbc80acf956a54f38bf7" + integrity sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q== + "@alloc/quick-lru@^5.2.0": version "5.2.0" resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30" @@ -1349,6 +1354,13 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.0.tgz#26a3d1ff49031c53a97d03b604375f028746a9ac" integrity sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg== +"@babel/runtime@7.6.0": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.0.tgz#4fc1d642a9fd0299754e8b5de62c631cf5568205" + integrity sha512-89eSBLJsxNxOERC0Op4vd+0Bqm6wRMqMbFtV3i0/fbaWw/mJ8Q3eBvgX0G4SyrOOLCtbu98HspF8o09MRT+KzQ== + dependencies: + regenerator-runtime "^0.13.2" + "@babel/runtime@^7.13.10", "@babel/runtime@^7.23.5": version "7.24.1" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.1.tgz#431f9a794d173b53720e69a6464abc6f0e2a5c57" @@ -1356,6 +1368,13 @@ dependencies: regenerator-runtime "^0.14.0" +"@babel/runtime@^7.16.3", "@babel/runtime@^7.17.2": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.7.tgz#f4f0d5530e8dbdf59b3451b9b3e594b6ba082e12" + integrity sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/runtime@^7.21.0": version "7.24.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.0.tgz#584c450063ffda59697021430cb47101b085951e" @@ -1427,6 +1446,453 @@ resolved "https://registry.yarnpkg.com/@cbor-extract/cbor-extract-win32-x64/-/cbor-extract-win32-x64-2.2.0.tgz#4b3f07af047f984c082de34b116e765cb9af975f" integrity sha512-l2M+Z8DO2vbvADOBNLbbh9y5ST1RY5sqkWOg/58GkUPBYou/cuNZ68SGQ644f1CvZ8kcOxyZtw06+dxWHIoN/w== +"@ceramicnetwork/anchor-listener@^4.13.0": + version "4.13.0" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/anchor-listener/-/anchor-listener-4.13.0.tgz#241d9b6898d7e83901e97a4418015bc0cf4d3d32" + integrity sha512-HGqnMlHIy4F0HheEGoajUmVAkEmLmadFq60QtegYlul03b12X2F56QPolmdnkfvilZDIgXR5z/OGloZKKso9UA== + dependencies: + "@ceramicnetwork/anchor-utils" "^4.13.0" + "@ethersproject/providers" "^5.5.1" + rxjs "^7.8.1" + +"@ceramicnetwork/anchor-utils@^4.13.0": + version "4.13.0" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/anchor-utils/-/anchor-utils-4.13.0.tgz#8b25cd6b89c32777dedb614479253a07ac397f45" + integrity sha512-qkmh+hk9uuNUO2TtRPbXZjBsD+Jsazl1olQGP/yAsBmjriE6szzJhf5hnBclRcJ78ssOFcn8k3NPuzBycJFFGg== + dependencies: + "@ceramicnetwork/common" "^5.13.0" + "@ethersproject/abi" "^5.7.0" + multiformats "^13.0.0" + uint8arrays "^5.0.1" + +"@ceramicnetwork/blockchain-utils-linking@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/blockchain-utils-linking/-/blockchain-utils-linking-5.3.0.tgz#fdab99a1aa70235e946bdebbc7b05b69041f896d" + integrity sha512-UDxnnlmWHobCRR3ni7SBf9HdNojDxExOPenLx0tjXBcYeJk5LN/APU1OkVOCd0YePRhr1v9b7kxCF0NwtEIUAA== + dependencies: + "@ceramicnetwork/streamid" "^5.3.0" + "@didtools/cacao" "^3.0.0" + "@stablelib/random" "^1.0.1" + "@stablelib/sha256" "^1.0.1" + caip "~1.1.0" + near-api-js "^0.44.2" + uint8arrays "^5.0.1" + +"@ceramicnetwork/blockchain-utils-validation@^5.13.0": + version "5.13.0" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/blockchain-utils-validation/-/blockchain-utils-validation-5.13.0.tgz#cb27609503d63f4e684b44434eea5ae56131cffd" + integrity sha512-g96+mR7s+rZ1lFSLHsdYx3cAXybBqExG7e7K7kKYQ/EJkKFNDAb0ABGCA1+3VdYvRwJJHq5XYyPiR1e1f6gPfA== + dependencies: + "@ceramicnetwork/blockchain-utils-linking" "^5.3.0" + "@ceramicnetwork/common" "^5.13.0" + "@ethersproject/contracts" "^5.5.0" + "@ethersproject/providers" "^5.5.1" + "@ethersproject/wallet" "^5.5.0" + "@noble/curves" "^1.1.0" + "@polkadot/util-crypto" "^7.0.2" + "@smontero/eosio-signing-tools" "^0.0.6" + "@taquito/utils" "^11.2.0" + "@tendermint/sig" "^0.6.0" + "@zondax/filecoin-signing-tools" "^0.18.2" + caip "~1.1.0" + tweetnacl "^1.0.3" + uint8arrays "^5.0.1" + +"@ceramicnetwork/codecs@^2.4.1": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/codecs/-/codecs-2.4.1.tgz#345ea2857915191d563abe7b9b165075b289f644" + integrity sha512-QhdUHp7PJm+qL05f6ovlUe7K85urBt3V7JKQrmq33jCYt4YlVT2bTyUdsrgcyA+IJZnXP1KEWuSdcpE1V3Qe/A== + dependencies: + "@ceramicnetwork/streamid" "^3.4.1" + cartonne "^3.0.1" + codeco "^1.1.0" + dag-jose "^4.0.0" + multiformats "^13.0.0" + uint8arrays "^5.0.1" + +"@ceramicnetwork/codecs@^4.13.0": + version "4.13.0" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/codecs/-/codecs-4.13.0.tgz#206597f42a5700f694a6eb6437c37acea28f3c5f" + integrity sha512-/p7+PdP4c+qBZXuHy1nd7cPNvlx/WHaCZgCdsLoB/ff+jbt0z0wIf34snEXvJddTAxfi5fAYYoMaqr7IhG0l7A== + dependencies: + "@ceramicnetwork/common" "^5.13.0" + "@ceramicnetwork/streamid" "^5.3.0" + cartonne "^3.0.1" + codeco "^1.1.0" + dag-jose "^4.0.0" + multiformats "^13.0.0" + uint8arrays "^5.0.1" + +"@ceramicnetwork/common@^3.4.1": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/common/-/common-3.4.1.tgz#47f24157742fbfb9a9137a585818fa5dc29e74ca" + integrity sha512-SVtPG6tkaDF77iM2mweXV+JSgZa3tKvuku0TIrA+pZswa1EHtnRHssSilaj4q91JNaTy2Gsk86oK6MuQp9+LKg== + dependencies: + "@ceramicnetwork/codecs" "^2.4.1" + "@ceramicnetwork/streamid" "^3.4.1" + "@didtools/cacao" "^3.0.0" + "@didtools/pkh-ethereum" "^0.2.0" + "@didtools/pkh-solana" "^0.2.0" + "@didtools/pkh-stacks" "^0.2.0" + "@didtools/pkh-tezos" "^0.3.0" + "@stablelib/random" "^1.0.1" + caip "~1.1.0" + flat "^5.0.2" + it-first "^3.0.4" + jet-logger "1.2.2" + lodash.clonedeep "^4.5.0" + logfmt "^1.3.2" + multiformats "^13.0.0" + rxjs "^7.8.1" + uint8arrays "^5.0.1" + +"@ceramicnetwork/common@^5.1.0", "@ceramicnetwork/common@^5.13.0": + version "5.13.0" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/common/-/common-5.13.0.tgz#0157449b8e8cf96148f81389bd79f1a78977b362" + integrity sha512-gYLXoABZqdhkci8JgeASkmWuGJSSGrLrscqa1RADb2VM1uq6Mv08oojCEgHN5MpxB8Hyb3/zbf1JHIttY4mpwQ== + dependencies: + "@ceramicnetwork/model-metrics" "^1.2.5" + "@ceramicnetwork/streamid" "^5.3.0" + "@didtools/cacao" "^3.0.0" + "@didtools/key-webauthn" "^2.0.2" + "@didtools/pkh-ethereum" "^0.2.0" + "@didtools/pkh-solana" "^0.2.0" + "@didtools/pkh-stacks" "^0.2.0" + "@didtools/pkh-tezos" "^0.3.0" + "@ipld/dag-cbor" "^9.1.0" + "@stablelib/random" "^1.0.1" + caip "~1.1.0" + flat "^5.0.2" + it-first "^3.0.4" + jet-logger "1.2.2" + lodash.clonedeep "^4.5.0" + logfmt "^1.3.2" + multiformats "^13.0.0" + rxjs "^7.8.1" + uint8arrays "^5.0.1" + +"@ceramicnetwork/core@^5.2.0": + version "5.14.0" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/core/-/core-5.14.0.tgz#6ff0ac6daa7a08ba3b80074683488894c39ae34d" + integrity sha512-ybKYgfMRhDkoraiskDee8Gp5holzdg9dy06cvczSAhEkTQFUZqrrO/hozaSyumoHO5SP7Xzyx2svYVGvOxyCXg== + dependencies: + "@ceramicnetwork/anchor-listener" "^4.13.0" + "@ceramicnetwork/anchor-utils" "^4.13.0" + "@ceramicnetwork/codecs" "^4.13.0" + "@ceramicnetwork/common" "^5.13.0" + "@ceramicnetwork/indexing" "^4.14.0" + "@ceramicnetwork/ipfs-topology" "^5.13.0" + "@ceramicnetwork/job-queue" "^4.14.0" + "@ceramicnetwork/model-metrics" "^1.2.5" + "@ceramicnetwork/observability" "^1.4.4" + "@ceramicnetwork/pinning-aggregation" "^5.13.0" + "@ceramicnetwork/pinning-ipfs-backend" "^5.13.0" + "@ceramicnetwork/stream-caip10-link" "^5.13.0" + "@ceramicnetwork/stream-caip10-link-handler" "^5.14.0" + "@ceramicnetwork/stream-handler-common" "^4.13.0" + "@ceramicnetwork/stream-model" "^4.13.0" + "@ceramicnetwork/stream-model-handler" "^4.14.0" + "@ceramicnetwork/stream-model-instance" "^4.14.0" + "@ceramicnetwork/stream-model-instance-handler" "^4.14.0" + "@ceramicnetwork/stream-tile" "^5.13.0" + "@ceramicnetwork/stream-tile-handler" "^5.14.0" + "@ceramicnetwork/streamid" "^5.3.0" + "@ceramicnetwork/wasm-bloom-filter" "^0.1.0" + "@datastructures-js/priority-queue" "^6.1.0" + "@ethersproject/providers" "^5.5.1" + "@ipld/dag-cbor" "^7.0.0" + "@scarf/scarf" "^1.1.1" + "@stablelib/random" "^1.0.1" + "@stablelib/sha256" "^1.0.1" + "@stablelib/uuid" "^1.0.1" + ajv "^8.8.2" + ajv-formats "^2.1.1" + await-semaphore "^0.1.3" + cartonne "^3.0.1" + codeco "^1.1.0" + dag-jose "^4.0.0" + dids "^5.0.0" + it-all "^3.0.1" + it-batch "^3.0.1" + it-first "^3.0.4" + knex "^2.5.1" + least-recent "^1.0.3" + level "^8.0.1" + lodash.clonedeep "^4.5.0" + mapmoize "^1.2.1" + multiformats "^13.0.0" + p-queue "^8.0.1" + pg "^8.11.3" + rxjs "^7.8.1" + sqlite3 "^5.0.8" + uint8arrays "^5.0.1" + +"@ceramicnetwork/http-client@^5.2.0": + version "5.14.0" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/http-client/-/http-client-5.14.0.tgz#2515b74909f79b80a78b4d646c279bf2de0c675a" + integrity sha512-/wcqy7ikaxaeXDRxx+CSgIJZtTisp0WD0lRxIIDrmqblmwsmame1sK0EFQ1Ha6YzxAQ13ZMgUfWbzv8lbFG7jw== + dependencies: + "@ceramicnetwork/common" "^5.13.0" + "@ceramicnetwork/stream-caip10-link" "^5.13.0" + "@ceramicnetwork/stream-model" "^4.13.0" + "@ceramicnetwork/stream-model-instance" "^4.14.0" + "@ceramicnetwork/stream-tile" "^5.13.0" + "@ceramicnetwork/streamid" "^5.3.0" + "@scarf/scarf" "^1.1.1" + query-string "^7.1.0" + rxjs "^7.8.1" + +"@ceramicnetwork/indexing@^4.14.0": + version "4.14.0" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/indexing/-/indexing-4.14.0.tgz#2bffc342106c9fe9d4e97b4b3ad354140a86a386" + integrity sha512-9J9WKcJdGDmvWdeniZhRcoVpZoGwVmYxOKNuHEQTySnDbiJp0mHZHY8BVNbasf4Ih/PrcJ6/O0cz2tBzKKGeVg== + dependencies: + "@ceramicnetwork/anchor-listener" "^4.13.0" + "@ceramicnetwork/anchor-utils" "^4.13.0" + "@ceramicnetwork/common" "^5.13.0" + "@ceramicnetwork/job-queue" "^4.14.0" + "@ceramicnetwork/stream-model" "^4.13.0" + "@ceramicnetwork/streamid" "^5.3.0" + "@ethersproject/providers" "^5.5.1" + knex "^2.5.1" + lodash.clonedeep "^4.5.0" + multiformats "^13.0.0" + p-queue "^8.0.1" + pg-boss "^8.2.0" + rxjs "^7.8.1" + uint8arrays "^5.0.1" + +"@ceramicnetwork/ipfs-topology@^5.13.0": + version "5.13.0" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/ipfs-topology/-/ipfs-topology-5.13.0.tgz#c1c958e0074cd5b1a6829787e78c3b6f9383a8ef" + integrity sha512-uG3wMoo1PssGw7+++NDjfU9+cCb7MZpyPZHanMMTBgXzae1fasRHBOq7FSlBfo8d2pbjlzrshfpqxsP4G2YtUQ== + dependencies: + "@ceramicnetwork/common" "^5.13.0" + +"@ceramicnetwork/job-queue@^4.14.0": + version "4.14.0" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/job-queue/-/job-queue-4.14.0.tgz#b88131cb41a40ab713147812f390e9662ce98f1e" + integrity sha512-yxZbs11npPOIlwomO7W6bOByT3LWktUpHkhMxnEcrPt4ITmN59D+Lptq1xXffwog0ciTHEUhZiePQmbgxubKvA== + dependencies: + "@ceramicnetwork/common" "^5.13.0" + pg "^8.11.3" + pg-boss "^8.2.0" + rxjs "^7.8.1" + +"@ceramicnetwork/model-metrics@^1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/model-metrics/-/model-metrics-1.2.5.tgz#5a8b4f12918671d7d532bf768f06ef1d8ed3cf67" + integrity sha512-L2T0K57CWCyHzTkGmBdM3BNX35YRPX9KqRVkPSjBv2q3Cwwm9KkrBRYHLN6W+37eWVBmKOq57lSTiQsnuSskAw== + dependencies: + "@ceramicnetwork/stream-model-instance" "^2.3.0" + "@ceramicnetwork/streamid" "^3.3.0" + dids "^5.0.2" + fs "0.0.1-security" + key-did-provider-ed25519 "^3.0.2" + key-did-resolver "^4.0.0" + uint8arrays "^5.0.1" + +"@ceramicnetwork/observability@^1.4.4": + version "1.5.6" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/observability/-/observability-1.5.6.tgz#b47cdb493090ff399e446224f99f9d548ba49ffd" + integrity sha512-cminxgAru5VvoBPEMURTaWzdEQqVMiV1e89iaAqPyjr+hAjALWStm90btNPt/PlHlpdkr/jmi4AFi1mFtdT9mQ== + dependencies: + "@opentelemetry/api" "^1.8.0" + "@opentelemetry/exporter-metrics-otlp-http" "^0.50.0" + "@opentelemetry/exporter-prometheus" "^0.50.0" + "@opentelemetry/exporter-trace-otlp-http" "^0.50.0" + "@opentelemetry/resources" "^1.23.0" + "@opentelemetry/sdk-metrics" "^1.23.0" + "@opentelemetry/sdk-trace-base" "^1.23.0" + "@opentelemetry/semantic-conventions" "^1.23.0" + "@types/node" "^20.11.16" + +"@ceramicnetwork/pinning-aggregation@^5.13.0": + version "5.13.0" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/pinning-aggregation/-/pinning-aggregation-5.13.0.tgz#167b9b5af6361aad81e28b1278580b92b593ece8" + integrity sha512-vbFgtH2K8l5PhGO0FVNDK3vFmtwk8KB/TaPkPPAfIiB/huBncx0x5yVv65zRNlhNpLVIBQDGpdN4ICjHokcjsg== + dependencies: + "@stablelib/sha256" "^1.0.1" + uint8arrays "^5.0.1" + +"@ceramicnetwork/pinning-ipfs-backend@^5.13.0": + version "5.13.0" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/pinning-ipfs-backend/-/pinning-ipfs-backend-5.13.0.tgz#856116f5d8c37a489cfc7d6dd018e7a2e02283c6" + integrity sha512-NReyMGFO7cJ/+J/jmJZS7QJ9RG0TShbp7vroJvQpHtY0ggWdfhOIrmzgLgbq63ZFF+vbg6SGgTvWKAAWdgsAMw== + dependencies: + "@stablelib/sha256" "^1.0.1" + ipfs-http-client "^60.0.0" + uint8arrays "^5.0.1" + +"@ceramicnetwork/stream-caip10-link-handler@^5.14.0": + version "5.14.0" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/stream-caip10-link-handler/-/stream-caip10-link-handler-5.14.0.tgz#935128872b52109aea39bba4e70c80e8adaebf36" + integrity sha512-NQHfM65FyJeAL5UBcwJ3EIOy/RFNZPdwLAhfKmZlQGwWmCXBRyJc6vGxxbs/fIEoKRw8AbjwLhCHt6cNSn1qgQ== + dependencies: + "@ceramicnetwork/blockchain-utils-validation" "^5.13.0" + "@ceramicnetwork/common" "^5.13.0" + "@ceramicnetwork/stream-caip10-link" "^5.13.0" + "@ceramicnetwork/stream-handler-common" "^4.13.0" + +"@ceramicnetwork/stream-caip10-link@^5.13.0": + version "5.13.0" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/stream-caip10-link/-/stream-caip10-link-5.13.0.tgz#e2f5ee8d592c6921e64b813e462155d1996c98a4" + integrity sha512-RJpsO/AERl/tAezICArYW+Wn67aqHzl4lC19D7r4lfI8Y+KOp1o4h7VkCgTFsXr5ulDQPbkE2WQqIkry8kXoUg== + dependencies: + "@ceramicnetwork/common" "^5.13.0" + "@ceramicnetwork/streamid" "^5.3.0" + caip "~1.1.0" + did-resolver "^4.0.1" + lodash.clonedeep "^4.5.0" + +"@ceramicnetwork/stream-handler-common@^4.13.0": + version "4.13.0" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/stream-handler-common/-/stream-handler-common-4.13.0.tgz#1b02d2b691bac0c38c9e5805b3becda64de2446b" + integrity sha512-YEl/TKlcNUw0ll//Ry3n7s7lbrKdVc9e1GTdxY+cPngb4vPt/pqAhlNfRR4WtQsruZ1GjRPQ239/1arTKdINrg== + dependencies: + "@ceramicnetwork/common" "^5.13.0" + "@ceramicnetwork/observability" "^1.4.4" + "@ceramicnetwork/streamid" "^5.3.0" + lodash.clonedeep "^4.5.0" + +"@ceramicnetwork/stream-model-handler@^4.14.0": + version "4.14.0" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/stream-model-handler/-/stream-model-handler-4.14.0.tgz#7408575014122de72d7576a25f04c9fec6832346" + integrity sha512-Np6y99Wtp/vXm4XdmhRQHFVDFOmgigrz2YeoqB5C8JZDIhNv+aQsbDOqEn2dxH4oTt5nhp4PmyPAjxaqxpHI0A== + dependencies: + "@ceramicnetwork/common" "^5.13.0" + "@ceramicnetwork/stream-handler-common" "^4.13.0" + "@ceramicnetwork/stream-model" "^4.13.0" + "@ceramicnetwork/streamid" "^5.3.0" + ajv "^8.8.2" + ajv-formats "^2.1.1" + fast-json-patch "^3.1.0" + json-ptr "^3.1.1" + lodash.clonedeep "^4.5.0" + lodash.ismatch "^4.4.0" + uint8arrays "^5.0.1" + +"@ceramicnetwork/stream-model-instance-handler@^4.14.0": + version "4.14.0" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/stream-model-instance-handler/-/stream-model-instance-handler-4.14.0.tgz#1e7be9aabb25cc3f9824f1d4a5144cd9f434b912" + integrity sha512-qpGkC3iTDSK4BYwcVlEyG7pRJKXwIm4zFGGBlUqcxXUE84QfkTOsHs0WdKeEKhCLs6F0Arn2REnPmk5JuQHOvg== + dependencies: + "@ceramicnetwork/common" "^5.13.0" + "@ceramicnetwork/stream-handler-common" "^4.13.0" + "@ceramicnetwork/stream-model" "^4.13.0" + "@ceramicnetwork/stream-model-instance" "^4.14.0" + "@ceramicnetwork/streamid" "^5.3.0" + ajv "^8.8.2" + ajv-formats "^2.1.1" + fast-json-patch "^3.1.0" + lodash.clonedeep "^4.5.0" + uint8arrays "^5.0.1" + +"@ceramicnetwork/stream-model-instance@^2.3.0": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/stream-model-instance/-/stream-model-instance-2.4.1.tgz#d680d926cb90719f30c0e8c2cb29c336cd77a900" + integrity sha512-vp+oY27BFM64pXN2l4riwK3/3rN1DCEZe/iBrWWJ79SC99S9jFsSnx2TB0RLkBF+n87IsWi+t1WA+FR1KNIe/Q== + dependencies: + "@ceramicnetwork/common" "^3.4.1" + "@ceramicnetwork/streamid" "^3.4.1" + "@ipld/dag-cbor" "^7.0.0" + "@stablelib/random" "^1.0.1" + fast-json-patch "^3.1.0" + object-sizeof "^2.6.1" + uint8arrays "^5.0.1" + +"@ceramicnetwork/stream-model-instance@^4.14.0", "@ceramicnetwork/stream-model-instance@^4.2.0": + version "4.14.0" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/stream-model-instance/-/stream-model-instance-4.14.0.tgz#d6bb56744a9f696b0a8eaf2b37388567b8970ba8" + integrity sha512-PxSZcyCW0IH8vqKD+eJNpQOHM+y2BzoV1qWuq3hg6ZIpQNWeM264NuVB42KxvAkzplG3se6EVu1iAEuDAVU83Q== + dependencies: + "@ceramicnetwork/common" "^5.13.0" + "@ceramicnetwork/streamid" "^5.3.0" + "@ipld/dag-cbor" "^7.0.0" + "@stablelib/random" "^1.0.1" + fast-json-patch "^3.1.0" + object-sizeof "^2.6.1" + uint8arrays "^5.0.1" + +"@ceramicnetwork/stream-model@^4.1.0", "@ceramicnetwork/stream-model@^4.13.0": + version "4.13.0" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/stream-model/-/stream-model-4.13.0.tgz#b846a17a7c5b21b40d079c32734bd76f0a30559a" + integrity sha512-fUf9YFTn5RxlWP+n80AgrLkAOmolWP5pjXxDbefg2ev8FJlANWU4J66QIdQPiWNhk8QNCMFN3O7Z/bvkWJyFgg== + dependencies: + "@ceramicnetwork/codecs" "^4.13.0" + "@ceramicnetwork/common" "^5.13.0" + "@ceramicnetwork/streamid" "^5.3.0" + "@ipld/dag-cbor" "^7.0.0" + "@stablelib/random" "^1.0.1" + ajv "^8.8.2" + ajv-formats "^2.1.1" + codeco "^1.1.0" + fast-json-patch "^3.1.0" + json-schema-typed "^8.0.1" + multiformats "^13.0.0" + uint8arrays "^5.0.1" + +"@ceramicnetwork/stream-tile-handler@^5.14.0": + version "5.14.0" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/stream-tile-handler/-/stream-tile-handler-5.14.0.tgz#9c6710a5d7332576bd00bec9307876aebe014296" + integrity sha512-DxEOggVij1qxDBdkhwoHA1ZjO7ewj31zzhXIe3sDqUhSX5L9iQotE28pyboPiHtoDyk60bapwUAgS1t4aShqlA== + dependencies: + "@ceramicnetwork/common" "^5.13.0" + "@ceramicnetwork/stream-handler-common" "^4.13.0" + "@ceramicnetwork/stream-tile" "^5.13.0" + "@ceramicnetwork/streamid" "^5.3.0" + ajv "^8.8.2" + ajv-formats "^2.1.1" + fast-json-patch "^3.1.0" + least-recent "^1.0.3" + lodash.clonedeep "^4.5.0" + uint8arrays "^5.0.1" + +"@ceramicnetwork/stream-tile@^5.13.0": + version "5.13.0" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/stream-tile/-/stream-tile-5.13.0.tgz#a06a09b2375712548fe3ae225915d7c140b3a137" + integrity sha512-9qKcZtKIKGu/8Ef1dn89xA7PIabT8hh6Ft+Fdb9k0vZckYlAnDyhzxQCfewcc+AhK4Z3m7qxfQl56dgN+ieWgQ== + dependencies: + "@ceramicnetwork/common" "^5.13.0" + "@ceramicnetwork/streamid" "^5.3.0" + "@ipld/dag-cbor" "^7.0.0" + "@stablelib/random" "^1.0.1" + dids "^5.0.0" + fast-json-patch "^3.1.0" + lodash.clonedeep "^4.5.0" + uint8arrays "^5.0.1" + +"@ceramicnetwork/streamid@^3.3.0", "@ceramicnetwork/streamid@^3.4.1": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/streamid/-/streamid-3.4.1.tgz#41e44cc9e3ac0603dfd6666f1dae07ac3cf2d837" + integrity sha512-m6uZjcdMdwzyO6TIVTJF4IJYjuceflmYDrlRxDcXrZySBNNKnL40tSHbzpcTfOy5YcIsTqJFxqUZQrFrC0mlDA== + dependencies: + "@ipld/dag-cbor" "^7.0.0" + "@stablelib/sha256" "^1.0.1" + cborg "^1.10.2" + mapmoize "^1.2.1" + multiformats "^13.0.0" + uint8arrays "^5.0.1" + varint "^6.0.0" + +"@ceramicnetwork/streamid@^5.0.0", "@ceramicnetwork/streamid@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/streamid/-/streamid-5.3.0.tgz#576c9349713004cd474ad08ff30714a3314f25b9" + integrity sha512-U/4k2iAjWIW3Ra3H8K0qJJjy9i9Zgw88gz9ecbIBDOF8Ud59ahEJpQYgdAnWc7kkSPpiZojZDTneZCgUYGQuRg== + dependencies: + "@ipld/dag-cbor" "^7.0.0" + "@stablelib/sha256" "^1.0.1" + cborg "^4.0.8" + mapmoize "^1.2.1" + multiformats "^13.0.0" + uint8arrays "^5.0.1" + varint "^6.0.0" + +"@ceramicnetwork/wasm-bloom-filter@^0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@ceramicnetwork/wasm-bloom-filter/-/wasm-bloom-filter-0.1.0.tgz#5d9705ff07a4b1a6a97115a68b1a57f117c804d0" + integrity sha512-vCKJsphSqVFpQISEBK/B59s278xmyab7BYX4yPZGI9aP92jjtGrrkQGaCQF+JOd/0ZSNRbYA3uOUH4BcKaoTCg== + "@chainsafe/is-ip@^2.0.1": version "2.0.2" resolved "https://registry.yarnpkg.com/@chainsafe/is-ip/-/is-ip-2.0.2.tgz#7311e7403f11d8c5cfa48111f56fcecaac37c9f6" @@ -1628,6 +2094,77 @@ "@types/conventional-commits-parser" "^5.0.0" chalk "^5.3.0" +"@composedb/client@^0.7.1": + version "0.7.1" + resolved "https://registry.yarnpkg.com/@composedb/client/-/client-0.7.1.tgz#382546e7a4a636debe6d3359d832724b9fe76087" + integrity sha512-LUMnaiNUbBLqqifxAybAigG+n7F+u8xhLOPsPR0F0KHPtJkJ8sXm0lpcHQPx6B4Tm5Tlb6F7Tu27WvGp+7wVCA== + dependencies: + "@ceramicnetwork/http-client" "^5.2.0" + "@ceramicnetwork/stream-model" "^4.1.0" + "@ceramicnetwork/stream-model-instance" "^4.2.0" + "@composedb/constants" "^0.7.1" + "@composedb/graphql-scalars" "^0.7.1" + "@composedb/runtime" "^0.7.1" + "@graphql-tools/batch-execute" "^9.0.4" + "@graphql-tools/stitch" "^9.0.5" + "@graphql-tools/utils" "^10.1.0" + dataloader "^2.2.2" + graphql "^16.8.1" + graphql-relay "^0.10.0" + +"@composedb/constants@^0.7.1": + version "0.7.1" + resolved "https://registry.yarnpkg.com/@composedb/constants/-/constants-0.7.1.tgz#4477f093ebb7ab3b9c17d79952416310b2a32602" + integrity sha512-fJrhOlM0kr9AVBR5iGwPXxCMbyzs06OCAcsqla1X4qWhMDHGvX/yMKV65FJIY38qwkuSdOUvhfh7vfsSmHIRnQ== + +"@composedb/graphql-scalars@^0.7.1": + version "0.7.1" + resolved "https://registry.yarnpkg.com/@composedb/graphql-scalars/-/graphql-scalars-0.7.1.tgz#01cdce359d4d5715df9d4f642f9ad19e0ddb1cbe" + integrity sha512-TX6f/1E3RZzWjDAKn3eRZ9z7zAPaE7BKWpOiomw9T3K787WPGmOIypnOOakdGE9dOf6ViYQ8eq4R6pzv0bbBpA== + dependencies: + "@ceramicnetwork/streamid" "^5.0.0" + "@composedb/types" "^0.7.1" + caip "^1.1.0" + graphql "^16.8.1" + graphql-scalars "^1.22.5" + multiformats "^13.1.0" + +"@composedb/loader@^0.7.1": + version "0.7.1" + resolved "https://registry.yarnpkg.com/@composedb/loader/-/loader-0.7.1.tgz#3e1ad9626f765683d80ed826a5d4e3ead558ce72" + integrity sha512-qmyWrNazJF/0Uc4rZqrttvbOnb0smjqTSF5i5aekThIWJtvBQ+a/GkoNjQvVQH3bWFfeRZS9TgNpD4SUpdFJpw== + dependencies: + "@ceramicnetwork/stream-model-instance" "^4.2.0" + "@ceramicnetwork/streamid" "^5.0.0" + dataloader "^2.2.2" + +"@composedb/runtime@^0.7.1": + version "0.7.1" + resolved "https://registry.yarnpkg.com/@composedb/runtime/-/runtime-0.7.1.tgz#b6f422cd1ddc81c0fe42d03195b7e970e7bfbeaa" + integrity sha512-ijv1/jNWYAwhsnJYJbyGT8MrQgZoIhDGDoD6ggF5VbcC8bYZcK88yNwASxT3s9NxQTelKznidvk9V14MxN8RUA== + dependencies: + "@ceramicnetwork/http-client" "^5.2.0" + "@ceramicnetwork/stream-model" "^4.1.0" + "@ceramicnetwork/stream-model-instance" "^4.2.0" + "@ceramicnetwork/streamid" "^5.0.0" + "@composedb/graphql-scalars" "^0.7.1" + "@composedb/loader" "^0.7.1" + graphql "^16.8.1" + graphql-relay "^0.10.0" + +"@composedb/types@^0.7.1": + version "0.7.1" + resolved "https://registry.yarnpkg.com/@composedb/types/-/types-0.7.1.tgz#4aba2a73d0a0285f3923d0f115043a78b42560b7" + integrity sha512-GtS3R06x1eU1NbBn5ZqewHk1VpvYLk9dwKV8YEzEXxnZvJa2WA8F5YD/TRItIfHgJjLNZ5O7obAK1fgDoCJxnQ== + dependencies: + "@ceramicnetwork/common" "^5.1.0" + "@ceramicnetwork/core" "^5.2.0" + "@ceramicnetwork/http-client" "^5.2.0" + "@ceramicnetwork/stream-model" "^4.1.0" + "@ceramicnetwork/stream-model-instance" "^4.2.0" + dids "^5.0.2" + json-schema-typed "^8.0.1" + "@cspotcode/source-map-support@^0.8.0": version "0.8.1" resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" @@ -1635,6 +2172,39 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" +"@datastructures-js/heap@^4.3.3": + version "4.3.3" + resolved "https://registry.yarnpkg.com/@datastructures-js/heap/-/heap-4.3.3.tgz#824c10f092ab03180702f0dea8ce96227ffe50a8" + integrity sha512-UcUu/DLh/aM4W3C8zZfwxxm6/6FIZUlm3mcAXuNOCa6Aj4iizNvNXQyb8DjZQH2jKSQbMRyNlngP6TPimuGjpQ== + +"@datastructures-js/priority-queue@^6.1.0": + version "6.3.1" + resolved "https://registry.yarnpkg.com/@datastructures-js/priority-queue/-/priority-queue-6.3.1.tgz#42971d509b457d8fbc42918f192d0ce7c6b2f5f3" + integrity sha512-eoxkWql/j0VJ0UFMFTpnyJz4KbEEVQ6aZ/JuJUgenu0Im4tYKylAycNGsYCHGXiVNEd7OKGVwfx1Ac3oYkuu7A== + dependencies: + "@datastructures-js/heap" "^4.3.3" + +"@desci-labs/desci-codex-composedb@^2.0.1": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@desci-labs/desci-codex-composedb/-/desci-codex-composedb-2.0.2.tgz#3a3724fe98d2efc58e11947de1e5571696a4d546" + integrity sha512-AEnWKXFqZFNhdCqyVTHwbdPcvb9+R3sZ6A0X6jAN7iS+J/0MHmv2muTEe1dbDcSZ6SteBTFc8p1wXqangwuegQ== + dependencies: + "@composedb/types" "^0.7.1" + +"@desci-labs/desci-codex-lib@^1.1.7": + version "1.1.7" + resolved "https://registry.yarnpkg.com/@desci-labs/desci-codex-lib/-/desci-codex-lib-1.1.7.tgz#d483d63f9a7760ab842022ce678e924c1c7fb8c3" + integrity sha512-Z06qpACxorVPn4tp35XHro2KTqvp0rVoaMkxwGssVM+4DqeuV3jEudyrSIZTc0A2BJ2SuqMYC9WtBdbq6/Py1w== + dependencies: + "@composedb/client" "^0.7.1" + "@desci-labs/desci-codex-composedb" "^2.0.1" + dids "^5.0.2" + gql-query-builder "^3.8.0" + graphql "^16.8.0" + key-did-provider-ed25519 "^4.0.2" + key-did-resolver "^4.0.0" + uint8arrays "^4.0.6" + "@desci-labs/desci-contracts@0.2.5-rc7": version "0.2.5-rc7" resolved "https://registry.yarnpkg.com/@desci-labs/desci-contracts/-/desci-contracts-0.2.5-rc7.tgz#a8a49c9518107305be712bcbdbb352faa4057a44" @@ -1648,6 +2218,145 @@ jsonld "^8.1.1" schema-dts "^1.1.2" +"@didtools/cacao@3.0.1", "@didtools/cacao@^3.0.0", "@didtools/cacao@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@didtools/cacao/-/cacao-3.0.1.tgz#4a705b583bde6d3a85bec33622d03ed1acfcb2b9" + integrity sha512-vV1JirxqVsBf2dqdvoS/msNN8fabvMfseZB0kf1FG8TbosrHd81+hgDOlQMZit7zJbTk5g3CGkZg3b7iYKkynw== + dependencies: + "@didtools/codecs" "^3.0.0" + "@didtools/siwx" "2.0.0" + "@ipld/dag-cbor" "^9.0.7" + caip "^1.1.0" + multiformats "^13.0.0" + uint8arrays "^5.0.1" + viem "^1.21.4" + +"@didtools/cacao@^2.0.0", "@didtools/cacao@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@didtools/cacao/-/cacao-2.1.0.tgz#5ce7bbae0abf6cce0631b8e5df657052065b9d40" + integrity sha512-35gopj+mOmAlA3nHoHiYMvNMXJtbJDJnVpIlCf/Wf/+/x+uG9aIQefXfF35D6JuaTCZ0apabjpT2umL5h3EXcw== + dependencies: + "@didtools/codecs" "^1.0.1" + "@didtools/siwx" "1.0.0" + "@ipld/dag-cbor" "^9.0.1" + caip "^1.1.0" + multiformats "^11.0.2" + uint8arrays "^4.0.3" + +"@didtools/codecs@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@didtools/codecs/-/codecs-1.0.1.tgz#2f0372e618ffb563c1b56279f1f5e79f59a2d48b" + integrity sha512-6PYXOCX7mwVWUcudKQ3eW5LtI8v5esozazbf2q2F01PE+LoeEvTytvgU9FEspj4pATpq3hPx1eenX2uLirDJ8w== + dependencies: + codeco "^1.1.0" + multiformats "^11.0.1" + uint8arrays "^4.0.3" + +"@didtools/codecs@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@didtools/codecs/-/codecs-3.0.0.tgz#860e74e7762f8d1cb630d3ceb87a4e728455e797" + integrity sha512-TemoVySZrs1XflMtOkwVTATtZEs42Mh2yk9SoYvBXES6Mz30PBJCm8v7U/2y1N5lrjb2cAPWs48Ryc7paetSxQ== + dependencies: + codeco "^1.2.0" + multiformats "^13.0.0" + uint8arrays "^5.0.1" + +"@didtools/key-webauthn@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@didtools/key-webauthn/-/key-webauthn-2.0.2.tgz#37d36d8a6015610a4d3ab9ccec9d86c42ea4a7c5" + integrity sha512-MkOqAiRBcRO64PMVfSFAB0SUIJMk+L8QyymE9dknjmfSKgD/ZKz7cw4pFV6IUNin75/DLrlDSfmCIIjYokivvQ== + dependencies: + "@didtools/cacao" "3.0.1" + "@ipld/dag-cbor" "^9.0.6" + "@noble/curves" "^1.2.0" + caip "^1.1.0" + cborg "^4.0.5" + multiformats "^13.0.0" + uint8arrays "^5.0.1" + varint "^6.0.0" + +"@didtools/pkh-ethereum@^0.2.0": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@didtools/pkh-ethereum/-/pkh-ethereum-0.2.1.tgz#8c03a56f34c824fa83db6161362f7fa45dd2b5e9" + integrity sha512-apQefbOqqy8HQMDNVG0ITxHLr9I5iZrjADX+mPB+ie1ue8MO8pOHMifLQ3j0R6RjS2einCd+hEZ4Ib4AKs3Xlw== + dependencies: + "@didtools/cacao" "^2.0.0" + "@ethersproject/wallet" "^5.7.0" + "@stablelib/random" "^1.0.2" + caip "^1.1.0" + +"@didtools/pkh-ethereum@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@didtools/pkh-ethereum/-/pkh-ethereum-0.4.1.tgz#b03472bf0196d2ece6a64d5f01aa96c866cdccb7" + integrity sha512-oE5bbyTauJ/WddaWnDK7bWns2E2LG4Ut33ICEcEQdlMoXM0902/vnGm8+6QE/yuLOyAllgf7DnDKvERF5IY6uQ== + dependencies: + "@didtools/cacao" "^2.1.0" + "@noble/curves" "^1.1.0" + "@noble/hashes" "^1.3.1" + "@stablelib/random" "^1.0.2" + caip "^1.1.0" + +"@didtools/pkh-ethereum@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@didtools/pkh-ethereum/-/pkh-ethereum-0.5.0.tgz#fca9008c546141f257508d4448c58609b975276b" + integrity sha512-2S+TS/I2jVTNnkgyslxQvSjCzzLsCabjXD2UWjJnVkAoxeJgPE9GvY1JhTDgvVLfxLPnYwTIP/O1WR9wJcDkFg== + dependencies: + "@didtools/cacao" "^3.0.0" + "@noble/curves" "^1.2.0" + "@noble/hashes" "^1.3.2" + "@stablelib/random" "^1.0.2" + caip "^1.1.0" + +"@didtools/pkh-solana@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@didtools/pkh-solana/-/pkh-solana-0.2.0.tgz#b66d7dd642306a9808d275871de408f2e3583e6f" + integrity sha512-wOfa+hbWo1ok8YnR8tq2mZKbcyEv9qrxtTR5jXOuhOqCkz30/qu9e2Wib/byx7Kx5/ik/2z1nd2YPL0vrA+TxQ== + dependencies: + "@didtools/cacao" "^3.0.0" + "@noble/curves" "^1.2.0" + "@stablelib/random" "^1.0.2" + caip "^1.1.0" + uint8arrays "^5.0.1" + +"@didtools/pkh-stacks@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@didtools/pkh-stacks/-/pkh-stacks-0.2.0.tgz#6dc7b546ca9ad458574a7270300c0663aac4727a" + integrity sha512-lXe8ZURCYCDQXrjaM7A4p1RCKrVsQ+NbO7bI70pRfjven82BPLDiqEJbhRGnWKbjQD1CQe9MJXLy3AuStKc7qw== + dependencies: + "@didtools/cacao" "^3.0.0" + "@stablelib/random" "^1.0.2" + "@stacks/common" "^6.10.0" + "@stacks/encryption" "^6.10.0" + "@stacks/transactions" "^6.10.0" + caip "^1.1.0" + jsontokens "^4.0.1" + +"@didtools/pkh-tezos@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@didtools/pkh-tezos/-/pkh-tezos-0.3.0.tgz#21d766f4b492c5acd30ce8710585dee479fc68ae" + integrity sha512-AB8drOnBkDSE9KolsiSShPwVOVbRXM2G5T//b+GgX9potVRTcRsD0z59x/6mU1e9g2kxpScOhjRrZsC0c+SQNw== + dependencies: + "@didtools/cacao" "^3.0.0" + "@noble/curves" "^1.2.0" + "@noble/hashes" "^1.3.2" + "@stablelib/random" "^1.0.2" + caip "^1.1.0" + uint8arrays "^5.0.1" + +"@didtools/siwx@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@didtools/siwx/-/siwx-1.0.0.tgz#18eacb098a3a1f69253a8216fa5071ad9c2c7ec1" + integrity sha512-b7sPDTNHdySoJ+Rp2p06x3rg1iTxI4yPTTA3PrPh40xcvFJ0K/YhdIb/Rzff13t92arcJ+VYGFhqtJorauV91g== + dependencies: + codeco "^1.1.0" + +"@didtools/siwx@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@didtools/siwx/-/siwx-2.0.0.tgz#95225f57888bff821baa182dee2d7860ee51940a" + integrity sha512-eqBtI5dZrptXTCyadnhvU0di/KvumoByT7F8KB/8BLU7M1lltfEmvf/c5AnsyrWO9338ygCs2u5mKz1p1Zdj5A== + dependencies: + codeco "^1.2.0" + "@digitalbazaar/http-client@^3.4.1": version "3.4.1" resolved "https://registry.yarnpkg.com/@digitalbazaar/http-client/-/http-client-3.4.1.tgz#5116fc44290d647cfe4b615d1f3fad9d6005e44d" @@ -1909,7 +2618,7 @@ dependencies: "@ethersproject/bignumber" "^5.7.0" -"@ethersproject/contracts@5.7.0": +"@ethersproject/contracts@5.7.0", "@ethersproject/contracts@^5.5.0": version "5.7.0" resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.7.0.tgz#c305e775abd07e48aa590e1a877ed5c316f8bd1e" integrity sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg== @@ -2012,7 +2721,7 @@ dependencies: "@ethersproject/logger" "^5.7.0" -"@ethersproject/providers@5.7.2": +"@ethersproject/providers@5.7.2", "@ethersproject/providers@^5.5.1": version "5.7.2" resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.7.2.tgz#f8b1a4f275d7ce58cf0a2eec222269a08beb18cb" integrity sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg== @@ -2120,7 +2829,7 @@ "@ethersproject/constants" "^5.7.0" "@ethersproject/logger" "^5.7.0" -"@ethersproject/wallet@5.7.0": +"@ethersproject/wallet@5.7.0", "@ethersproject/wallet@^5.5.0", "@ethersproject/wallet@^5.7.0": version "5.7.0" resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.7.0.tgz#4e5d0790d96fe21d61d38fb40324e6c7ef350b2d" integrity sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA== @@ -2195,6 +2904,114 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.1.tgz#16308cea045f0fc777b6ff20a9f25474dd8293d2" integrity sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q== +"@gar/promisify@^1.0.1": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" + integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== + +"@graphql-tools/batch-delegate@^9.0.3": + version "9.0.3" + resolved "https://registry.yarnpkg.com/@graphql-tools/batch-delegate/-/batch-delegate-9.0.3.tgz#7d496a693e7f3226dbff5fc30989bbbd7ef5fa16" + integrity sha512-wYYbDLQeXU+lEUQJDjylN/e1V3OTVkeJSZYgroDniBfg3etDuOJruAIWZ6S6skKB1PZBy1emEbs6HjrziHeX0A== + dependencies: + "@graphql-tools/delegate" "^10.0.11" + "@graphql-tools/utils" "^10.2.1" + dataloader "2.2.2" + tslib "^2.4.0" + value-or-promise "^1.0.12" + +"@graphql-tools/batch-execute@^9.0.4": + version "9.0.4" + resolved "https://registry.yarnpkg.com/@graphql-tools/batch-execute/-/batch-execute-9.0.4.tgz#11601409c0c33491971fc82592de12390ec58be2" + integrity sha512-kkebDLXgDrep5Y0gK1RN3DMUlLqNhg60OAz0lTCqrYeja6DshxLtLkj+zV4mVbBA4mQOEoBmw6g1LZs3dA84/w== + dependencies: + "@graphql-tools/utils" "^10.0.13" + dataloader "^2.2.2" + tslib "^2.4.0" + value-or-promise "^1.0.12" + +"@graphql-tools/delegate@^10.0.11", "@graphql-tools/delegate@^10.0.4": + version "10.0.11" + resolved "https://registry.yarnpkg.com/@graphql-tools/delegate/-/delegate-10.0.11.tgz#d66b46a5f90b0c323848e0b38379836842d1ce72" + integrity sha512-+sKeecdIVXhFB/66e5yjeKYZ3Lpn52yNG637ElVhciuLGgFc153rC6l6zcuNd9yx5wMrNx35U/h3HsMIEI3xNw== + dependencies: + "@graphql-tools/batch-execute" "^9.0.4" + "@graphql-tools/executor" "^1.2.1" + "@graphql-tools/schema" "^10.0.4" + "@graphql-tools/utils" "^10.2.1" + dataloader "^2.2.2" + tslib "^2.5.0" + +"@graphql-tools/executor@^1.2.1": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@graphql-tools/executor/-/executor-1.2.6.tgz#71caa7c52108e4744bfa5ffdc958126bb4b48ff2" + integrity sha512-+1kjfqzM5T2R+dCw7F4vdJ3CqG+fY/LYJyhNiWEFtq0ToLwYzR/KKyD8YuzTirEjSxWTVlcBh7endkx5n5F6ew== + dependencies: + "@graphql-tools/utils" "^10.1.1" + "@graphql-typed-document-node/core" "3.2.0" + "@repeaterjs/repeater" "^3.0.4" + tslib "^2.4.0" + value-or-promise "^1.0.12" + +"@graphql-tools/merge@^9.0.3", "@graphql-tools/merge@^9.0.4": + version "9.0.4" + resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-9.0.4.tgz#66c34cbc2b9a99801c0efca7b8134b2c9aecdb06" + integrity sha512-MivbDLUQ+4Q8G/Hp/9V72hbn810IJDEZQ57F01sHnlrrijyadibfVhaQfW/pNH+9T/l8ySZpaR/DpL5i+ruZ+g== + dependencies: + "@graphql-tools/utils" "^10.0.13" + tslib "^2.4.0" + +"@graphql-tools/schema@^10.0.3", "@graphql-tools/schema@^10.0.4": + version "10.0.4" + resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-10.0.4.tgz#d4fc739a2cc07b4fc5f31a714178a561cba210cd" + integrity sha512-HuIwqbKxPaJujox25Ra4qwz0uQzlpsaBOzO6CVfzB/MemZdd+Gib8AIvfhQArK0YIN40aDran/yi+E5Xf0mQww== + dependencies: + "@graphql-tools/merge" "^9.0.3" + "@graphql-tools/utils" "^10.2.1" + tslib "^2.4.0" + value-or-promise "^1.0.12" + +"@graphql-tools/stitch@^9.0.5": + version "9.2.9" + resolved "https://registry.yarnpkg.com/@graphql-tools/stitch/-/stitch-9.2.9.tgz#4556c586a2e5faa6b8bce6330f4dd0b2f2748eb7" + integrity sha512-+vWcsdL5nGyKMuq08sME+hf3vmp4qnkAiSj25a9HaBU118KJCvp9wTMYRB6Om5H2nlStDxP2HMS4RK3fv7vf8w== + dependencies: + "@graphql-tools/batch-delegate" "^9.0.3" + "@graphql-tools/delegate" "^10.0.11" + "@graphql-tools/executor" "^1.2.1" + "@graphql-tools/merge" "^9.0.4" + "@graphql-tools/schema" "^10.0.4" + "@graphql-tools/utils" "^10.2.1" + "@graphql-tools/wrap" "^10.0.2" + tslib "^2.4.0" + value-or-promise "^1.0.11" + +"@graphql-tools/utils@^10.0.13", "@graphql-tools/utils@^10.1.0", "@graphql-tools/utils@^10.1.1", "@graphql-tools/utils@^10.2.1": + version "10.2.2" + resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-10.2.2.tgz#6477295fae051ffb5d6c28253aa6d8a449d4a820" + integrity sha512-ueoplzHIgFfxhFrF4Mf/niU/tYHuO6Uekm2nCYU72qpI+7Hn9dA2/o5XOBvFXDk27Lp5VSvQY5WfmRbqwVxaYQ== + dependencies: + "@graphql-typed-document-node/core" "^3.1.1" + cross-inspect "1.0.0" + dset "^3.1.2" + tslib "^2.4.0" + +"@graphql-tools/wrap@^10.0.2": + version "10.0.5" + resolved "https://registry.yarnpkg.com/@graphql-tools/wrap/-/wrap-10.0.5.tgz#614b964a158887b4a644f5425b2b9a57b5751f72" + integrity sha512-Cbr5aYjr3HkwdPvetZp1cpDWTGdD1Owgsb3z/ClzhmrboiK86EnQDxDvOJiQkDCPWE9lNBwj8Y4HfxroY0D9DQ== + dependencies: + "@graphql-tools/delegate" "^10.0.4" + "@graphql-tools/schema" "^10.0.3" + "@graphql-tools/utils" "^10.1.1" + tslib "^2.4.0" + value-or-promise "^1.0.12" + +"@graphql-typed-document-node/core@3.2.0", "@graphql-typed-document-node/core@^3.1.1": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.2.0.tgz#5f3d96ec6b2354ad6d8a28bf216a1d97b5426861" + integrity sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ== + "@grpc/grpc-js@^1.7.1", "@grpc/grpc-js@^1.7.3": version "1.10.2" resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.10.2.tgz#19e6da577d88210a01ecc7987b2394b841ed34dd" @@ -2315,7 +3132,15 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== -"@ipld/dag-cbor@^9.0.0": +"@ipld/dag-cbor@^7.0.0", "@ipld/dag-cbor@^7.0.1": + version "7.0.3" + resolved "https://registry.yarnpkg.com/@ipld/dag-cbor/-/dag-cbor-7.0.3.tgz#aa31b28afb11a807c3d627828a344e5521ac4a1e" + integrity sha512-1VVh2huHsuohdXC1bGJNE8WR72slZ9XE2T3wbBBq31dm7ZBatmKLLxrB+XAqafxfRFjv08RZmj/W/ZqaM13AuA== + dependencies: + cborg "^1.6.0" + multiformats "^9.5.4" + +"@ipld/dag-cbor@^9.0.0", "@ipld/dag-cbor@^9.0.1", "@ipld/dag-cbor@^9.0.6", "@ipld/dag-cbor@^9.0.7", "@ipld/dag-cbor@^9.1.0": version "9.2.0" resolved "https://registry.yarnpkg.com/@ipld/dag-cbor/-/dag-cbor-9.2.0.tgz#3a3f0bee02d7e1c2f15582e896843d5b00fbba9f" integrity sha512-N14oMy0q4gM6OuZkIpisKe0JBSjf1Jb39VI+7jMLiWX9124u1Z3Fdj/Tag1NA0cVxxqWDh0CqsjcVfOKtelPDA== @@ -2527,6 +3352,11 @@ multiformats "^11.0.0" uint8arrays "^4.0.2" +"@multiformats/base-x@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@multiformats/base-x/-/base-x-4.0.1.tgz#95ff0fa58711789d53aefb2590a8b7a4e715d121" + integrity sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw== + "@multiformats/dns@^1.0.1": version "1.0.2" resolved "https://registry.yarnpkg.com/@multiformats/dns/-/dns-1.0.2.tgz#56a9e91572c071f3977c693f39f23636bcdb80f5" @@ -2649,17 +3479,51 @@ resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.0.tgz#e561fb330466d41807123d932b365cf3d33ceba2" integrity sha512-9WEbVRRAqJ3YFVqEZIxUqkiO8l1nool1LmNxygr5HWF8AcSYsEpneUDhmjUVJEzO2A04+oPtZdombzzPPkTtgg== +"@noble/ciphers@^0.4.0": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@noble/ciphers/-/ciphers-0.4.1.tgz#977fc35f563a4ca315ebbc4cbb1f9b670bd54456" + integrity sha512-QCOA9cgf3Rc33owG0AYBB9wszz+Ul2kramWN8tXG44Gyciud/tbkEqvxRF/IpqQaBpRBNi9f4jdNxqB2CQCIXg== + +"@noble/curves@1.2.0", "@noble/curves@~1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.2.0.tgz#92d7e12e4e49b23105a2555c6984d41733d65c35" + integrity sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw== + dependencies: + "@noble/hashes" "1.3.2" + +"@noble/curves@^1.0.0", "@noble/curves@^1.1.0", "@noble/curves@^1.2.0", "@noble/curves@^1.3.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.4.0.tgz#f05771ef64da724997f69ee1261b2417a49522d6" + integrity sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg== + dependencies: + "@noble/hashes" "1.4.0" + "@noble/ed25519@^1.6.0": version "1.7.3" resolved "https://registry.yarnpkg.com/@noble/ed25519/-/ed25519-1.7.3.tgz#57e1677bf6885354b466c38e2b620c62f45a7123" integrity sha512-iR8GBkDt0Q3GyaVcIu7mSsVIqnFbkbRzGLWlvhwunacoLwt4J3swfKhfaM6rN6WY+TBGoYT1GtT1mIh2/jGbRQ== -"@noble/hashes@^1.2.0": +"@noble/hashes@1.1.5", "@noble/hashes@~1.1.1": + version "1.1.5" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.5.tgz#1a0377f3b9020efe2fae03290bd2a12140c95c11" + integrity sha512-LTMZiiLc+V4v1Yi16TD6aX2gmtKszNye0pQgbaLqkvhIqP7nVsSaJsWloGQjJfJ8offaoP5GtX3yY5swbcJxxQ== + +"@noble/hashes@1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" + integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== + +"@noble/hashes@1.4.0", "@noble/hashes@^1.1.2", "@noble/hashes@^1.3.0", "@noble/hashes@^1.3.1", "@noble/hashes@^1.3.2", "@noble/hashes@^1.3.3": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426" + integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg== + +"@noble/hashes@^1.2.0", "@noble/hashes@~1.3.0", "@noble/hashes@~1.3.2": version "1.3.3" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.3.tgz#39908da56a4adc270147bb07968bf3b16cfe1699" integrity sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA== -"@noble/secp256k1@^1.5.4": +"@noble/secp256k1@1.7.1", "@noble/secp256k1@^1.5.4", "@noble/secp256k1@^1.6.3": version "1.7.1" resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" integrity sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw== @@ -2685,6 +3549,22 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@npmcli/fs@^1.0.0": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-1.1.1.tgz#72f719fe935e687c56a4faecf3c03d06ba593257" + integrity sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ== + dependencies: + "@gar/promisify" "^1.0.1" + semver "^7.3.5" + +"@npmcli/move-file@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674" + integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== + dependencies: + mkdirp "^1.0.4" + rimraf "^3.0.2" + "@one-ini/wasm@0.1.1": version "0.1.1" resolved "https://registry.yarnpkg.com/@one-ini/wasm/-/wasm-0.1.1.tgz#6013659736c9dbfccc96e8a9c2b3de317df39323" @@ -2697,6 +3577,13 @@ dependencies: "@opentelemetry/api" "^1.0.0" +"@opentelemetry/api-logs@0.50.0": + version "0.50.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/api-logs/-/api-logs-0.50.0.tgz#d46b76daab0bc18fa92dcdabacfc106c380d19a1" + integrity sha512-JdZuKrhOYggqOpUljAq4WWNi5nB10PmgoF0y2CvedLGXd0kSawb/UBnWT8gg1ND3bHCNHStAIVT0ELlxJJRqrA== + dependencies: + "@opentelemetry/api" "^1.0.0" + "@opentelemetry/api@^1.0.0", "@opentelemetry/api@^1.3.0", "@opentelemetry/api@^1.8.0": version "1.8.0" resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.8.0.tgz#5aa7abb48f23f693068ed2999ae627d2f7d902ec" @@ -2775,6 +3662,20 @@ dependencies: "@opentelemetry/semantic-conventions" "1.22.0" +"@opentelemetry/core@1.23.0": + version "1.23.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.23.0.tgz#f2e7ada7f35750f3c1674aef1e52c879005c0731" + integrity sha512-hdQ/a9TMzMQF/BO8Cz1juA43/L5YGtCSiKoOHmrTEf7VMDAZgy8ucpWx3eQTnQ3gBloRcWtzvcrMZABC3PTSKQ== + dependencies: + "@opentelemetry/semantic-conventions" "1.23.0" + +"@opentelemetry/core@1.25.0": + version "1.25.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.25.0.tgz#ad034f5c2669f589bd703bfbbaa38b51f8504053" + integrity sha512-n0B3s8rrqGrasTgNkXLKXzN0fXo+6IYP7M5b7AMsrZM33f/y6DS6kJ0Btd7SespASWq8bgL3taLo0oe0vB52IQ== + dependencies: + "@opentelemetry/semantic-conventions" "1.25.0" + "@opentelemetry/core@1.8.0": version "1.8.0" resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.8.0.tgz#cca18594dd48ded6dc0d08c7e789c79af0315934" @@ -2826,6 +3727,17 @@ "@opentelemetry/resources" "1.8.0" "@opentelemetry/sdk-metrics" "1.8.0" +"@opentelemetry/exporter-metrics-otlp-http@^0.50.0": + version "0.50.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-metrics-otlp-http/-/exporter-metrics-otlp-http-0.50.0.tgz#fa804b8d300f3e9c1b6047f4a17949cfaed902db" + integrity sha512-DMilj0pTOGxeaRPvVBil/KugvLMV5l+GzoXEWBKXYGEnfNlX+huPeMpYl+zJJBtI3Coht2KArnNOLhs2wqA3yA== + dependencies: + "@opentelemetry/core" "1.23.0" + "@opentelemetry/otlp-exporter-base" "0.50.0" + "@opentelemetry/otlp-transformer" "0.50.0" + "@opentelemetry/resources" "1.23.0" + "@opentelemetry/sdk-metrics" "1.23.0" + "@opentelemetry/exporter-metrics-otlp-proto@^0.34.0": version "0.34.0" resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-metrics-otlp-proto/-/exporter-metrics-otlp-proto-0.34.0.tgz#db75ed1a891358fe5a0df98df486a87ad93b5009" @@ -2839,6 +3751,15 @@ "@opentelemetry/resources" "1.8.0" "@opentelemetry/sdk-metrics" "1.8.0" +"@opentelemetry/exporter-prometheus@^0.50.0": + version "0.50.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-prometheus/-/exporter-prometheus-0.50.0.tgz#fc5dfed6246a9d796020377361601fd7c5e1a1f7" + integrity sha512-6jBrGqzpU1b2gCPUWTSSW+G3ejbZRx9SYhhFg0MO6v8R51mcln9KH6oIdTDrA+3Ie3L18bpygKrIWA9VPWEifg== + dependencies: + "@opentelemetry/core" "1.23.0" + "@opentelemetry/resources" "1.23.0" + "@opentelemetry/sdk-metrics" "1.23.0" + "@opentelemetry/exporter-trace-otlp-grpc@0.34.0", "@opentelemetry/exporter-trace-otlp-grpc@^0.34.0": version "0.34.0" resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-trace-otlp-grpc/-/exporter-trace-otlp-grpc-0.34.0.tgz#6ec4a897f263e371f4ce8e3b1aa83167fe6aedc2" @@ -2885,6 +3806,17 @@ "@opentelemetry/resources" "1.14.0" "@opentelemetry/sdk-trace-base" "1.14.0" +"@opentelemetry/exporter-trace-otlp-http@^0.50.0": + version "0.50.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.50.0.tgz#6f5961edf98ac85654c82c2f60044051cdbb1e7a" + integrity sha512-L7OtIMT7MsFqkmhbQlPBGRXt7152VN5esHpQEJYIBFedOEo3Da+yHpu5ojMZtPzpIvSpB5Xr5lnJUjJCbkttCA== + dependencies: + "@opentelemetry/core" "1.23.0" + "@opentelemetry/otlp-exporter-base" "0.50.0" + "@opentelemetry/otlp-transformer" "0.50.0" + "@opentelemetry/resources" "1.23.0" + "@opentelemetry/sdk-trace-base" "1.23.0" + "@opentelemetry/exporter-trace-otlp-proto@0.34.0", "@opentelemetry/exporter-trace-otlp-proto@^0.34.0": version "0.34.0" resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-trace-otlp-proto/-/exporter-trace-otlp-proto-0.34.0.tgz#526a2749007f35f7a70cf7d08406fcd421a03d8b" @@ -3280,6 +4212,13 @@ dependencies: "@opentelemetry/core" "1.14.0" +"@opentelemetry/otlp-exporter-base@0.50.0": + version "0.50.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.50.0.tgz#28bf0e175a22589f3a113873279bd1e7bb27a204" + integrity sha512-JUmjmrCmE1/fc4LjCQMqLfudgSl5OpUkzx7iA94b4jgeODM7zWxUoVXL7/CT7fWf47Cn+pmKjMvTCSESqZZ3mA== + dependencies: + "@opentelemetry/core" "1.23.0" + "@opentelemetry/otlp-grpc-exporter-base@0.34.0": version "0.34.0" resolved "https://registry.yarnpkg.com/@opentelemetry/otlp-grpc-exporter-base/-/otlp-grpc-exporter-base-0.34.0.tgz#edc3a9d8449f48e47c63c2f73e2c63c5a2f25102" @@ -3340,6 +4279,18 @@ "@opentelemetry/sdk-metrics" "1.14.0" "@opentelemetry/sdk-trace-base" "1.14.0" +"@opentelemetry/otlp-transformer@0.50.0": + version "0.50.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/otlp-transformer/-/otlp-transformer-0.50.0.tgz#211fe512fcce9d76042680f955336dbde3be03ef" + integrity sha512-s0sl1Yfqd5q1Kjrf6DqXPWzErL+XHhrXOfejh4Vc/SMTNqC902xDsC8JQxbjuramWt/+hibfguIvi7Ns8VLolA== + dependencies: + "@opentelemetry/api-logs" "0.50.0" + "@opentelemetry/core" "1.23.0" + "@opentelemetry/resources" "1.23.0" + "@opentelemetry/sdk-logs" "0.50.0" + "@opentelemetry/sdk-metrics" "1.23.0" + "@opentelemetry/sdk-trace-base" "1.23.0" + "@opentelemetry/propagation-utils@^0.29.5": version "0.29.5" resolved "https://registry.yarnpkg.com/@opentelemetry/propagation-utils/-/propagation-utils-0.29.5.tgz#2d3ba90a69370e7c9f2f851943cdd2e2e63a56bd" @@ -3436,6 +4387,22 @@ "@opentelemetry/core" "1.22.0" "@opentelemetry/semantic-conventions" "1.22.0" +"@opentelemetry/resources@1.23.0": + version "1.23.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.23.0.tgz#4c71430f3e20c4d88b67ef5629759fae108485e5" + integrity sha512-iPRLfVfcEQynYGo7e4Di+ti+YQTAY0h5mQEUJcHlU9JOqpb4x965O6PZ+wMcwYVY63G96KtdS86YCM1BF1vQZg== + dependencies: + "@opentelemetry/core" "1.23.0" + "@opentelemetry/semantic-conventions" "1.23.0" + +"@opentelemetry/resources@1.25.0", "@opentelemetry/resources@^1.23.0": + version "1.25.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.25.0.tgz#84a1e70097e342aa2047aac97be114ad14966793" + integrity sha512-iHjydPMYJ+Li1auveJCq2rp5U2h6Mhq8BidiyE0jfVlDTFyR1ny8AfJHfmFzJ/RAM8vT8L7T21kcmGybxZC7lQ== + dependencies: + "@opentelemetry/core" "1.25.0" + "@opentelemetry/semantic-conventions" "1.25.0" + "@opentelemetry/resources@1.8.0": version "1.8.0" resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.8.0.tgz#260be9742cf7bceccc0db928d8ca8d64391acfe3" @@ -3452,6 +4419,14 @@ "@opentelemetry/core" "1.14.0" "@opentelemetry/resources" "1.14.0" +"@opentelemetry/sdk-logs@0.50.0": + version "0.50.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-logs/-/sdk-logs-0.50.0.tgz#6636492cf626a9666f61d91025e25243d1a43bfc" + integrity sha512-PeUEupBB29p9nlPNqXoa1PUWNLsZnxG0DCDj3sHqzae+8y76B/A5hvZjg03ulWdnvBLYpnJslqzylG9E0IL87g== + dependencies: + "@opentelemetry/core" "1.23.0" + "@opentelemetry/resources" "1.23.0" + "@opentelemetry/sdk-metrics@1.14.0": version "1.14.0" resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-metrics/-/sdk-metrics-1.14.0.tgz#ee51d72eb32a74108e6632681ce2df46cddc0714" @@ -3461,6 +4436,15 @@ "@opentelemetry/resources" "1.14.0" lodash.merge "4.6.2" +"@opentelemetry/sdk-metrics@1.23.0": + version "1.23.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-metrics/-/sdk-metrics-1.23.0.tgz#b4cf3cc86b6dedf5c438c67c829df7399bf64be1" + integrity sha512-4OkvW6+wST4h6LFG23rXSTf6nmTf201h9dzq7bE0z5R9ESEVLERZz6WXwE7PSgg1gdjlaznm1jLJf8GttypFDg== + dependencies: + "@opentelemetry/core" "1.23.0" + "@opentelemetry/resources" "1.23.0" + lodash.merge "^4.6.2" + "@opentelemetry/sdk-metrics@1.8.0": version "1.8.0" resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-metrics/-/sdk-metrics-1.8.0.tgz#d061060f03861ab3f345d0f924922bc1a6396157" @@ -3470,6 +4454,15 @@ "@opentelemetry/resources" "1.8.0" lodash.merge "4.6.2" +"@opentelemetry/sdk-metrics@^1.23.0": + version "1.25.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-metrics/-/sdk-metrics-1.25.0.tgz#0c954d580c17821ae4385d29447718df09e80b79" + integrity sha512-IF+Sv4VHgBr/BPMKabl+GouJIhEqAOexCHgXVTISdz3q9P9H/uA8ScCF+22gitQ69aFtESbdYOV+Fen5+avQng== + dependencies: + "@opentelemetry/core" "1.25.0" + "@opentelemetry/resources" "1.25.0" + lodash.merge "^4.6.2" + "@opentelemetry/sdk-metrics@^1.8.0", "@opentelemetry/sdk-metrics@^1.9.1": version "1.22.0" resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-metrics/-/sdk-metrics-1.22.0.tgz#b94c62403013e4c72b96dc747d71d786073efafc" @@ -3524,6 +4517,15 @@ "@opentelemetry/resources" "1.14.0" "@opentelemetry/semantic-conventions" "1.14.0" +"@opentelemetry/sdk-trace-base@1.23.0": + version "1.23.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.23.0.tgz#ff0a0f8ec47205e0b14b3b765ea2a34de1ad01dd" + integrity sha512-PzBmZM8hBomUqvCddF/5Olyyviayka44O5nDWq673np3ctnvwMOvNrsUORZjKja1zJbwEuD9niAGbnVrz3jwRQ== + dependencies: + "@opentelemetry/core" "1.23.0" + "@opentelemetry/resources" "1.23.0" + "@opentelemetry/semantic-conventions" "1.23.0" + "@opentelemetry/sdk-trace-base@1.8.0": version "1.8.0" resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.8.0.tgz#70713aab90978a16dea188c8335209f857be7384" @@ -3533,6 +4535,15 @@ "@opentelemetry/resources" "1.8.0" "@opentelemetry/semantic-conventions" "1.8.0" +"@opentelemetry/sdk-trace-base@^1.23.0": + version "1.25.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.25.0.tgz#263f9ce19001c5cd7a814d0eb40ebc6469ae763d" + integrity sha512-6+g2fiRQUG39guCsKVeY8ToeuUf3YUnPkN6DXRA1qDmFLprlLvZm9cS6+chgbW70cZJ406FTtSCDnJwxDC5sGQ== + dependencies: + "@opentelemetry/core" "1.25.0" + "@opentelemetry/resources" "1.25.0" + "@opentelemetry/semantic-conventions" "1.25.0" + "@opentelemetry/sdk-trace-base@^1.8.0": version "1.22.0" resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.22.0.tgz#7833bf2493a7b49461915ca32aa2884c87afd78c" @@ -3576,6 +4587,16 @@ resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.22.0.tgz#d7502533a7c96e25baab86bac965468e0703a8b4" integrity sha512-CAOgFOKLybd02uj/GhCdEeeBjOS0yeoDeo/CA7ASBSmenpZHAKGB3iDm/rv3BQLcabb/OprDEsSQ1y0P8A7Siw== +"@opentelemetry/semantic-conventions@1.23.0": + version "1.23.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.23.0.tgz#627f2721b960fe586b7f72a07912cb7699f06eef" + integrity sha512-MiqFvfOzfR31t8cc74CTP1OZfz7MbqpAnLCra8NqQoaHJX6ncIRTdYOQYBDQ2uFISDq0WY8Y9dDTWvsgzzBYRg== + +"@opentelemetry/semantic-conventions@1.25.0", "@opentelemetry/semantic-conventions@^1.23.0": + version "1.25.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.0.tgz#390eb4d42a29c66bdc30066af9035645e9bb7270" + integrity sha512-M+kkXKRAIAiAP6qYyesfrC5TOmDpDVtsxuGfPcqd9B/iBrac+E14jYwrgm0yZBUIbIP2OnqC3j+UgkXLm1vxUQ== + "@opentelemetry/semantic-conventions@1.8.0": version "1.8.0" resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.8.0.tgz#fe2aa90e6df050a11cd57f5c0f47b0641fd2cad3" @@ -3598,6 +4619,102 @@ resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31" integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA== +"@polkadot/networks@7.9.2": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-7.9.2.tgz#03e3f3ac6bdea177517436537826055df60bcb9a" + integrity sha512-4obI1RdW5/7TFwbwKA9oqw8aggVZ65JAUvIFMd2YmMC2T4+NiZLnok0WhRkhZkUnqjLIHXYNwq7Ho1i39dte0g== + dependencies: + "@babel/runtime" "^7.16.3" + +"@polkadot/util-crypto@^7.0.2": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-7.9.2.tgz#cdc336f92a6bc3d40c5a23734e1974fb777817f0" + integrity sha512-nNwqUwP44eCH9jKKcPie+IHLKkg9LMe6H7hXo91hy3AtoslnNrT51tP3uAm5yllhLvswJfnAgnlHq7ybCgqeFw== + dependencies: + "@babel/runtime" "^7.16.3" + "@polkadot/networks" "7.9.2" + "@polkadot/util" "7.9.2" + "@polkadot/wasm-crypto" "^4.4.1" + "@polkadot/x-randomvalues" "7.9.2" + blakejs "^1.1.1" + bn.js "^4.12.0" + create-hash "^1.2.0" + ed2curve "^0.3.0" + elliptic "^6.5.4" + hash.js "^1.1.7" + js-sha3 "^0.8.0" + micro-base "^0.9.0" + scryptsy "^2.1.0" + tweetnacl "^1.0.3" + xxhashjs "^0.2.2" + +"@polkadot/util@7.9.2": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-7.9.2.tgz#567ac659516d6b685ed7e796919901d92e5cbe6b" + integrity sha512-6ABY6ErgkCsM4C6+X+AJSY4pBGwbKlHZmUtHftaiTvbaj4XuA4nTo3GU28jw8wY0Jh2cJZJvt6/BJ5GVkm5tBA== + dependencies: + "@babel/runtime" "^7.16.3" + "@polkadot/x-textdecoder" "7.9.2" + "@polkadot/x-textencoder" "7.9.2" + "@types/bn.js" "^4.11.6" + bn.js "^4.12.0" + camelcase "^6.2.1" + ip-regex "^4.3.0" + +"@polkadot/wasm-crypto-asmjs@^4.6.1": + version "4.6.1" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-4.6.1.tgz#4f4a5adcf8dce65666eaa0fb16b6ff7b0243aead" + integrity sha512-1oHQjz2oEO1kCIcQniOP+dZ9N2YXf2yCLHLsKaKSvfXiWaetVCaBNB8oIHIVYvuLnVc8qlMi66O6xc1UublHsw== + dependencies: + "@babel/runtime" "^7.17.2" + +"@polkadot/wasm-crypto-wasm@^4.6.1": + version "4.6.1" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-4.6.1.tgz#882d8199e216966c612f56a18e31f6aaae77e7eb" + integrity sha512-NI3JVwmLjrSYpSVuhu0yeQYSlsZrdpK41UC48sY3kyxXC71pi6OVePbtHS1K3xh3FFmDd9srSchExi3IwzKzMw== + dependencies: + "@babel/runtime" "^7.17.2" + +"@polkadot/wasm-crypto@^4.4.1": + version "4.6.1" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto/-/wasm-crypto-4.6.1.tgz#12f8481e6f9021928435168beb0697d57ff573e9" + integrity sha512-2wEftBDxDG+TN8Ah6ogtvzjdZdcF0mAjU4UNNOfpmkBCxQYZOrAHB8HXhzo3noSsKkLX7PDX57NxvJ9OhoTAjw== + dependencies: + "@babel/runtime" "^7.17.2" + "@polkadot/wasm-crypto-asmjs" "^4.6.1" + "@polkadot/wasm-crypto-wasm" "^4.6.1" + +"@polkadot/x-global@7.9.2": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@polkadot/x-global/-/x-global-7.9.2.tgz#b272b0a3bedaad3bcbf075ec4682abe68cf2a850" + integrity sha512-JX5CrGWckHf1P9xKXq4vQCAuMUbL81l2hOWX7xeP8nv4caHEpmf5T1wD1iMdQBL5PFifo6Pg0V6/oZBB+bts7A== + dependencies: + "@babel/runtime" "^7.16.3" + +"@polkadot/x-randomvalues@7.9.2": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-7.9.2.tgz#0c9bb7b48a0791c2a32e9605a31a5ce56fee621d" + integrity sha512-svQfG31yCXf6yVyIgP0NgCzEy7oc3Lw054ZspkaqjOivxYdrXaf5w3JSSUyM/MRjI2+nk+B/EyJoMYcfSwTfsQ== + dependencies: + "@babel/runtime" "^7.16.3" + "@polkadot/x-global" "7.9.2" + +"@polkadot/x-textdecoder@7.9.2": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-7.9.2.tgz#a78548e33efeb3a25f761fec9787b2bcae7f0608" + integrity sha512-wfwbSHXPhrOAl12QvlIOGNkMH/N/h8PId2ytIjvM/8zPPFB5Il6DWSFLtVapOGEpIFjEWbd5t8Td4pHBVXIEbg== + dependencies: + "@babel/runtime" "^7.16.3" + "@polkadot/x-global" "7.9.2" + +"@polkadot/x-textencoder@7.9.2": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-7.9.2.tgz#b32bfd6fbff8587c56452f58252a52d62bbcd5b9" + integrity sha512-A19wwYINuZwU2dUyQ/mMzB0ISjyfc4cISfL4zCMUAVgj7xVoXMYV2GfjNdMpA8Wsjch3su6pxLbtJ2wU03sRTQ== + dependencies: + "@babel/runtime" "^7.16.3" + "@polkadot/x-global" "7.9.2" + "@prisma/client@4.10.1": version "4.10.1" resolved "https://registry.yarnpkg.com/@prisma/client/-/client-4.10.1.tgz#c47fd54661ee74b174cee63e9dc418ecf57a6ccd" @@ -4137,6 +5254,46 @@ resolved "https://registry.yarnpkg.com/@redis/time-series/-/time-series-1.0.5.tgz#a6d70ef7a0e71e083ea09b967df0a0ed742bc6ad" integrity sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg== +"@repeaterjs/repeater@^3.0.4": + version "3.0.6" + resolved "https://registry.yarnpkg.com/@repeaterjs/repeater/-/repeater-3.0.6.tgz#be23df0143ceec3c69f8b6c2517971a5578fdaa2" + integrity sha512-Javneu5lsuhwNCryN+pXH93VPQ8g0dBX7wItHFgYiwQmzE1sVdg5tWHiOgHywzL2W21XQopa7IwIEnNbmeUJYA== + +"@scarf/scarf@^1.1.1": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@scarf/scarf/-/scarf-1.3.0.tgz#f8c75560d0dace4452dee1e31995e6396e61f3ee" + integrity sha512-lHKK8M5CTcpFj2hZDB3wIjb0KAbEOgDmiJGDv1WBRfQgRm/a8/XMEkG/N1iM01xgbUDsPQwi42D+dFo1XPAKew== + +"@scure/base@^1.1.3", "@scure/base@~1.1.0", "@scure/base@~1.1.2": + version "1.1.7" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.7.tgz#fe973311a5c6267846aa131bc72e96c5d40d2b30" + integrity sha512-PPNYBslrLNNUQ/Yad37MHYsNQtK67EhWb6WtSvNLLPo7SdVZgkUjD6Dg+5On7zNwmskf8OX7I7Nx5oN+MIWE0g== + +"@scure/bip32@1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.2.tgz#90e78c027d5e30f0b22c1f8d50ff12f3fb7559f8" + integrity sha512-N1ZhksgwD3OBlwTv3R6KFEcPojl/W4ElJOeCZdi+vuI5QmTFwLq3OFf2zd2ROpKvxFdgZ6hUpb0dx9bVNEwYCA== + dependencies: + "@noble/curves" "~1.2.0" + "@noble/hashes" "~1.3.2" + "@scure/base" "~1.1.2" + +"@scure/bip39@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.0.tgz#92f11d095bae025f166bef3defcc5bf4945d419a" + integrity sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w== + dependencies: + "@noble/hashes" "~1.1.1" + "@scure/base" "~1.1.0" + +"@scure/bip39@1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.1.tgz#5cee8978656b272a917b7871c981e0541ad6ac2a" + integrity sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg== + dependencies: + "@noble/hashes" "~1.3.0" + "@scure/base" "~1.1.0" + "@selderee/plugin-htmlparser2@^0.11.0": version "0.11.0" resolved "https://registry.yarnpkg.com/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz#d5b5e29a7ba6d3958a1972c7be16f4b2c188c517" @@ -5161,6 +6318,14 @@ "@smithy/types" "^2.12.0" tslib "^2.6.2" +"@smontero/eosio-signing-tools@^0.0.6": + version "0.0.6" + resolved "https://registry.yarnpkg.com/@smontero/eosio-signing-tools/-/eosio-signing-tools-0.0.6.tgz#b6371a63e27cd83a779d47b4911a49ca3e24d702" + integrity sha512-Uk5gnTMVnBUcUe3DUy957cfZozSni9uBzZBLLd3Wd04WWxjR6JqQw1QXGxl9GQuetwIGryX8iNj31WXPLuyA/w== + dependencies: + eosjs-ecc "^4.0.7" + node-fetch "^2.6.1" + "@socket.io/component-emitter@~3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz#96116f2a912e0c02817345b3c10751069920d553" @@ -5180,12 +6345,40 @@ dependencies: "@stablelib/int" "^1.0.1" +"@stablelib/blake2b@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/blake2b/-/blake2b-1.0.1.tgz#0045a77e182c4cf3260bc9b533fc4cd5c287f8ea" + integrity sha512-B3KyKoBAjkIFeH7romcF96i+pVFYk7K2SBQ1pZvaxV+epSBXJ+n0C66esUhyz6FF+5FbdQVm77C5fzGFcEZpKA== + dependencies: + "@stablelib/binary" "^1.0.1" + "@stablelib/hash" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + +"@stablelib/ed25519@^1.0.2": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@stablelib/ed25519/-/ed25519-1.0.3.tgz#f8fdeb6f77114897c887bb6a3138d659d3f35996" + integrity sha512-puIMWaX9QlRsbhxfDc5i+mNPMY+0TmQEskunY1rZEBPi1acBCVQAhnsk/1Hk50DGPtVsZtAWQg4NHGlVaO9Hqg== + dependencies: + "@stablelib/random" "^1.0.2" + "@stablelib/sha512" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + +"@stablelib/hash@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/hash/-/hash-1.0.1.tgz#3c944403ff2239fad8ebb9015e33e98444058bc5" + integrity sha512-eTPJc/stDkdtOcrNMZ6mcMK1e6yBbqRBaNW55XA1jU8w/7QdnCF0CmMmOD1m7VSkBR44PWrMHU2l6r8YEQHMgg== + +"@stablelib/hex@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/hex/-/hex-1.0.1.tgz#564bd46d896941c93131d1e1869eabc17cf9bab5" + integrity sha512-PQOEChVBjhYGgAD+ehO2ow1gSj1slre3jW4oMD4kV8VrhYhzmtsQDWDZej3BQO8qkVezdczDvISxVSF24PuYNA== + "@stablelib/int@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@stablelib/int/-/int-1.0.1.tgz#75928cc25d59d73d75ae361f02128588c15fd008" integrity sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w== -"@stablelib/random@^1.0.1": +"@stablelib/random@^1.0.1", "@stablelib/random@^1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@stablelib/random/-/random-1.0.2.tgz#2dece393636489bf7e19c51229dd7900eddf742c" integrity sha512-rIsE83Xpb7clHPVRlBj8qNe5L8ISQOzjghYQm/dZ7VaM2KHYwMW5adjQjrzTZCchFnNCNhkwtnOBa9HTMJCI8w== @@ -5193,11 +6386,81 @@ "@stablelib/binary" "^1.0.1" "@stablelib/wipe" "^1.0.1" +"@stablelib/sha256@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/sha256/-/sha256-1.0.1.tgz#77b6675b67f9b0ea081d2e31bda4866297a3ae4f" + integrity sha512-GIIH3e6KH+91FqGV42Kcj71Uefd/QEe7Dy42sBTeqppXV95ggCcxLTk39bEr+lZfJmp+ghsR07J++ORkRELsBQ== + dependencies: + "@stablelib/binary" "^1.0.1" + "@stablelib/hash" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + +"@stablelib/sha512@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/sha512/-/sha512-1.0.1.tgz#6da700c901c2c0ceacbd3ae122a38ac57c72145f" + integrity sha512-13gl/iawHV9zvDKciLo1fQ8Bgn2Pvf7OV6amaRVKiq3pjQ3UmEpXxWiAfV8tYjUpeZroBxtyrwtdooQT/i3hzw== + dependencies: + "@stablelib/binary" "^1.0.1" + "@stablelib/hash" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + +"@stablelib/uuid@^1.0.1": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@stablelib/uuid/-/uuid-1.0.2.tgz#0b803d954ce598067712f9170c9000b99f072d55" + integrity sha512-hduG+zCobfqjVDps3twWxBPuVYkobKQ+Dc8mQek7KfUAgbW4sJpBbr+Zd8l0KnwiFyesjAO3mZ+f3W4uLJtvNA== + dependencies: + "@stablelib/hex" "^1.0.1" + "@stablelib/random" "^1.0.2" + "@stablelib/wipe" "^1.0.1" + "@stablelib/wipe@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@stablelib/wipe/-/wipe-1.0.1.tgz#d21401f1d59ade56a62e139462a97f104ed19a36" integrity sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg== +"@stacks/common@^6.10.0", "@stacks/common@^6.13.0": + version "6.13.0" + resolved "https://registry.yarnpkg.com/@stacks/common/-/common-6.13.0.tgz#2fbfc39789cb4c64ae0089cee38b22c57e9e6c76" + integrity sha512-wwzyihjaSdmL6NxKvDeayy3dqM0L0Q2sawmdNtzJDi0FnXuJGm5PeapJj7bEfcI9XwI7Bw5jZoC6mCn9nc5YIw== + dependencies: + "@types/bn.js" "^5.1.0" + "@types/node" "^18.0.4" + +"@stacks/encryption@^6.10.0": + version "6.15.0" + resolved "https://registry.yarnpkg.com/@stacks/encryption/-/encryption-6.15.0.tgz#fc2d1a7e8a7cfe57f172af9880bad09a32461f08" + integrity sha512-506BdBvWhbXY1jxCdUcdbBzcSJctO2nzgzfenQwUuoBABSc1N/MFwQdlR9ZusY+E31zBxQPLfbr36V05/p2cfQ== + dependencies: + "@noble/hashes" "1.1.5" + "@noble/secp256k1" "1.7.1" + "@scure/bip39" "1.1.0" + "@stacks/common" "^6.13.0" + "@types/node" "^18.0.4" + base64-js "^1.5.1" + bs58 "^5.0.0" + ripemd160-min "^0.0.6" + varuint-bitcoin "^1.1.2" + +"@stacks/network@^6.13.0": + version "6.13.0" + resolved "https://registry.yarnpkg.com/@stacks/network/-/network-6.13.0.tgz#da178f8144f9c64757b7e57cf223190d12183f81" + integrity sha512-Ss/Da4BNyPBBj1OieM981fJ7SkevKqLPkzoI1+Yo7cYR2df+0FipIN++Z4RfpJpc8ne60vgcx7nJZXQsiGhKBQ== + dependencies: + "@stacks/common" "^6.13.0" + cross-fetch "^3.1.5" + +"@stacks/transactions@^6.10.0": + version "6.15.0" + resolved "https://registry.yarnpkg.com/@stacks/transactions/-/transactions-6.15.0.tgz#41d61aec7c00035112bf25d423139b9828207dc6" + integrity sha512-P6XKDcqqycPy+KBJBw8+5N+u57D8moJN7msYdde1gYXERmvOo9ht/MNREWWQ7SAM7Nlhau5mpezCdYCzXOCilQ== + dependencies: + "@noble/hashes" "1.1.5" + "@noble/secp256k1" "1.7.1" + "@stacks/common" "^6.13.0" + "@stacks/network" "^6.13.0" + c32check "^2.0.0" + lodash.clonedeep "^4.5.0" + "@swc/core-darwin-arm64@1.3.101": version "1.3.101" resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.101.tgz#9ffdc0e77c31b20877fa7405c82905e0c76738d0" @@ -5284,6 +6547,50 @@ resolved "https://registry.yarnpkg.com/@swc/types/-/types-0.1.5.tgz#043b731d4f56a79b4897a3de1af35e75d56bc63a" integrity sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw== +"@taquito/utils@^11.2.0": + version "11.2.0" + resolved "https://registry.yarnpkg.com/@taquito/utils/-/utils-11.2.0.tgz#19341a5222e078f70f3181692de75cb853ca02ee" + integrity sha512-I5LoD5fG9S2Yo4CNpW4u3vF9lUJG1PxkGLi6ntvvH49SBXwo9HJ/n/v04aoE9V7ncA0a7LUm6ucnROagIc2QQQ== + dependencies: + "@stablelib/blake2b" "^1.0.1" + "@stablelib/ed25519" "^1.0.2" + "@types/bs58check" "^2.1.0" + blakejs "^1.1.1" + bs58check "^2.1.2" + buffer "^6.0.3" + elliptic "^6.5.4" + typedarray-to-buffer "^4.0.0" + +"@tendermint/belt@0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@tendermint/belt/-/belt-0.3.0.tgz#09b50c50d7ab2967c0b6d42008c3f2ea33409994" + integrity sha512-3ZIsrbh9HLGM8cFyptK5iBeWou30srDiBjY8cVXFkz8aqPprt0OT7T9JqiqoG570x1pB0xiKwDDBxtQ120Gxug== + dependencies: + "@tendermint/types" "0.1.2" + +"@tendermint/sig@^0.6.0": + version "0.6.0" + resolved "https://registry.yarnpkg.com/@tendermint/sig/-/sig-0.6.0.tgz#c6c863bfa6047ed5ce1028cd6c3231462b8fc519" + integrity sha512-qbAETvlDMghtPA2/HXSi0NKmtm/AL2iDUpivJQ9w/7kzifKIP15mJF4jx0y3TwG9vSYjQ/+NKTgJPTT6UJ+JKg== + dependencies: + "@tendermint/belt" "0.3.0" + "@tendermint/types" "0.1.2" + bech32 "1.1.4" + bip32 "2.0.5" + bip39 "3.0.2" + create-hash "1.2.0" + secp256k1 "4.0.1" + +"@tendermint/types@0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@tendermint/types/-/types-0.1.2.tgz#e86745bf30c71690a1de2265d998951f86e051bf" + integrity sha512-VTYYB5xj6jRS0FnJWaSTuDBYOrXXxz1T23tJHuCkK2VGAqHOwaNHrtUK+fKSaYIoCDr21JM0S+uGej5Toqw1aQ== + +"@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== + "@tsconfig/node10@^1.0.7": version "1.0.9" resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" @@ -5323,6 +6630,20 @@ resolved "https://registry.yarnpkg.com/@types/aws-lambda/-/aws-lambda-8.10.81.tgz#6d405269aad82e05a348687631aa9a587cdbe158" integrity sha512-C1rFKGVZ8KwqhwBOYlpoybTSRtxu2433ea6JaO3amc6ubEe08yQoFsPa9aU9YqvX7ppeZ25CnCtC4AH9mhtxsQ== +"@types/bn.js@^4.11.6": + version "4.11.6" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" + integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== + dependencies: + "@types/node" "*" + +"@types/bn.js@^5.1.0": + version "5.1.5" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.5.tgz#2e0dacdcce2c0f16b905d20ff87aedbc6f7b4bf0" + integrity sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A== + dependencies: + "@types/node" "*" + "@types/body-parser@*", "@types/body-parser@^1.19.1": version "1.19.5" resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4" @@ -5331,6 +6652,13 @@ "@types/connect" "*" "@types/node" "*" +"@types/bs58check@^2.1.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@types/bs58check/-/bs58check-2.1.2.tgz#ca6264599cd9c0bdfeb839a0927f13a9cb77ba0f" + integrity sha512-xpXaQlOIY1KoXlA/ytHGHpEIU87PJt+g9SH7nC6HdCgaBwT2IEZIwBMHbjuX6BpnfbiUMlmwqurdLDwXpcdmSA== + dependencies: + "@types/node" "*" + "@types/bunyan@1.8.7": version "1.8.7" resolved "https://registry.yarnpkg.com/@types/bunyan/-/bunyan-1.8.7.tgz#63cc65b5ecff6217d1509409a575e7b991f80831" @@ -5687,6 +7015,16 @@ dependencies: undici-types "~5.26.4" +"@types/node@10.12.18": + version "10.12.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" + integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== + +"@types/node@11.11.6": + version "11.11.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.6.tgz#df929d1bb2eee5afdda598a41930fe50b43eaa6a" + integrity sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ== + "@types/node@^18.0.0": version "18.19.25" resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.25.tgz#bde496da9937031ef60e615418160b71f0b03776" @@ -5694,6 +7032,20 @@ dependencies: undici-types "~5.26.4" +"@types/node@^18.0.4": + version "18.19.34" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.34.tgz#c3fae2bbbdb94b4a52fe2d229d0dccce02ef3d27" + integrity sha512-eXF4pfBNV5DAMKGbI02NnDtWrQ40hAN558/2vvS4gMpMIxaf6JmD7YjnZbq0Q9TDSSkKBamime8ewRoomHdt4g== + dependencies: + undici-types "~5.26.4" + +"@types/node@^20.11.16": + version "20.14.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.2.tgz#a5f4d2bcb4b6a87bffcaa717718c5a0f208f4a18" + integrity sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q== + dependencies: + undici-types "~5.26.4" + "@types/normalize-package-data@^2.4.0": version "2.4.4" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" @@ -6073,6 +7425,22 @@ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== +"@zondax/filecoin-signing-tools@^0.18.2": + version "0.18.6" + resolved "https://registry.yarnpkg.com/@zondax/filecoin-signing-tools/-/filecoin-signing-tools-0.18.6.tgz#8436d5b2666d51f640ccdd07300da3112716f3d6" + integrity sha512-dJZ5vpvv1DQ2h/45RsjcOmLohugvanTCbmEDTTRmWradWhD09S+X6r4VTMt2KY8MN19Mz16K0OLrNIaSc2C2YA== + dependencies: + "@ipld/dag-cbor" "^7.0.0" + axios "^0.24.0" + base32-decode "^1.0.0" + base32-encode "1.2.0" + bip32 "2.0.6" + bip39 "^3.0.4" + blakejs "^1.1.1" + bn.js "^5.1.2" + leb128 "0.0.5" + secp256k1 "^4.0.3" + JSONStream@^1.0.4: version "1.3.5" resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" @@ -6091,6 +7459,11 @@ abbrev@^2.0.0: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-2.0.0.tgz#cf59829b8b4f03f89dda2771cb7f3653828c89bf" integrity sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ== +abitype@0.9.8: + version "0.9.8" + resolved "https://registry.yarnpkg.com/abitype/-/abitype-0.9.8.tgz#1f120b6b717459deafd213dfbf3a3dd1bf10ae8c" + integrity sha512-puLifILdm+8sjyss4S+fsUN09obiT1g2YW6CtcQF+QDzxR0euzgEB29MZujC6zMk2a6SVmtttq1fc6+YFA7WYQ== + abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" @@ -6098,6 +7471,19 @@ abort-controller@^3.0.0: dependencies: event-target-shim "^5.0.0" +abstract-level@^1.0.2, abstract-level@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/abstract-level/-/abstract-level-1.0.4.tgz#3ad8d684c51cc9cbc9cf9612a7100b716c414b57" + integrity sha512-eUP/6pbXBkMbXFdx4IH2fVgvB7M0JvR7/lIL33zcs0IBcwjdzSSl31TOJsaCzmKSSDF9h8QYSOJux4Nd4YJqFg== + dependencies: + buffer "^6.0.3" + catering "^2.1.0" + is-buffer "^2.0.5" + level-supports "^4.0.0" + level-transcoder "^1.0.1" + module-error "^1.0.1" + queue-microtask "^1.2.3" + accepts@~1.3.4, accepts@~1.3.8: version "1.3.8" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" @@ -6136,7 +7522,7 @@ aes-js@3.0.0: resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw== -agent-base@6: +agent-base@6, agent-base@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== @@ -6150,6 +7536,13 @@ agent-base@^7.0.2: dependencies: debug "^4.3.4" +agentkeepalive@^4.1.3: + version "4.5.0" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923" + integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew== + dependencies: + humanize-ms "^1.2.1" + aggregate-error@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" @@ -6158,6 +7551,13 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" +ajv-formats@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== + dependencies: + ajv "^8.0.0" + ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" @@ -6173,6 +7573,16 @@ ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^8.0.0, ajv@^8.8.2: + version "8.16.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.16.0.tgz#22e2a92b94f005f7e0f9c9d39652ef0b8f6f0cb4" + integrity sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw== + 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.0.1, ajv@^8.11.0: version "8.12.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" @@ -6279,6 +7689,11 @@ append-transform@^2.0.0: dependencies: default-require-extensions "^3.0.0" +"aproba@^1.0.3 || ^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" + integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== + archiver-utils@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-2.1.0.tgz#e8a460e94b693c3e3da182a098ca6285ba9249e2" @@ -6336,6 +7751,14 @@ arconnect@^0.4.2: dependencies: arweave "^1.10.13" +are-we-there-yet@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz#679df222b278c64f2cdba1175cdc00b0d96164bd" + integrity sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg== + dependencies: + delegates "^1.0.0" + readable-stream "^3.6.0" + arg@^4.1.0: version "4.1.3" resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" @@ -6546,6 +7969,11 @@ available-typed-arrays@^1.0.7: dependencies: possible-typed-array-names "^1.0.0" +await-semaphore@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/await-semaphore/-/await-semaphore-0.1.3.tgz#2b88018cc8c28e06167ae1cdff02504f1f9688d3" + integrity sha512-d1W2aNSYcz/sxYO4pMGX9vq65qOTu0P800epMud+6cYYX0QcT7zyqcxec3VWzpgvdXo57UWmVbZpLMjX2m1I7Q== + aws-sdk@^2.1186.0: version "2.1576.0" resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1576.0.tgz#f852d8c51df41b55e437610c653b31759f6a1a98" @@ -6572,6 +8000,13 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.12.0.tgz#ce1c9d143389679e253b314241ea9aa5cec980d3" integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg== +axios@^0.24.0: + version "0.24.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.24.0.tgz#804e6fa1e4b9c5288501dd9dff56a7a0940d20d6" + integrity sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA== + dependencies: + follow-redirects "^1.14.4" + axios@^0.25.0: version "0.25.0" resolved "https://registry.yarnpkg.com/axios/-/axios-0.25.0.tgz#349cfbb31331a9b4453190791760a8d35b093e0a" @@ -6600,11 +8035,30 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +base-x@^3.0.2: + version "3.0.9" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" + integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== + dependencies: + safe-buffer "^5.0.1" + base-x@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/base-x/-/base-x-4.0.0.tgz#d0e3b7753450c73f8ad2389b5c018a4af7b2224a" integrity sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw== +base32-decode@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/base32-decode/-/base32-decode-1.0.0.tgz#2a821d6a664890c872f20aa9aca95a4b4b80e2a7" + integrity sha512-KNWUX/R7wKenwE/G/qFMzGScOgVntOmbE27vvc6GrniDGYb6a5+qWcuoXl8WIOQL7q0TpK7nZDm1Y04Yi3Yn5g== + +base32-encode@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/base32-encode/-/base32-encode-1.2.0.tgz#e150573a5e431af0a998e32bdfde7045725ca453" + integrity sha512-cHFU8XeRyx0GgmoWi5qHMCVRiqU6J3MHWxVgun7jggCBUpVzm1Ir7M9dYr2whjSNc3tFeXfQ/oZjQu/4u55h9A== + dependencies: + to-data-view "^1.1.0" + base64-js@^1.0.2, base64-js@^1.3.0, base64-js@^1.3.1, base64-js@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" @@ -6627,6 +8081,11 @@ bech32@1.1.4: resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== +bigi@1.4.2, bigi@^1.1.0: + version "1.4.2" + resolved "https://registry.yarnpkg.com/bigi/-/bigi-1.4.2.tgz#9c665a95f88b8b08fc05cfd731f561859d725825" + integrity sha512-ddkU+dFIuEIW8lE7ZwdIAf2UPoM90eaprg5m3YXAVVTmKlqV/9BX4A2M8BOK2yOq6/VgZFVhK6QAxJebhlbhzw== + bignumber.js@^9.0.0, bignumber.js@^9.0.2: version "9.1.2" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" @@ -6637,6 +8096,56 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== +bindings@^1.3.0, bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +bip32@2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/bip32/-/bip32-2.0.5.tgz#e3808a9e97a880dbafd0f5f09ca4a1e14ee275d2" + integrity sha512-zVY4VvJV+b2fS0/dcap/5XLlpqtgwyN8oRkuGgAS1uLOeEp0Yo6Tw2yUTozTtlrMJO3G8n4g/KX/XGFHW6Pq3g== + dependencies: + "@types/node" "10.12.18" + bs58check "^2.1.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + tiny-secp256k1 "^1.1.3" + typeforce "^1.11.5" + wif "^2.0.6" + +bip32@2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/bip32/-/bip32-2.0.6.tgz#6a81d9f98c4cd57d05150c60d8f9e75121635134" + integrity sha512-HpV5OMLLGTjSVblmrtYRfFFKuQB+GArM0+XP8HGWfJ5vxYBqo+DesvJwOdC2WJ3bCkZShGf0QIfoIpeomVzVdA== + dependencies: + "@types/node" "10.12.18" + bs58check "^2.1.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + tiny-secp256k1 "^1.1.3" + typeforce "^1.11.5" + wif "^2.0.6" + +bip39@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/bip39/-/bip39-3.0.2.tgz#2baf42ff3071fc9ddd5103de92e8f80d9257ee32" + integrity sha512-J4E1r2N0tUylTKt07ibXvhpT2c5pyAFgvuA5q1H9uDy6dEGpjV8jmymh3MTYJDLCNbIVClSB9FbND49I6N24MQ== + dependencies: + "@types/node" "11.11.6" + create-hash "^1.1.0" + pbkdf2 "^3.0.9" + randombytes "^2.0.1" + +bip39@^3.0.4: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bip39/-/bip39-3.1.0.tgz#c55a418deaf48826a6ceb34ac55b3ee1577e18a3" + integrity sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A== + dependencies: + "@noble/hashes" "^1.2.0" + bl@^4.0.3, bl@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" @@ -6646,6 +8155,11 @@ bl@^4.0.3, bl@^4.1.0: inherits "^2.0.4" readable-stream "^3.4.0" +blakejs@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.2.1.tgz#5057e4206eadb4a97f7c0b6e197a505042fc3814" + integrity sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ== + blob-to-it@^2.0.0: version "2.0.5" resolved "https://registry.yarnpkg.com/blob-to-it/-/blob-to-it-2.0.5.tgz#5c7af31b139fde37b7f7d8e82dff8358ae38a63f" @@ -6658,12 +8172,17 @@ bluebird@^3.4.6: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== -bn.js@^4.0.0, bn.js@^4.11.9: +bn.js@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" + integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== + +bn.js@^4.0.0, bn.js@^4.11.8, bn.js@^4.11.9, bn.js@^4.12.0: version "4.12.0" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== -bn.js@^5.2.1: +bn.js@^5.0.0, bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== @@ -6686,6 +8205,15 @@ body-parser@1.20.2, body-parser@^1.20.2: type-is "~1.6.18" unpipe "1.0.0" +borsh@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/borsh/-/borsh-0.6.0.tgz#a7c9eeca6a31ca9e0607cb49f329cb659eb791e1" + integrity sha512-sl5k89ViqsThXQpYa9XDtz1sBl3l1lI313cFUY1HKr+wvMILnb+58xpkqTNrYbelh99dY7K8usxoCusQmqix9Q== + dependencies: + bn.js "^5.2.0" + bs58 "^4.0.0" + text-encoding-utf-8 "^1.0.2" + bowser@^2.11.0: version "2.11.0" resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f" @@ -6718,6 +8246,16 @@ brorand@^1.1.0: resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== +browser-level@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browser-level/-/browser-level-1.0.1.tgz#36e8c3183d0fe1c405239792faaab5f315871011" + integrity sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ== + dependencies: + abstract-level "^1.0.2" + catering "^2.1.1" + module-error "^1.0.2" + run-parallel-limit "^1.1.0" + browser-readablestream-to-it@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/browser-readablestream-to-it/-/browser-readablestream-to-it-1.0.3.tgz#ac3e406c7ee6cdf0a502dd55db33bab97f7fba76" @@ -6733,6 +8271,17 @@ browser-stdout@1.3.1: resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== +browserify-aes@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.0.6.tgz#5e7725dbdef1fd5930d4ebab48567ce451c48a0a" + integrity sha512-MMvWM6jpfsiuzY2Y+pRJvHRac3x3rHWQisWoz1dJaF9qDFsD8HdVxB7MyZKeLKeEt0fEjrXXZ0mxgTHSoJusug== + dependencies: + buffer-xor "^1.0.2" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + inherits "^2.0.1" + browserslist@^4.21.10, browserslist@^4.21.5, browserslist@^4.22.2: version "4.23.0" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.0.tgz#8f3acc2bbe73af7213399430890f86c63a5674ab" @@ -6743,6 +8292,13 @@ browserslist@^4.21.10, browserslist@^4.21.5, browserslist@^4.22.2: node-releases "^2.0.14" update-browserslist-db "^1.0.13" +bs58@4.0.1, bs58@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" + integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== + dependencies: + base-x "^3.0.2" + bs58@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/bs58/-/bs58-5.0.0.tgz#865575b4d13c09ea2a84622df6c8cbeb54ffc279" @@ -6750,6 +8306,15 @@ bs58@^5.0.0: dependencies: base-x "^4.0.0" +bs58check@<3.0.0, bs58check@^2.1.1, bs58check@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" + integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== + dependencies: + bs58 "^4.0.0" + create-hash "^1.1.0" + safe-buffer "^5.1.2" + bs58check@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-3.0.1.tgz#2094d13720a28593de1cba1d8c4e48602fdd841c" @@ -6773,6 +8338,18 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== +buffer-pipe@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/buffer-pipe/-/buffer-pipe-0.0.3.tgz#242197681d4591e7feda213336af6c07a5ce2409" + integrity sha512-GlxfuD/NrKvCNs0Ut+7b1IHjylfdegMBxQIlZHj7bObKVQBxB5S84gtm2yu1mQ8/sSggceWBDPY0cPXgvX2MuA== + dependencies: + safe-buffer "^5.1.2" + +buffer-xor@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== + buffer@4.9.2: version "4.9.2" resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" @@ -6823,11 +8400,50 @@ busboy@1.6.0, busboy@^1.0.0: dependencies: streamsearch "^1.1.0" +bytebuffer@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/bytebuffer/-/bytebuffer-5.0.1.tgz#582eea4b1a873b6d020a48d58df85f0bba6cfddd" + integrity sha512-IuzSdmADppkZ6DlpycMkm8l9zeEq16fWtLvunEwFiYciR/BHo4E8/xs5piFquG+Za8OWmMqHF8zuRviz2LHvRQ== + dependencies: + long "~3" + bytes@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== +c32check@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/c32check/-/c32check-2.0.0.tgz#b9365618b2fb135c0783d03f00605b7b0f90c659" + integrity sha512-rpwfAcS/CMqo0oCqDf3r9eeLgScRE3l/xHDCXhM3UyrfvIn7PrLq63uHh7yYbv8NzaZn5MVsVhIRpQ+5GZ5HyA== + dependencies: + "@noble/hashes" "^1.1.2" + base-x "^4.0.0" + +cacache@^15.2.0: + version "15.3.0" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.3.0.tgz#dc85380fb2f556fe3dda4c719bfa0ec875a7f1eb" + integrity sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ== + dependencies: + "@npmcli/fs" "^1.0.0" + "@npmcli/move-file" "^1.0.1" + chownr "^2.0.0" + fs-minipass "^2.0.0" + glob "^7.1.4" + infer-owner "^1.0.4" + lru-cache "^6.0.0" + minipass "^3.1.1" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.2" + mkdirp "^1.0.3" + p-map "^4.0.0" + promise-inflight "^1.0.1" + rimraf "^3.0.2" + ssri "^8.0.1" + tar "^6.0.2" + unique-filename "^1.1.1" + cachedir@2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.3.0.tgz#0c75892a052198f0b21c7c1804d8331edfcae0e8" @@ -6843,6 +8459,11 @@ caching-transform@^4.0.0: package-hash "^4.0.0" write-file-atomic "^3.0.0" +caip@^1.1.0, caip@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/caip/-/caip-1.1.1.tgz#c2c2b598b5e052d72c35c8d81b31f864e19c61e3" + integrity sha512-a3v5lteUUOoyRI0U6qe5ayCCGkF2mCmJ5zQMDnOD2vRjgRg6sm9p8TsRC2h4D4beyqRN9RYniphAPnj/+jQC6g== + call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" @@ -6878,7 +8499,7 @@ camelcase@^5.0.0, camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -camelcase@^6.0.0: +camelcase@^6.0.0, camelcase@^6.2.1: version "6.3.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== @@ -6893,11 +8514,36 @@ canonicalize@^1.0.1: resolved "https://registry.yarnpkg.com/canonicalize/-/canonicalize-1.0.8.tgz#24d1f1a00ed202faafd9bf8e63352cd4450c6df1" integrity sha512-0CNTVCLZggSh7bc5VkX5WWPWO+cyZbNd07IHIsSXLia/eAq+r836hgk+8BKoEh7949Mda87VUOitx5OddVj64A== +canonicalize@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/canonicalize/-/canonicalize-2.0.0.tgz#32be2cef4446d67fd5348027a384cae28f17226a" + integrity sha512-ulDEYPv7asdKvqahuAY35c1selLdzDwHqugK92hfkzvlDCwXRRelDkR+Er33md/PtnpqHemgkuDPanZ4fiYZ8w== + +capability@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/capability/-/capability-0.2.5.tgz#51ad87353f1936ffd77f2f21c74633a4dea88801" + integrity sha512-rsJZYVCgXd08sPqwmaIqjAd5SUTfonV0z/gDJ8D6cN8wQphky1kkAYEqQ+hmDxTw7UihvBfjUVUSY+DBEe44jg== + +cartonne@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/cartonne/-/cartonne-3.0.1.tgz#70aea12530b7ca400630326edb7cbbd02031883d" + integrity sha512-Y8DH//DthEUbfvOMGYj/9K3F1RcWkiVu2dB9tGkiBnMqojAXTpu+TUs9FNNx202H0TQdJgbPsQl7Q6NuJ48dCw== + dependencies: + "@ipld/dag-cbor" "^9.0.7" + multiformats "^13.0.0" + multihashes-sync "^2.0.0" + varintes "^2.0.5" + caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== +catering@^2.1.0, catering@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/catering/-/catering-2.1.1.tgz#66acba06ed5ee28d5286133982a927de9a04b510" + integrity sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w== + cbor-extract@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cbor-extract/-/cbor-extract-2.2.0.tgz#cee78e630cbeae3918d1e2e58e0cebaf3a3be840" @@ -6919,11 +8565,21 @@ cbor-x@^1.3.0: optionalDependencies: cbor-extract "^2.2.0" +cborg@^1.10.2, cborg@^1.6.0: + version "1.10.2" + resolved "https://registry.yarnpkg.com/cborg/-/cborg-1.10.2.tgz#83cd581b55b3574c816f82696307c7512db759a1" + integrity sha512-b3tFPA9pUr2zCUiCfRd2+wok2/LBSNUMKOuRRok+WlvvAgEt/PlbgPTsZUcwCOs53IJvLgTp0eotwtosE6njug== + cborg@^4.0.0: version "4.1.3" resolved "https://registry.yarnpkg.com/cborg/-/cborg-4.1.3.tgz#5db6c9bcfe125cf1a653584840b6fe32ecd14580" integrity sha512-I8sAcVtiarz0dZ4IYixNUaL2hIl9cMDjo1ytI57F5fUlekTEO5Im8aXbAvsuayeP76hHSPRMwos0AUuntHJjqQ== +cborg@^4.0.5, cborg@^4.0.8: + version "4.2.1" + resolved "https://registry.yarnpkg.com/cborg/-/cborg-4.2.1.tgz#57170ef570dcdaf93575469a51f3b918a854669d" + integrity sha512-LSdnRagOTx1QZ3/ECLEOMc5fYHaDBjjQkBeBGtZ9KkGa78Opb5UzUxJeuxhmYTZm1DUzdBjj9JT3fcQNRL9ZBg== + chai@^4.3.4: version "4.4.1" resolved "https://registry.yarnpkg.com/chai/-/chai-4.4.1.tgz#3603fa6eba35425b0f2ac91a009fe924106e50d1" @@ -7012,6 +8668,11 @@ chokidar@^3.5.2, chokidar@^3.5.3: optionalDependencies: fsevents "~2.3.2" +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + chownr@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" @@ -7022,6 +8683,25 @@ chrome-trace-event@^1.0.2: resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +classic-level@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/classic-level/-/classic-level-1.4.1.tgz#169ecf9f9c6200ad42a98c8576af449c1badbaee" + integrity sha512-qGx/KJl3bvtOHrGau2WklEZuXhS3zme+jf+fsu6Ej7W7IP/C49v7KNlWIsT1jZu0YnfzSIYDGcEWpCa1wKGWXQ== + dependencies: + abstract-level "^1.0.2" + catering "^2.1.0" + module-error "^1.0.1" + napi-macros "^2.2.2" + node-gyp-build "^4.3.0" + clean-stack@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" @@ -7109,6 +8789,11 @@ cluster-key-slot@1.1.2: resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz#88ddaa46906e303b5de30d3153b7d9fe0a0c19ac" integrity sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA== +codeco@^1.1.0, codeco@^1.2.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/codeco/-/codeco-1.2.3.tgz#2ec2ea3cac5c9e4f077b502144c00cbabdb212b5" + integrity sha512-nbj0SrL3Cr5nWRwStBDYkA/lEJ9xm9TOjKk7Fo4rEspEC/fb9k3N9MvoK/ygTInBh5dqjsFGC9Bd6AE3GnAyxg== + color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -7133,6 +8818,16 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +color-support@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== + +colorette@2.0.19: + version "2.0.19" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" + integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== + colorette@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.4.0.tgz#5190fbb87276259a86ad700bff2c6d6faa3fca40" @@ -7143,6 +8838,11 @@ colorette@^2.0.16, colorette@^2.0.7: resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== +colors@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.0.tgz#5f20c9fef6945cb1134260aab33bfbdc8295e04e" + integrity sha512-EDpX3a7wHMWFA7PUHWPHNWqOxIIRSJetuwl0AS5Oi/5FMV8kWm69RTlgm00GKjBO1xFHMtBbL49yRtMMdticBw== + combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -7261,6 +8961,11 @@ config-chain@^1.1.13: ini "^1.3.4" proto-list "~1.2.1" +console-control-strings@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== + content-disposition@0.5.4: version "0.5.4" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" @@ -7422,11 +9127,77 @@ crc32-stream@^4.0.2: crc-32 "^1.2.0" readable-stream "^3.4.0" +create-hash@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.1.3.tgz#606042ac8b9262750f483caddab0f5819172d8fd" + integrity sha512-snRpch/kwQhcdlnZKYanNF1m0RDlrCdSKQaH87w1FCFPVPNCQ/Il9QJKAX2jVBZddRdaHBMC+zXa9Gw9tmkNUA== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + ripemd160 "^2.0.0" + sha.js "^2.4.0" + +create-hash@1.2.0, create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.6.tgz#acb9e221a4e17bdb076e90657c42b93e3726cf06" + integrity sha512-23osI7H2SH6Zm4g7A7BTM9+3XicGZkemw00eEhrFViR3EdGru+azj2fMKf9J2zWMGO7AfPgYRdIRL96kkdy8QA== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +create-hmac@^1.1.4, create-hmac@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + create-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== +cron-parser@^4.0.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/cron-parser/-/cron-parser-4.9.0.tgz#0340694af3e46a0894978c6f52a6dbb5c0f11ad5" + integrity sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q== + dependencies: + luxon "^3.2.1" + +cross-fetch@^3.1.5: + version "3.1.8" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.8.tgz#0327eba65fd68a7d119f8fb2bf9334a1a7956f82" + integrity sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg== + dependencies: + node-fetch "^2.6.12" + +cross-inspect@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cross-inspect/-/cross-inspect-1.0.0.tgz#5fda1af759a148594d2d58394a9e21364f6849af" + integrity sha512-4PFfn4b5ZN6FMNGSZlyb7wUhuN8wvj8t/VQHZdM4JsDcruGJ8L2kf9zao98QIrBPFCpdk27qst/AGTl7pL3ypQ== + dependencies: + tslib "^2.4.0" + cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" @@ -7451,6 +9222,11 @@ csstype@^3.0.2: resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== +cuint@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/cuint/-/cuint-0.2.2.tgz#408086d409550c2631155619e9fa7bcadc3b991b" + integrity sha512-d4ZVpCW31eWwCMe1YT3ur7mUDnTXbgwyzaL320DrcRT45rfjYxkt5QWLrmOJ+/UEAI2+fQgKe/fCjR8l4TpRgw== + cz-conventional-changelog@3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/cz-conventional-changelog/-/cz-conventional-changelog-3.3.0.tgz#9246947c90404149b3fe2cf7ee91acad3b7d22d2" @@ -7465,6 +9241,22 @@ cz-conventional-changelog@3.3.0: optionalDependencies: "@commitlint/load" ">6.1.1" +dag-jose-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/dag-jose-utils/-/dag-jose-utils-3.0.0.tgz#38a0fb1e17c0af5ea148fdd50a8b77671fe329fa" + integrity sha512-gu+XutOTy3kD8fDcA1SMjZ2U0mUOb/hxoRVZaMCizXN7Ssbc5dKOzeXQ4GquV4BdQzs3w5Y7irOpn2plFPIJfg== + dependencies: + "@ipld/dag-cbor" "^7.0.1" + multiformats "^11.0.1" + +dag-jose-utils@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/dag-jose-utils/-/dag-jose-utils-4.0.0.tgz#0cdecb555e6dbff2f023f36beee5b2a14d93d337" + integrity sha512-bmmXtVdEKp/zYH8El4GGkMREJioUztz8fzOErfy5dTbyKIVOF61C5sfsZLYCB/wiT/I9+SPNrQeo/Cx6Ik3wJQ== + dependencies: + "@ipld/dag-cbor" "^9.0.7" + multiformats "^13.0.0" + dag-jose@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/dag-jose/-/dag-jose-4.0.0.tgz#4e65f62af58dd5203b2b094eb52142ffe0cdec1d" @@ -7490,6 +9282,11 @@ data-uri-to-buffer@^4.0.0: resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz#d8feb2b2881e6a4f58c2e08acfd0e2834e26222e" integrity sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A== +dataloader@2.2.2, dataloader@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/dataloader/-/dataloader-2.2.2.tgz#216dc509b5abe39d43a9b9d97e6e5e473dfbe3e0" + integrity sha512-8YnDaaf7N3k/q5HnTJVuzSyLETjoZjVmHc4AeKAzOvKHEFQKcn64OKBfzHYtE9zGjctNM7V9I0MfnUVLpi7M5g== + date-fns@^2.30.0: version "2.30.0" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0" @@ -7528,6 +9325,13 @@ debug@^3.2.7: dependencies: ms "^2.1.1" +debug@^4.3.3: + version "4.3.5" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.5.tgz#e83444eceb9fedd4a1da56d671ae2446a01a6e1e" + integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg== + dependencies: + ms "2.1.2" + decamelize-keys@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.1.tgz#04a2d523b2f18d80d0158a43b895d56dff8d19d8" @@ -7546,6 +9350,18 @@ decamelize@^4.0.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== +decode-uri-component@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" + integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== + +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + dedent@0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" @@ -7558,6 +9374,11 @@ deep-eql@^4.1.3: dependencies: type-detect "^4.0.0" +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" @@ -7600,16 +9421,31 @@ define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1: has-property-descriptors "^1.0.0" object-keys "^1.1.1" +delay@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/delay/-/delay-5.0.0.tgz#137045ef1b96e5071060dd5be60bf9334436bd1d" + integrity sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw== + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -depd@2.0.0: +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== + +depd@2.0.0, depd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== + destroy@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" @@ -7625,6 +9461,11 @@ detect-indent@6.1.0: resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.1.0.tgz#592485ebbbf6b3b1ab2be175c8393d04ca0d57e6" integrity sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA== +detect-libc@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700" + integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw== + detect-libc@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.2.tgz#8ccf2ba9315350e1241b88d0ac3b0e1fbd99605d" @@ -7643,6 +9484,60 @@ dezalgo@^1.0.4: asap "^2.0.0" wrappy "1" +did-jwt@^7.2.0, did-jwt@^7.4.7: + version "7.4.7" + resolved "https://registry.yarnpkg.com/did-jwt/-/did-jwt-7.4.7.tgz#44105fb0a0cdfd78c087de52087422075c674700" + integrity sha512-Apz7nIfIHSKWIMaEP5L/K8xkwByvjezjTG0xiqwKdnNj1x8M0+Yasury5Dm/KPltxi2PlGfRPf3IejRKZrT8mQ== + dependencies: + "@noble/ciphers" "^0.4.0" + "@noble/curves" "^1.0.0" + "@noble/hashes" "^1.3.0" + "@scure/base" "^1.1.3" + canonicalize "^2.0.0" + did-resolver "^4.1.0" + multibase "^4.0.6" + multiformats "^9.6.2" + uint8arrays "3.1.1" + +did-resolver@^4.0.1, did-resolver@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/did-resolver/-/did-resolver-4.1.0.tgz#740852083c4fd5bf9729d528eca5d105aff45eb6" + integrity sha512-S6fWHvCXkZg2IhS4RcVHxwuyVejPR7c+a4Go0xbQ9ps5kILa8viiYQgrM4gfTyeTjJ0ekgJH9gk/BawTpmkbZA== + +dids@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/dids/-/dids-4.0.4.tgz#b84e10f0d41554c91cfe9f06f731bfc1f70cfe60" + integrity sha512-PKxQP0QFqgeMe0dbL7LCRdPJVhZU2ejj8RWCfJ6vro3a+o5o32cWNM1X6YXpdIWq6G5fTJw9KO2dHj2ZzYDc7w== + dependencies: + "@didtools/cacao" "^2.1.0" + "@didtools/codecs" "^1.0.1" + "@didtools/pkh-ethereum" "^0.4.1" + "@stablelib/random" "^1.0.1" + codeco "^1.1.0" + dag-jose-utils "^3.0.0" + did-jwt "^7.2.0" + did-resolver "^4.1.0" + multiformats "^11.0.2" + rpc-utils "^0.6.1" + uint8arrays "^4.0.3" + +dids@^5.0.0, dids@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/dids/-/dids-5.0.2.tgz#5a87b101814a46cdc2ecc0d32fa5c0e6d78e8ccb" + integrity sha512-sxTgrvJtatqdm7dukGbquk23BVvbiaxf3nTKywWaY9AUqwC2IYEo6FG0En2cMl3J1fqMMQXrGg9luh2xDmYOmw== + dependencies: + "@didtools/cacao" "^3.0.1" + "@didtools/codecs" "^3.0.0" + "@didtools/pkh-ethereum" "^0.5.0" + "@stablelib/random" "^1.0.2" + codeco "^1.2.0" + dag-jose-utils "^4.0.0" + did-jwt "^7.4.7" + did-resolver "^4.1.0" + multiformats "^13.0.0" + rpc-utils "^0.6.2" + uint8arrays "^5.0.1" + didyoumean@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037" @@ -7748,6 +9643,11 @@ dotenv@^10.0.0: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== +dset@^3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/dset/-/dset-3.1.3.tgz#c194147f159841148e8e34ca41f638556d9542d2" + integrity sha512-20TuZZHCEZ2O71q9/+8BwKwZ0QtD9D8ObhrihJPr+vLLYlSuAU3/zL4cSlgbfeoGHTjCSJBa7NGcrF9/Bx/WJQ== + eastasianwidth@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" @@ -7768,6 +9668,20 @@ ecdsa-sig-formatter@1.0.11, ecdsa-sig-formatter@^1.0.11: dependencies: safe-buffer "^5.0.1" +ecurve@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/ecurve/-/ecurve-1.0.5.tgz#d148e8fe50a674f983bb5bae09da0ea23e10535e" + integrity sha512-1Z3Zu5Nh5LSVGnwEnie1LDoHZByZxG2tk3wftkqeVHrfujmR8O+dOh96HVPxRPh4BjRWX0Z9mpwCYv/O/njgDw== + dependencies: + bigi "^1.1.0" + +ed2curve@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/ed2curve/-/ed2curve-0.3.0.tgz#322b575152a45305429d546b071823a93129a05d" + integrity sha512-8w2fmmq3hv9rCrcI7g9hms2pMunQr1JINfcjwR9tAyZqhtyaMN991lF/ZfHfr5tzZQ8c7y7aBgZbjfbd0fjFwQ== + dependencies: + tweetnacl "1.x.x" + editorconfig@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-1.0.4.tgz#040c9a8e9a6c5288388b87c2db07028aa89f53a3" @@ -7808,6 +9722,19 @@ elliptic@6.5.4: minimalistic-assert "^1.0.1" minimalistic-crypto-utils "^1.0.1" +elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.4: + version "6.5.5" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.5.tgz#c715e09f78b6923977610d4c2346d6ce22e6dded" + integrity sha512-7EjbcmUm17NQFu4Pmgmq2olYMj8nwMnpcddByChSUjArp8F5DQWcIcpriwO4ZToLNAJig0yiyjswfyGNje/ixw== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" @@ -7823,7 +9750,7 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== -encoding@^0.1.13: +encoding@^0.1.12, encoding@^0.1.13: version "0.1.13" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== @@ -7890,6 +9817,31 @@ entities@^4.2.0, entities@^4.4.0: resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== +env-paths@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== + +eosjs-ecc@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eosjs-ecc/-/eosjs-ecc-4.0.7.tgz#f5246da3b84839fcc237204768ef6e5ea56cc814" + integrity sha512-uuqhqnrDy9XTpKfkhiZqRDUTCCI9oWBalVK5IosL7kpYwA9I3lm68INYFLyWsHpF2xwHqPql8MrMYJ3zfOn5Qg== + dependencies: + "@babel/runtime" "7.6.0" + bigi "1.4.2" + browserify-aes "1.0.6" + bs58 "4.0.1" + bytebuffer "5.0.1" + create-hash "1.1.3" + create-hmac "1.1.6" + ecurve "1.0.5" + randombytes "2.0.5" + +err-code@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" + integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== + err-code@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/err-code/-/err-code-3.0.1.tgz#a444c7b992705f2b120ee320b09972eef331c920" @@ -7902,6 +9854,15 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" +error-polyfill@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/error-polyfill/-/error-polyfill-0.1.3.tgz#df848b61ad8834f7a5db69a70b9913df86721d15" + integrity sha512-XHJk60ufE+TG/ydwp4lilOog549iiQF2OAPhkk9DdiYWMrltz5yhDz/xnKuenNwP7gy3dsibssO5QpVhkrSzzg== + dependencies: + capability "^0.2.5" + o3 "^1.0.3" + u3 "^0.1.1" + error@7.0.2: version "7.0.2" resolved "https://registry.yarnpkg.com/error/-/error-7.0.2.tgz#a5f75fff4d9926126ddac0ea5dc38e689153cb02" @@ -8217,6 +10178,11 @@ eslint@^7.32.0: text-table "^0.2.0" v8-compile-cache "^2.0.3" +esm@^3.2.25: + version "3.2.25" + resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" + integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== + espree@^7.3.0, espree@^7.3.1: version "7.3.1" resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" @@ -8326,6 +10292,14 @@ events@3.3.0, events@^3.2.0, events@^3.3.0: resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== +evp_bytestokey@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + execa@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" @@ -8356,6 +10330,11 @@ execa@^5.0.0, execa@^5.1.1: signal-exit "^3.0.3" strip-final-newline "^2.0.0" +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + expand-tilde@^2.0.0, expand-tilde@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" @@ -8455,7 +10434,12 @@ fast-glob@^3.2.9, fast-glob@^3.3.0: merge2 "^1.3.0" micromatch "^4.0.4" -fast-json-stable-stringify@^2.0.0: +fast-json-patch@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-json-patch/-/fast-json-patch-3.1.1.tgz#85064ea1b1ebf97a3f7ad01e23f9337e72c66947" + integrity sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ== + +fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== @@ -8528,6 +10512,11 @@ file-type@^3.3.0: resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" integrity sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA== +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + fill-range@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" @@ -8535,6 +10524,11 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" +filter-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b" + integrity sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ== + finalhandler@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" @@ -8620,6 +10614,11 @@ follow-redirects@^1.0.0, follow-redirects@^1.14.7, follow-redirects@^1.14.8, fol resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.5.tgz#54d4d6d062c0fa7d9d17feb008461550e3ba8020" integrity sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw== +follow-redirects@^1.14.4: + version "1.15.6" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" + integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== + for-each@^0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" @@ -8748,6 +10747,11 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== +fs@0.0.1-security: + version "0.0.1-security" + resolved "https://registry.yarnpkg.com/fs/-/fs-0.0.1-security.tgz#8a7bd37186b6dddf3813f23858b57ecaaf5e41d4" + integrity sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w== + fsevents@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" @@ -8778,6 +10782,20 @@ functions-have-names@^1.2.3: resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== +gauge@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.4.tgz#52ff0652f2bbf607a989793d53b751bef2328dce" + integrity sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg== + dependencies: + aproba "^1.0.3 || ^2.0.0" + color-support "^1.1.3" + console-control-strings "^1.1.0" + has-unicode "^2.0.1" + signal-exit "^3.0.7" + string-width "^4.2.3" + strip-ansi "^6.0.1" + wide-align "^1.1.5" + gaxios@^5.0.0: version "5.1.3" resolved "https://registry.yarnpkg.com/gaxios/-/gaxios-5.1.3.tgz#f7fa92da0fe197c846441e5ead2573d4979e9013" @@ -8891,6 +10909,11 @@ get-them-args@1.3.2: resolved "https://registry.yarnpkg.com/get-them-args/-/get-them-args-1.3.2.tgz#74a20ba8a4abece5ae199ad03f2bcc68fdfc9ba5" integrity sha512-LRn8Jlk+DwZE4GTlDbT3Hikd1wSHgLMme/+7ddlqKd7ldwR6LjJgTVWzBnR01wnYGe4KgrXjg287RaI22UHmAw== +getopts@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/getopts/-/getopts-2.3.0.tgz#71e5593284807e03e2427449d4f6712a268666f4" + integrity sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA== + getpass@^0.1.1: version "0.1.7" resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" @@ -8909,6 +10932,11 @@ git-raw-commits@^2.0.0: split2 "^3.0.0" through2 "^4.0.0" +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw== + glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -9077,7 +11105,12 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" -graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.9: +gql-query-builder@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/gql-query-builder/-/gql-query-builder-3.8.0.tgz#d182d127f88abb7d39f7bec2c64f8b4570812e2f" + integrity sha512-q0PncZTrLDeyiH4R7YH1ISM+XGB4NvQ8eTm/Wr/sHSuquFZvqvDpGyMhbgoCZDc8kNAK8GOdfh3nI2GCLREFvw== + +graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -9087,6 +11120,23 @@ graphemer@^1.4.0: resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== +graphql-relay@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/graphql-relay/-/graphql-relay-0.10.1.tgz#4729ec92b5cf73879cf76d817ddbee7808d1cec9" + integrity sha512-8AtwSe6B0/b4+YzynHr38PP7S+zX5Vs5LEo0BEzGCPq/THAiHa5H5ZLf3bRbKbok15ADxDQSsGJmlqXeJDDPIw== + +graphql-scalars@^1.22.5: + version "1.23.0" + resolved "https://registry.yarnpkg.com/graphql-scalars/-/graphql-scalars-1.23.0.tgz#486785d1a6f9449277054a92afc7e1fb73f459d6" + integrity sha512-YTRNcwitkn8CqYcleKOx9IvedA8JIERn8BRq21nlKgOr4NEcTaWEG0sT+H92eF3ALTFbPgsqfft4cw+MGgv0Gg== + dependencies: + tslib "^2.5.0" + +graphql@^16.8.0, graphql@^16.8.1: + version "16.8.2" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.8.2.tgz#54771c7ff195da913f5e70af8044a026d32eca2a" + integrity sha512-cvVIBILwuoSyD54U4cF/UXDh5yAobhNV/tPygI4lZhgOIJQE/WLWC4waBRb4I6bDVYb3OVx3lfHbaQOEoUD5sg== + gtoken@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-7.1.0.tgz#d61b4ebd10132222817f7222b1e6064bd463fc26" @@ -9159,7 +11209,21 @@ has-tostringtag@^1.0.0, has-tostringtag@^1.0.2: dependencies: has-symbols "^1.0.3" -hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3: +has-unicode@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== + +hash-base@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== + dependencies: + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== @@ -9281,6 +11345,11 @@ htmlparser2@^8.0.2: domutils "^3.0.1" entities "^4.4.0" +http-cache-semantics@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" + integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== + http-errors@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" @@ -9292,6 +11361,26 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" +http-errors@^1.7.2: + version "1.8.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" + integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.1" + +http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== + dependencies: + "@tootallnate/once" "1" + agent-base "6" + debug "4" + http-proxy-middleware@3.0.0-beta.0: version "3.0.0-beta.0" resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-3.0.0-beta.0.tgz#4c32cd1a190ec3c5d4e255b88c267ef47de0ec32" @@ -9348,6 +11437,13 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== + dependencies: + ms "^2.0.0" + iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -9417,6 +11513,11 @@ indent-string@^4.0.0: resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== +infer-owner@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -9435,7 +11536,7 @@ ini@4.1.1: resolved "https://registry.yarnpkg.com/ini/-/ini-4.1.1.tgz#d95b3d843b1e906e56d6747d5447904ff50ce7a1" integrity sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g== -ini@^1.3.4: +ini@^1.3.4, ini@~1.3.0: version "1.3.8" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== @@ -9502,6 +11603,11 @@ interpret@^1.0.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== +interpret@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" + integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== + invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" @@ -9509,6 +11615,19 @@ invariant@^2.2.4: dependencies: loose-envify "^1.0.0" +ip-address@^9.0.5: + version "9.0.5" + resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-9.0.5.tgz#117a960819b08780c3bd1f14ef3c1cc1d3f3ea5a" + integrity sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g== + dependencies: + jsbn "1.1.0" + sprintf-js "^1.1.3" + +ip-regex@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5" + integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q== + ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" @@ -9530,7 +11649,7 @@ ipfs-core-types@^0.14.1: ipfs-unixfs "^9.0.0" multiformats "^11.0.0" -ipfs-core-utils@^0.18.0: +ipfs-core-utils@^0.18.0, ipfs-core-utils@^0.18.1: version "0.18.1" resolved "https://registry.yarnpkg.com/ipfs-core-utils/-/ipfs-core-utils-0.18.1.tgz#d5fae11bfdb511749c6f905b0d0da3174eb50909" integrity sha512-P7jTpdfvlyBG3JR4o+Th3QJADlmXmwMxbkjszXry6VAjfSfLIIqXsdeYPoVRkV69GFEeQozuz2k/jR+U8cUH/Q== @@ -9556,6 +11675,31 @@ ipfs-core-utils@^0.18.0: timeout-abort-controller "^3.0.0" uint8arrays "^4.0.2" +ipfs-http-client@^60.0.0: + version "60.0.1" + resolved "https://registry.yarnpkg.com/ipfs-http-client/-/ipfs-http-client-60.0.1.tgz#d2e9ab430aad43a92a6e44008e534afba4fd22b9" + integrity sha512-amwM5TNuf077J+/q27jPHfatC05vJuIbX6ZnlYLjc2QsjOCKsORNBqV3brNw7l+fPrijV1yrwEDLG3JEnKsfMw== + dependencies: + "@ipld/dag-cbor" "^9.0.0" + "@ipld/dag-json" "^10.0.0" + "@ipld/dag-pb" "^4.0.0" + "@libp2p/logger" "^2.0.5" + "@libp2p/peer-id" "^2.0.0" + "@multiformats/multiaddr" "^11.1.5" + any-signal "^3.0.0" + dag-jose "^4.0.0" + err-code "^3.0.1" + ipfs-core-types "^0.14.1" + ipfs-core-utils "^0.18.1" + ipfs-utils "^9.0.13" + it-first "^2.0.0" + it-last "^2.0.0" + merge-options "^3.0.4" + multiformats "^11.0.0" + parse-duration "^1.0.0" + stream-to-it "^0.2.2" + uint8arrays "^4.0.2" + ipfs-unixfs@^11.1.3: version "11.1.3" resolved "https://registry.yarnpkg.com/ipfs-unixfs/-/ipfs-unixfs-11.1.3.tgz#b53f36d8d34022516d6cfead4305839712c1dab2" @@ -9638,6 +11782,11 @@ is-boolean-object@^1.1.0: call-bind "^1.0.2" has-tostringtag "^1.0.0" +is-buffer@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" + integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== + is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" @@ -9691,6 +11840,11 @@ is-interactive@^1.0.0: resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== +is-lambda@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" + integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== + is-negative-zero@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz#ced903a027aca6381b777a5743069d7376a49747" @@ -9843,6 +11997,11 @@ isomorphic-ws@^5.0.0: resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf" integrity sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw== +isows@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/isows/-/isows-1.0.3.tgz#93c1cf0575daf56e7120bab5c8c448b0809d0d74" + integrity sha512-2cKei4vlmg2cxEjm3wVSqn8pcoRF/LX/wpifuuNquFO4SQmPwarClT+SUCA2lt+l581tTeZIPIZuIDo2jWN1fg== + isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" @@ -9918,11 +12077,26 @@ it-all@^2.0.0: resolved "https://registry.yarnpkg.com/it-all/-/it-all-2.0.1.tgz#45d530ecf6e13fb81d7ba583cdfd55ffdb376b05" integrity sha512-9UuJcCRZsboz+HBQTNOau80Dw+ryGaHYFP/cPYzFBJBFcfDathMYnhHk4t52en9+fcyDGPTdLB+lFc1wzQIroA== +it-all@^3.0.1: + version "3.0.6" + resolved "https://registry.yarnpkg.com/it-all/-/it-all-3.0.6.tgz#30a4f922ae9ca0945b0f720d3478ae6f5b6707ab" + integrity sha512-HXZWbxCgQZJfrv5rXvaVeaayXED8nTKx9tj9fpBhmcUJcedVZshMMMqTj0RG2+scGypb9Ut1zd1ifbf3lA8L+Q== + +it-batch@^3.0.1: + version "3.0.6" + resolved "https://registry.yarnpkg.com/it-batch/-/it-batch-3.0.6.tgz#0bcda35bf1c600e821c6d5f4d2446fe85a26ab1d" + integrity sha512-pQAAlSvJ4aV6xM/6LRvkPdKSKXxS4my2fGzNUxJyAQ8ccFdxPmK1bUuF5OoeUDkcdrbs8jtsmc4DypCMrGY6sg== + it-first@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/it-first/-/it-first-2.0.1.tgz#75d66b254c385ae3a1906def060a69006a437cef" integrity sha512-noC1oEQcWZZMUwq7VWxHNLML43dM+5bviZpfmkxkXlvBe60z7AFRqpZSga9uQBo792jKv9otnn1IjA4zwgNARw== +it-first@^3.0.4: + version "3.0.6" + resolved "https://registry.yarnpkg.com/it-first/-/it-first-3.0.6.tgz#f532f0f36fe9bf0c291e0162b9d3375d59fe8f05" + integrity sha512-ExIewyK9kXKNAplg2GMeWfgjUcfC1FnUXz/RPfAvIXby+w7U4b3//5Lic0NV03gXT8O/isj5Nmp6KiY0d45pIQ== + it-glob@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/it-glob/-/it-glob-1.0.2.tgz#bab9b04d6aaac42884502f3a0bfee84c7a29e15e" @@ -10011,6 +12185,13 @@ jest-worker@^27.4.5: merge-stream "^2.0.0" supports-color "^8.0.0" +jet-logger@1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/jet-logger/-/jet-logger-1.2.2.tgz#f3866c0a34b6dc43f03bf4479ca677a1110156bc" + integrity sha512-Kbw4G3BC45+Umz5XBnsE50pHplruJTVKGRy5X1YfCu3Te7f8ggTL8Tm10YegAD2QP41MVQ3o/Y9MFAZzfythqw== + dependencies: + colors "1.3.0" + jiti@^1.19.1: version "1.21.0" resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.0.tgz#7c97f8fe045724e136a397f7340475244156105d" @@ -10053,7 +12234,12 @@ js-cookie@^3.0.5: resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-3.0.5.tgz#0b7e2fd0c01552c58ba86e0841f94dc2557dcdbc" integrity sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw== -js-sha3@0.8.0: +js-sha256@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/js-sha256/-/js-sha256-0.9.0.tgz#0b89ac166583e91ef9123644bd3c5334ce9d0966" + integrity sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA== + +js-sha3@0.8.0, js-sha3@^0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== @@ -10078,6 +12264,11 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" +jsbn@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040" + integrity sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A== + jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" @@ -10105,6 +12296,11 @@ json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== +json-ptr@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/json-ptr/-/json-ptr-3.1.1.tgz#184c3d48db659fa9bbc1519f7db6f390ddffb659" + integrity sha512-SiSJQ805W1sDUCD1+/t1/1BIrveq2Fe9HJqENxZmMCILmrPI7WhS/pePpIOx85v6/H2z1Vy7AI08GV2TzfXocg== + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -10115,6 +12311,11 @@ json-schema-traverse@^1.0.0: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== +json-schema-typed@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/json-schema-typed/-/json-schema-typed-8.0.1.tgz#826ee39e3b6cef536f85412ff048d3ff6f19dfa0" + integrity sha512-XQmWYj2Sm4kn4WeTYvmpKEbyPsL7nBsb647c7pMe6l02/yx2+Jfc4dT6UZkEXnIUb5LhD55r2HPsJ1milQ4rDg== + json-schema@0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" @@ -10166,6 +12367,15 @@ jsonparse@^1.2.0: resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== +jsontokens@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/jsontokens/-/jsontokens-4.0.1.tgz#c3edf74a01160b2ca6d62b021b288edd59d1184a" + integrity sha512-+MO415LEN6M+3FGsRz4wU20g7N2JA+2j9d9+pGaNJHviG4L8N0qzavGyENw6fJqsq9CcrHOIL6iWX5yeTZ86+Q== + dependencies: + "@noble/hashes" "^1.1.2" + "@noble/secp256k1" "^1.6.3" + base64-js "^1.5.1" + jsonwebtoken@^8.5.1: version "8.5.1" resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" @@ -10226,6 +12436,40 @@ jws@^4.0.0: jwa "^2.0.0" safe-buffer "^5.0.1" +key-did-provider-ed25519@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/key-did-provider-ed25519/-/key-did-provider-ed25519-3.0.2.tgz#5c336954680db2ae03e9d4a25cdbde30b72062b5" + integrity sha512-4Yw0CeO1hKRaUsh9NIz4tn4Ysr09CdoJItyT0vHjd5iedJ+FvVt7pTbNr7IY0/+8mWvYslutAK5LFrwu5agpsA== + dependencies: + "@noble/curves" "^1.1.0" + did-jwt "^7.2.0" + dids "^4.0.4" + fast-json-stable-stringify "^2.1.0" + rpc-utils "^0.6.2" + uint8arrays "^4.0.3" + +key-did-provider-ed25519@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/key-did-provider-ed25519/-/key-did-provider-ed25519-4.0.2.tgz#f1ae847257e5aefff7ac6899630231034e62da05" + integrity sha512-bnnRGuuUtylKGMVmgXVSoGccBg87roFi6xy5dQmTgNqnCmrxBBUatYoVimcnA+SGCFqi2qk6B9dD10Ed4rTZPg== + dependencies: + "@noble/curves" "^1.3.0" + did-jwt "^7.4.7" + dids "^5.0.2" + fast-json-stable-stringify "^2.1.0" + rpc-utils "^0.6.2" + uint8arrays "^5.0.1" + +key-did-resolver@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/key-did-resolver/-/key-did-resolver-4.0.0.tgz#011910ef2db7db82977466ac6850b4976f8cd761" + integrity sha512-+U2nd/0rjO4Yqe2hnHBD7ygcLRfT43Oje9IIjv1BlBi0lopwxZpIFQ7GekguOHK02r+JGdl8mpJVNHs5lvXVOA== + dependencies: + "@noble/curves" "^1.2.0" + multiformats "^13.0.0" + uint8arrays "^5.0.1" + varint "^6.0.0" + keyv@^4.5.3: version "4.5.4" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" @@ -10246,6 +12490,26 @@ kind-of@^6.0.3: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== +knex@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/knex/-/knex-2.5.1.tgz#a6c6b449866cf4229f070c17411f23871ba52ef9" + integrity sha512-z78DgGKUr4SE/6cm7ku+jHvFT0X97aERh/f0MUKAKgFnwCYBEW4TFBqtHWFYiJFid7fMrtpZ/gxJthvz5mEByA== + dependencies: + colorette "2.0.19" + commander "^10.0.0" + debug "4.3.4" + escalade "^3.1.1" + esm "^3.2.25" + get-package-type "^0.1.0" + getopts "2.3.0" + interpret "^2.2.0" + lodash "^4.17.21" + pg-connection-string "2.6.1" + rechoir "^0.8.0" + resolve-from "^5.0.0" + tarn "^3.0.2" + tildify "2.0.0" + kubo-rpc-client@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/kubo-rpc-client/-/kubo-rpc-client-3.0.4.tgz#4027b0abeb848d4a5bdb18a7d614af5173966575" @@ -10296,6 +12560,43 @@ leac@^0.6.0: resolved "https://registry.yarnpkg.com/leac/-/leac-0.6.0.tgz#dcf136e382e666bd2475f44a1096061b70dc0912" integrity sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg== +least-recent@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/least-recent/-/least-recent-1.0.3.tgz#8c11b57c3874dac051f65e265b690e10a35390c6" + integrity sha512-PH9ZuFAKFf5fY7j0wizus6f/Ni2wSaby4eQYEUmR+sK6lY7OEbVz/iEh/tTgEmgOivWJhay89wVyUe5VnXoUSQ== + dependencies: + nanoevents "^8.0.0" + +leb128@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/leb128/-/leb128-0.0.5.tgz#84524a86ef7799fb3933ce41345f6490e27ac948" + integrity sha512-elbNtfmu3GndZbesVF6+iQAfVjOXW9bM/aax9WwMlABZW+oK9sbAZEXoewaPHmL34sxa8kVwWsru8cNE/yn2gg== + dependencies: + bn.js "^5.0.0" + buffer-pipe "0.0.3" + +level-supports@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-4.0.1.tgz#431546f9d81f10ff0fea0e74533a0e875c08c66a" + integrity sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA== + +level-transcoder@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/level-transcoder/-/level-transcoder-1.0.1.tgz#f8cef5990c4f1283d4c86d949e73631b0bc8ba9c" + integrity sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w== + dependencies: + buffer "^6.0.3" + module-error "^1.0.1" + +level@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/level/-/level-8.0.1.tgz#737161db1bc317193aca4e7b6f436e7e1df64379" + integrity sha512-oPBGkheysuw7DmzFQYyFe8NAia5jFLAgEnkgWnK3OXAuJr8qFT+xBQIwokAZPME2bhPFzS8hlYcL16m8UZrtwQ== + dependencies: + abstract-level "^1.0.4" + browser-level "^1.0.1" + classic-level "^1.2.0" + levn@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" @@ -10382,6 +12683,16 @@ lodash.camelcase@^4.3.0: resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== + lodash.defaults@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" @@ -10422,6 +12733,11 @@ lodash.isinteger@^4.0.4: resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA== +lodash.ismatch@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37" + integrity sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g== + lodash.isnumber@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" @@ -10495,6 +12811,14 @@ log-update@^4.0.0: slice-ansi "^4.0.0" wrap-ansi "^6.2.0" +logfmt@^1.3.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/logfmt/-/logfmt-1.4.0.tgz#6cb1e62cf65143a3248aa0f2823c3bd436e2251f" + integrity sha512-p1Ow0C2dDJYaQBhRHt+HVMP6ELuBm4jYSYNHPMfz0J5wJ9qA6/7oBOlBZBfT1InqguTYcvJzNea5FItDxTcbyw== + dependencies: + split "0.2.x" + through "2.3.x" + long@^2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/long/-/long-2.4.0.tgz#9fa180bb1d9500cdc29c4156766a1995e1f4524f" @@ -10505,6 +12829,11 @@ long@^5.0.0: resolved "https://registry.yarnpkg.com/long/-/long-5.2.3.tgz#a3ba97f3877cf1d778eccbcb048525ebb77499e1" integrity sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q== +long@~3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b" + integrity sha512-ZYvPPOMqUwPoDsbJaR10iQJYnMuZhRTvHYl62ErLIEX7RgFlziSBUUvrt3OVfc47QlHHpzPZYP17g3Fv7oeJkg== + longest@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/longest/-/longest-2.0.1.tgz#781e183296aa94f6d4d916dc335d0d17aefa23f8" @@ -10543,6 +12872,11 @@ lru-cache@^6.0.0: resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.0.tgz#0bd445ca57363465900f4d1f9bd8db343a4d95c3" integrity sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q== +luxon@^3.2.1: + version "3.4.4" + resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.4.4.tgz#cf20dc27dc532ba41a169c43fdcc0063601577af" + integrity sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA== + make-dir@^3.0.0, make-dir@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" @@ -10562,6 +12896,28 @@ make-error@^1, make-error@^1.1.1: resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== +make-fetch-happen@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz#53085a09e7971433e6765f7971bf63f4e05cb968" + integrity sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg== + dependencies: + agentkeepalive "^4.1.3" + cacache "^15.2.0" + http-cache-semantics "^4.1.0" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^6.0.0" + minipass "^3.1.3" + minipass-collect "^1.0.2" + minipass-fetch "^1.3.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + negotiator "^0.6.2" + promise-retry "^2.0.1" + socks-proxy-agent "^6.0.0" + ssri "^8.0.0" + map-obj@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" @@ -10572,6 +12928,11 @@ map-obj@^4.0.0: resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a" integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ== +mapmoize@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/mapmoize/-/mapmoize-1.2.1.tgz#a491a01dfc9f851478120057d98af9b160edf4d7" + integrity sha512-LK8ArSM1wbfRPTnl+LpdxW1pwkfY6GxtM9p+STr6aDtM7ImR8jLuf4ekei43/AN0f7XDSrohzwwK57eGHSDAuA== + marked@7.0.4: version "7.0.4" resolved "https://registry.yarnpkg.com/marked/-/marked-7.0.4.tgz#e2558ee2d535b9df6a27c6e282dc603a18388a6d" @@ -10584,6 +12945,15 @@ md-to-react-email@4.1.0: dependencies: marked "7.0.4" +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -10655,6 +13025,11 @@ methods@^1.1.2, methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== +micro-base@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/micro-base/-/micro-base-0.9.0.tgz#09cfe20285bec0ea97f41dc3d10e3fba3d0266ee" + integrity sha512-4+tOMKidYT5nQ6/UNmYrGVO5PMcnJdfuR4NC8HK8s2H61B4itOhA9yrsjBdqGV7ecdtej36x3YSIfPLRmPrspg== + micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" @@ -10690,6 +13065,11 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + min-indent@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" @@ -10754,12 +13134,51 @@ minimist@1.2.7: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== -minimist@^1.1.0, minimist@^1.2.0, minimist@^1.2.6: +minimist@^1.1.0, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.6: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== -minipass@^3.0.0: +minipass-collect@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" + integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== + dependencies: + minipass "^3.0.0" + +minipass-fetch@^1.3.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-1.4.1.tgz#d75e0091daac1b0ffd7e9d41629faff7d0c1f1b6" + integrity sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw== + dependencies: + minipass "^3.1.0" + minipass-sized "^1.0.3" + minizlib "^2.0.0" + optionalDependencies: + encoding "^0.1.12" + +minipass-flush@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" + integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== + dependencies: + minipass "^3.0.0" + +minipass-pipeline@^1.2.2, minipass-pipeline@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" + integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== + dependencies: + minipass "^3.0.0" + +minipass-sized@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" + integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== + dependencies: + minipass "^3.0.0" + +minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3: version "3.3.6" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== @@ -10781,7 +13200,7 @@ minipass@^5.0.0: resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== -minizlib@^2.1.1: +minizlib@^2.0.0, minizlib@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== @@ -10789,6 +13208,11 @@ minizlib@^2.1.1: minipass "^3.0.0" yallist "^4.0.0" +mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + mkdirp@^0.5.4: version "0.5.6" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" @@ -10832,6 +13256,11 @@ module-details-from-path@^1.0.3: resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b" integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A== +module-error@^1.0.1, module-error@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/module-error/-/module-error-1.0.2.tgz#8d1a48897ca883f47a45816d4fb3e3c6ba404d86" + integrity sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA== + mri@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b" @@ -10847,7 +13276,7 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3, ms@^2.1.1: +ms@2.1.3, ms@^2.0.0, ms@^2.1.1: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -10875,7 +13304,14 @@ multer@^1.4.5-lts.1: type-is "^1.6.4" xtend "^4.0.0" -multiformats@^11.0.0, multiformats@^11.0.2: +multibase@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/multibase/-/multibase-4.0.6.tgz#6e624341483d6123ca1ede956208cb821b440559" + integrity sha512-x23pDe5+svdLz/k5JPGCVdfn7Q5mZVMBETiC+ORfO+sor9Sgs0smJzAjfTbM5tckeCqnaUuMYoz+k3RXMmJClQ== + dependencies: + "@multiformats/base-x" "^4.0.1" + +multiformats@^11.0.0, multiformats@^11.0.1, multiformats@^11.0.2: version "11.0.2" resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-11.0.2.tgz#b14735efc42cd8581e73895e66bebb9752151b60" integrity sha512-b5mYMkOkARIuVZCpvijFj9a6m5wMVLC7cf/jIPd5D/ARDOfLC5+IFkbgDXQgcU2goIsTD/O9NY4DI/Mt4OGvlg== @@ -10890,6 +13326,24 @@ multiformats@^13.0.0, multiformats@^13.1.0: resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-13.1.0.tgz#5aa9d2175108a448fc3bdb54ba8a3d0b6cab3ac3" integrity sha512-HzdtdBwxsIkzpeXzhQ5mAhhuxcHbjEHH+JQoxt7hG/2HGFjjwyolLo7hbaexcnhoEuV4e0TNJ8kkpMjiEYY4VQ== +multiformats@^9.4.2, multiformats@^9.5.4, multiformats@^9.6.2: + version "9.9.0" + resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-9.9.0.tgz#c68354e7d21037a8f1f8833c8ccd68618e8f1d37" + integrity sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg== + +multihashes-sync@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/multihashes-sync/-/multihashes-sync-2.0.0.tgz#777c6ab4b32862075a775cec15f09c1e69d426df" + integrity sha512-hoBamCqXuVmeo4NAY52dbYuUIKHy3/FcqxyKZSbhqicR2SbUjgiY4FoDvE8BV40dPfAJTT6pQpqYeuKxqKwOLQ== + dependencies: + "@noble/hashes" "^1.3.3" + multiformats "^13.0.0" + +mustache@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/mustache/-/mustache-4.2.0.tgz#e5892324d60a12ec9c2a73359edca52972bf6f64" + integrity sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ== + mute-stream@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" @@ -10904,7 +13358,17 @@ mz@^2.7.0: object-assign "^4.0.1" thenify-all "^1.0.0" -nanoid@^3.1.20, nanoid@^3.3.6, nanoid@^3.3.7: +nan@^2.13.2: + version "2.20.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.20.0.tgz#08c5ea813dd54ed16e5bd6505bf42af4f7838ca3" + integrity sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw== + +nanoevents@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/nanoevents/-/nanoevents-8.0.0.tgz#d58d5cf69b172d794707b2468bdaccc415ad23b6" + integrity sha512-bYYwNCdNc5ea6/Lwh1uioU1/7aaKa3EPmNQ2weTm8PWSpbWrsaWHePe0Zq4SF+D3F3JX3cn+QdktOPCf1meOqw== + +nanoid@^3.1.20, nanoid@^3.3.1, nanoid@^3.3.6, nanoid@^3.3.7: version "3.3.7" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== @@ -10914,6 +13378,16 @@ nanoid@^4.0.0: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-4.0.2.tgz#140b3c5003959adbebf521c170f282c5e7f9fb9e" integrity sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw== +napi-build-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" + integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== + +napi-macros@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.2.2.tgz#817fef20c3e0e40a963fbf7b37d1600bd0201044" + integrity sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g== + native-fetch@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/native-fetch/-/native-fetch-3.0.0.tgz#06ccdd70e79e171c365c75117959cf4fe14a09bb" @@ -10929,7 +13403,24 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -negotiator@0.6.3: +near-api-js@^0.44.2: + version "0.44.2" + resolved "https://registry.yarnpkg.com/near-api-js/-/near-api-js-0.44.2.tgz#e451f68f2c56bd885c7b918db5818a3e6e9423d0" + integrity sha512-eMnc4V+geggapEUa3nU2p8HSHn/njtloI4P2mceHQWO8vDE1NGpnAw8FuTBrLmXSgIv9m6oocgFc9t3VNf5zwg== + dependencies: + bn.js "5.2.0" + borsh "^0.6.0" + bs58 "^4.0.0" + depd "^2.0.0" + error-polyfill "^0.1.3" + http-errors "^1.7.2" + js-sha256 "^0.9.0" + mustache "^4.0.0" + node-fetch "^2.6.1" + text-encoding-utf-8 "^1.0.2" + tweetnacl "^1.0.1" + +negotiator@0.6.3, negotiator@^0.6.2: version "0.6.3" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== @@ -10962,12 +13453,29 @@ next@14.1.0: "@next/swc-win32-ia32-msvc" "14.1.0" "@next/swc-win32-x64-msvc" "14.1.0" +node-abi@^3.3.0: + version "3.65.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.65.0.tgz#ca92d559388e1e9cab1680a18c1a18757cdac9d3" + integrity sha512-ThjYBfoDNr08AWx6hGaRbfPwxKV9kVzAzOzlLKbk2CuqXE2xnCh+cbAGnwM3t8Lq4v9rUB7VfondlkBckcJrVA== + dependencies: + semver "^7.3.5" + +node-addon-api@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" + integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== + +node-addon-api@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-7.1.0.tgz#71f609369379c08e251c558527a107107b5e0fdb" + integrity sha512-mNcltoe1R8o7STTegSOHdnJNN7s5EUvhoS7ShnTHDyOSd+8H+UdWODq6qSv67PjC8Zc5JRT8+oLAMCr0SIXw7g== + node-domexception@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== -node-fetch@^2.6.8, node-fetch@^2.6.9: +node-fetch@^2.6.1, node-fetch@^2.6.12, node-fetch@^2.6.8, node-fetch@^2.6.9: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== @@ -10995,6 +13503,27 @@ node-gyp-build-optional-packages@5.1.1: dependencies: detect-libc "^2.0.1" +node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: + version "4.8.1" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.1.tgz#976d3ad905e71b76086f4f0b0d3637fe79b6cda5" + integrity sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw== + +node-gyp@8.x: + version "8.4.1" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.4.1.tgz#3d49308fc31f768180957d6b5746845fbd429937" + integrity sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w== + dependencies: + env-paths "^2.2.0" + glob "^7.1.4" + graceful-fs "^4.2.6" + make-fetch-happen "^9.1.0" + nopt "^5.0.0" + npmlog "^6.0.0" + rimraf "^3.0.2" + semver "^7.3.5" + tar "^6.1.2" + which "^2.0.2" + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -11036,6 +13565,13 @@ noms@0.0.0: inherits "^2.0.1" readable-stream "~1.0.31" +nopt@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" + integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== + dependencies: + abbrev "1" + nopt@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/nopt/-/nopt-7.2.0.tgz#067378c68116f602f552876194fd11f1292503d7" @@ -11087,6 +13623,16 @@ npm-run-path@^4.0.0, npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" +npmlog@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830" + integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg== + dependencies: + are-we-there-yet "^3.0.0" + console-control-strings "^1.1.0" + gauge "^4.0.3" + set-blocking "^2.0.0" + nyc@^15.1.0: version "15.1.0" resolved "https://registry.yarnpkg.com/nyc/-/nyc-15.1.0.tgz#1335dae12ddc87b6e249d5a1994ca4bdaea75f02" @@ -11120,6 +13666,13 @@ nyc@^15.1.0: test-exclude "^6.0.0" yargs "^15.0.2" +o3@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/o3/-/o3-1.0.3.tgz#192ce877a882dfa6751f0412a865fafb2da1dac0" + integrity sha512-f+4n+vC6s4ysy7YO7O2gslWZBUu8Qj2i2OUJOvjRxQva7jVjYjB29jrr9NCjmxZQR0gzrOcv1RnqoYOeMs5VRQ== + dependencies: + capability "^0.2.5" + oauth-sign@~0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" @@ -11145,6 +13698,13 @@ object-keys@^1.1.1: resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== +object-sizeof@^2.6.1: + version "2.6.4" + resolved "https://registry.yarnpkg.com/object-sizeof/-/object-sizeof-2.6.4.tgz#cdcb6697ac20978ddfa57d6d4f5fae8e7b8509dc" + integrity sha512-YuJAf7Bi61KROcYmXm8RCeBrBw8UOaJDzTm1gp0eU7RjYi1xEte3/Nmg/VyPaHcJZ3sNojs1Y0xvSrgwkLmcFw== + dependencies: + buffer "^6.0.3" + object.assign@^4.1.5: version "4.1.5" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0" @@ -11423,6 +13983,17 @@ pathval@^1.1.1: resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== +pbkdf2@^3.0.9: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + peberminta@^0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/peberminta/-/peberminta-0.9.0.tgz#8ec9bc0eb84b7d368126e71ce9033501dca2a352" @@ -11438,6 +14009,34 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== +pg-boss@^8.2.0: + version "8.4.2" + resolved "https://registry.yarnpkg.com/pg-boss/-/pg-boss-8.4.2.tgz#4c300e3683e6acd7c157481544a49b8f565fe5e5" + integrity sha512-xcl/G8C7qlCyrcvlQvgLVBIe68zO0XfZc6K86/G9fq/mL+YQMEo1spW6lHqsPpNi2KGlpXwBEL/XZxkMa19eRA== + dependencies: + cron-parser "^4.0.0" + delay "^5.0.0" + lodash.debounce "^4.0.8" + p-map "^4.0.0" + pg "^8.5.1" + serialize-error "^8.1.0" + uuid "^9.0.0" + +pg-cloudflare@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz#e6d5833015b170e23ae819e8c5d7eaedb472ca98" + integrity sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q== + +pg-connection-string@2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.6.1.tgz#78c23c21a35dd116f48e12e23c0965e8d9e2cbfb" + integrity sha512-w6ZzNu6oMmIzEAYVw+RLK0+nqHPt8K3ZnknKi+g48Ak2pr3dtljJW3o+D/n2zzCG07Zoe9VOX3aiKpj+BN0pjg== + +pg-connection-string@^2.6.4: + version "2.6.4" + resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.6.4.tgz#f543862adfa49fa4e14bc8a8892d2a84d754246d" + integrity sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA== + pg-int8@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c" @@ -11448,12 +14047,22 @@ pg-numeric@1.0.2: resolved "https://registry.yarnpkg.com/pg-numeric/-/pg-numeric-1.0.2.tgz#816d9a44026086ae8ae74839acd6a09b0636aa3a" integrity sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw== +pg-pool@^3.6.2: + version "3.6.2" + resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.6.2.tgz#3a592370b8ae3f02a7c8130d245bc02fa2c5f3f2" + integrity sha512-Htjbg8BlwXqSBQ9V8Vjtc+vzf/6fVUuak/3/XXKA9oxZprwW3IMDQTGHP+KDmVL7rtd+R1QjbnCFPuTHm3G4hg== + pg-protocol@*: version "1.6.0" resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.6.0.tgz#4c91613c0315349363af2084608db843502f8833" integrity sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q== -pg-types@^2.2.0: +pg-protocol@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.6.1.tgz#21333e6d83b01faaebfe7a33a7ad6bfd9ed38cb3" + integrity sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg== + +pg-types@^2.1.0, pg-types@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3" integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA== @@ -11477,6 +14086,26 @@ pg-types@^4.0.1: postgres-interval "^3.0.0" postgres-range "^1.1.1" +pg@^8.11.3, pg@^8.5.1: + version "8.12.0" + resolved "https://registry.yarnpkg.com/pg/-/pg-8.12.0.tgz#9341724db571022490b657908f65aee8db91df79" + integrity sha512-A+LHUSnwnxrnL/tZ+OLfqR1SxLN3c/pgDztZ47Rpbsd4jUytsTtwQo/TLPRzPJMp/1pbhYVhH9cuSZLAajNfjQ== + dependencies: + pg-connection-string "^2.6.4" + pg-pool "^3.6.2" + pg-protocol "^1.6.1" + pg-types "^2.1.0" + pgpass "1.x" + optionalDependencies: + pg-cloudflare "^1.1.1" + +pgpass@1.x: + version "1.0.5" + resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.5.tgz#9b873e4a564bb10fa7a7dbd55312728d422a223d" + integrity sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug== + dependencies: + split2 "^4.1.0" + picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" @@ -11701,6 +14330,24 @@ postgres-range@^1.1.1: resolved "https://registry.yarnpkg.com/postgres-range/-/postgres-range-1.1.4.tgz#a59c5f9520909bcec5e63e8cf913a92e4c952863" integrity sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w== +prebuild-install@^7.1.1: + version "7.1.2" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.2.tgz#a5fd9986f5a6251fbc47e1e5c65de71e68c0a056" + integrity sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ== + dependencies: + detect-libc "^2.0.0" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp-classic "^0.5.3" + napi-build-utils "^1.0.1" + node-abi "^3.3.0" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^4.0.0" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -11788,6 +14435,19 @@ progress@^2.0.0: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== + +promise-retry@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" + integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== + dependencies: + err-code "^2.0.2" + retry "^0.12.0" + proto-list@~1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" @@ -11903,12 +14563,22 @@ qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== +query-string@^7.1.0: + version "7.1.3" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-7.1.3.tgz#a1cf90e994abb113a325804a972d98276fe02328" + integrity sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg== + dependencies: + decode-uri-component "^0.2.2" + filter-obj "^1.1.0" + split-on-first "^1.0.0" + strict-uri-encode "^2.0.0" + querystring@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" integrity sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g== -queue-microtask@^1.2.2: +queue-microtask@^1.2.2, queue-microtask@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== @@ -11928,7 +14598,14 @@ race-signal@^1.0.2: resolved "https://registry.yarnpkg.com/race-signal/-/race-signal-1.0.2.tgz#e42379fba0cec4ee8dab7c9bbbd4aa6e0d14c25f" integrity sha512-o3xNv0iTcIDQCXFlF6fPAMEBRjFxssgGoRqLbg06m+AdzEXXLUmoNOoUHTVz2NoBI8hHwKFKoC6IqyNtWr2bww== -randombytes@^2.1.0: +randombytes@2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.5.tgz#dc009a246b8d09a177b4b7a0ae77bc570f4b1b79" + integrity sha512-8T7Zn1AhMsQ/HI1SjcCfT/t4ii3eAqco3yOcSzS4mozsOz69lHLsoMXmF9nZgnFanYscnSlUSgs8uZyKzpE6kg== + dependencies: + safe-buffer "^5.1.0" + +randombytes@^2.0.1, randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== @@ -11950,6 +14627,16 @@ raw-body@2.5.2: iconv-lite "0.4.24" unpipe "1.0.0" +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + rdf-canonize@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/rdf-canonize/-/rdf-canonize-3.4.0.tgz#87f88342b173cc371d812a07de350f0c1aa9f058" @@ -12157,6 +14844,13 @@ rechoir@^0.6.2: dependencies: resolve "^1.1.6" +rechoir@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.8.0.tgz#49f866e0d32146142da3ad8f0eff352b3215ff22" + integrity sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ== + dependencies: + resolve "^1.20.0" + redent@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" @@ -12182,6 +14876,11 @@ reflect-metadata@^0.1.13: resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.14.tgz#24cf721fe60677146bb77eeb0e1f9dece3d65859" integrity sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A== +regenerator-runtime@^0.13.2: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== + regenerator-runtime@^0.14.0: version "0.14.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" @@ -12298,7 +14997,7 @@ resolve-global@1.0.0, resolve-global@^1.0.0: dependencies: global-dirs "^0.1.1" -resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.22.1, resolve@^1.22.2, resolve@^1.22.4: +resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.20.0, resolve@^1.22.1, resolve@^1.22.2, resolve@^1.22.4: version "1.22.8" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== @@ -12320,6 +15019,11 @@ retimer@^3.0.0: resolved "https://registry.yarnpkg.com/retimer/-/retimer-3.0.0.tgz#98b751b1feaf1af13eb0228f8ea68b8f9da530df" integrity sha512-WKE0j11Pa0ZJI5YIk0nflGI7SQsfl2ljihVy7ogh7DeQSeYAUi0ubZ/yEueGtDfUPk6GH5LRw1hBdLq4IwUBWA== +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== + reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" @@ -12344,11 +15048,38 @@ rimraf@^5.0.1: dependencies: glob "^10.3.7" +ripemd160-min@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/ripemd160-min/-/ripemd160-min-0.0.6.tgz#a904b77658114474d02503e819dcc55853b67e62" + integrity sha512-+GcJgQivhs6S9qvLogusiTcS9kQUfgR75whKuy5jIhuiOfQuJ8fjqxV6EGD5duH1Y/FawFUMtMhyeq3Fbnib8A== + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +rpc-utils@^0.6.1, rpc-utils@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rpc-utils/-/rpc-utils-0.6.2.tgz#3cab779f93048eda69ff198c58b1a2c2e35e3fa6" + integrity sha512-kzk1OflbBckfDBAo8JwsmtQSHzj+6hxRt5G+u8A8ZSmunBw1nhWvRkSq8j1+EvWBqBRLy1aiGLUW5644CZqQtA== + dependencies: + nanoid "^3.3.1" + run-async@^2.4.0: version "2.4.1" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== +run-parallel-limit@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz#be80e936f5768623a38a963262d6bef8ff11e7ba" + integrity sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw== + dependencies: + queue-microtask "^1.2.2" + run-parallel@^1.1.6, run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -12373,7 +15104,7 @@ safe-array-concat@^1.1.0: has-symbols "^1.0.3" isarray "^2.0.5" -safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0: +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -12438,6 +15169,29 @@ scrypt-js@3.0.1: resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== +scryptsy@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/scryptsy/-/scryptsy-2.1.0.tgz#8d1e8d0c025b58fdd25b6fa9a0dc905ee8faa790" + integrity sha512-1CdSqHQowJBnMAFyPEBRfqag/YP9OF394FV+4YREIJX4ljD7OxvQRDayyoyyCk+senRjSkP6VnUNQmVQqB6g7w== + +secp256k1@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.1.tgz#b9570ca26ace9e74c3171512bba253da9c0b6d60" + integrity sha512-iGRjbGAKfXMqhtdkkuNxsgJQfJO8Oo78Rm7DAvsG3XKngq+nJIOGqrCSXcQqIVsmCj0wFanE5uTKFxV3T9j2wg== + dependencies: + elliptic "^6.5.2" + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + +secp256k1@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.3.tgz#c4559ecd1b8d3c1827ed2d1b94190d69ce267303" + integrity sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA== + dependencies: + elliptic "^6.5.4" + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + secure-json-parse@^2.4.0: version "2.7.0" resolved "https://registry.yarnpkg.com/secure-json-parse/-/secure-json-parse-2.7.0.tgz#5a5f9cd6ae47df23dba3151edd06855d47e09862" @@ -12503,6 +15257,13 @@ send@0.18.0: range-parser "~1.2.1" statuses "2.0.1" +serialize-error@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-8.1.0.tgz#3a069970c712f78634942ddd50fbbc0eaebe2f67" + integrity sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ== + dependencies: + type-fest "^0.20.2" + serialize-javascript@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" @@ -12564,6 +15325,14 @@ setprototypeof@1.2.0: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -12615,7 +15384,7 @@ side-channel@^1.0.4, side-channel@^1.0.6: get-intrinsic "^1.2.4" object-inspect "^1.13.1" -signal-exit@^3.0.2, signal-exit@^3.0.3: +signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== @@ -12625,6 +15394,20 @@ signal-exit@^4.0.1: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== +simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + +simple-get@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543" + integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== + dependencies: + decompress-response "^6.0.0" + once "^1.3.1" + simple-concat "^1.0.0" + simple-update-notifier@^1.0.7: version "1.1.0" resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz#67694c121de354af592b347cdba798463ed49c82" @@ -12664,6 +15447,11 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" +smart-buffer@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== + socket.io-adapter@~2.5.2: version "2.5.4" resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.5.4.tgz#4fdb1358667f6d68f25343353bd99bd11ee41006" @@ -12703,6 +15491,23 @@ socket.io@4.7.3: socket.io-adapter "~2.5.2" socket.io-parser "~4.2.4" +socks-proxy-agent@^6.0.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz#2687a31f9d7185e38d530bef1944fe1f1496d6ce" + integrity sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ== + dependencies: + agent-base "^6.0.2" + debug "^4.3.3" + socks "^2.6.2" + +socks@^2.6.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.3.tgz#1ebd0f09c52ba95a09750afe3f3f9f724a800cb5" + integrity sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw== + dependencies: + ip-address "^9.0.5" + smart-buffer "^4.2.0" + sonic-boom@^3.0.0, sonic-boom@^3.7.0: version "3.8.0" resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-3.8.0.tgz#e442c5c23165df897d77c3c14ef3ca40dec66a66" @@ -12781,6 +15586,11 @@ spdx-license-ids@^3.0.0: resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz#887da8aa73218e51a1d917502d79863161a93f9c" integrity sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg== +split-on-first@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" + integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== + split2@^3.0.0: version "3.2.2" resolved "https://registry.yarnpkg.com/split2/-/split2-3.2.2.tgz#bf2cf2a37d838312c249c89206fd7a17dd12365f" @@ -12788,16 +15598,40 @@ split2@^3.0.0: dependencies: readable-stream "^3.0.0" -split2@^4.0.0: +split2@^4.0.0, split2@^4.1.0: version "4.2.0" resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== +split@0.2.x: + version "0.2.10" + resolved "https://registry.yarnpkg.com/split/-/split-0.2.10.tgz#67097c601d697ce1368f418f06cd201cf0521a57" + integrity sha512-e0pKq+UUH2Xq/sXbYpZBZc3BawsfDZ7dgv+JtRTUPNcvF5CMR4Y9cvJqkMY0MoxWzTHvZuz1beg6pNEKlszPiQ== + dependencies: + through "2" + +sprintf-js@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.3.tgz#4914b903a2f8b685d17fdf78a70e917e872e444a" + integrity sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA== + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== +sqlite3@^5.0.8: + version "5.1.7" + resolved "https://registry.yarnpkg.com/sqlite3/-/sqlite3-5.1.7.tgz#59ca1053c1ab38647396586edad019b1551041b7" + integrity sha512-GGIyOiFaG+TUra3JIfkI/zGP8yZYLPQ0pl1bH+ODjiX57sPhrLU5sQJn1y9bDKZUFYkX1crlrPfSYt0BKKdkog== + dependencies: + bindings "^1.5.0" + node-addon-api "^7.0.0" + prebuild-install "^7.1.1" + tar "^6.1.11" + optionalDependencies: + node-gyp "8.x" + sshpk@^1.7.0: version "1.18.0" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.18.0.tgz#1663e55cddf4d688b86a46b77f0d5fe363aba028" @@ -12813,6 +15647,13 @@ sshpk@^1.7.0: safer-buffer "^2.0.2" tweetnacl "~0.14.0" +ssri@^8.0.0, ssri@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" + integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== + dependencies: + minipass "^3.1.1" + stacktrace-parser@0.1.10: version "0.1.10" resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" @@ -12825,6 +15666,11 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== +"statuses@>= 1.5.0 < 2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + stream-browserify@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-3.0.0.tgz#22b0a2850cdf6503e73085da1fc7b7d0c2122f2f" @@ -12845,6 +15691,11 @@ streamsearch@^1.1.0: resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== +strict-uri-encode@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" + integrity sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ== + string-argv@0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" @@ -12855,7 +15706,7 @@ string-template@~0.2.1: resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" integrity sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw== -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -12976,6 +15827,11 @@ strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1. resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== + strnum@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.5.tgz#5c4e829fe15ad4ff0d20c3db5ac97b73c9b072db" @@ -13115,7 +15971,17 @@ tapable@^2.1.1, tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== -tar-stream@^2.2.0: +tar-fs@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" + integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + +tar-stream@^2.1.4, tar-stream@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== @@ -13126,6 +15992,18 @@ tar-stream@^2.2.0: inherits "^2.0.3" readable-stream "^3.1.1" +tar@^6.0.2, tar@^6.1.11, tar@^6.1.2: + version "6.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" + integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^5.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + tar@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.0.tgz#b14ce49a79cb1cd23bc9b016302dea5474493f73" @@ -13138,6 +16016,11 @@ tar@^6.2.0: mkdirp "^1.0.3" yallist "^4.0.0" +tarn@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/tarn/-/tarn-3.0.2.tgz#73b6140fbb881b71559c4f8bfde3d9a4b3d27693" + integrity sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ== + terser-webpack-plugin@^5.3.10: version "5.3.10" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz#904f4c9193c6fd2a03f693a2150c62a92f40d199" @@ -13168,6 +16051,11 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" +text-encoding-utf-8@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz#585b62197b0ae437e3c7b5d0af27ac1021e10d13" + integrity sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg== + text-extensions@^1.0.0: version "1.9.0" resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" @@ -13223,11 +16111,16 @@ through2@^4.0.0: dependencies: readable-stream "3" -"through@>=2.2.7 <3", through@^2.3.6, through@^2.3.8: +through@2, through@2.3.x, "through@>=2.2.7 <3", through@^2.3.6, through@^2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== +tildify@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/tildify/-/tildify-2.0.0.tgz#f205f3674d677ce698b7067a99e949ce03b4754a" + integrity sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw== + timeout-abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/timeout-abort-controller/-/timeout-abort-controller-3.0.0.tgz#dd57ffca041652c03769904f8d95afd93fb95595" @@ -13235,6 +16128,17 @@ timeout-abort-controller@^3.0.0: dependencies: retimer "^3.0.0" +tiny-secp256k1@^1.1.3: + version "1.1.6" + resolved "https://registry.yarnpkg.com/tiny-secp256k1/-/tiny-secp256k1-1.1.6.tgz#7e224d2bee8ab8283f284e40e6b4acb74ffe047c" + integrity sha512-FmqJZGduTyvsr2cF3375fqGHUovSwDi/QytexX1Se4BPuPZpTE5Ftp5fg+EFSuEf3lhZqgCRjEG3ydUQ/aNiwA== + dependencies: + bindings "^1.3.0" + bn.js "^4.11.8" + create-hmac "^1.1.7" + elliptic "^6.4.0" + nan "^2.13.2" + tiny-typed-emitter@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz#b3b027fdd389ff81a152c8e847ee2f5be9fad7b5" @@ -13247,6 +16151,11 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" +to-data-view@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/to-data-view/-/to-data-view-1.1.0.tgz#08d6492b0b8deb9b29bdf1f61c23eadfa8994d00" + integrity sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ== + to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" @@ -13374,6 +16283,11 @@ tunnel-agent@^0.6.0: dependencies: safe-buffer "^5.0.1" +tweetnacl@1.x.x, tweetnacl@^1.0.1, tweetnacl@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" + integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== + tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" @@ -13485,11 +16399,21 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" +typedarray-to-buffer@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-4.0.0.tgz#cdd2933c61dd3f5f02eda5d012d441f95bfeb50a" + integrity sha512-6dOYeZfS3O9RtRD1caom0sMxgK59b27+IwoNy8RDPsmslSGOyU+mpTamlaIW7aNKi90ZQZ9DFaZL3YRoiSCULQ== + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== +typeforce@^1.11.5: + version "1.18.0" + resolved "https://registry.yarnpkg.com/typeforce/-/typeforce-1.18.0.tgz#d7416a2c5845e085034d70fcc5b6cc4a90edbfdc" + integrity sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g== + typescript@5.1.6: version "5.1.6" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" @@ -13505,6 +16429,11 @@ typescript@^5.0.0: resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.2.tgz#0ae9cebcfae970718474fe0da2c090cad6577372" integrity sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ== +u3@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/u3/-/u3-0.1.1.tgz#5f52044f42ee76cd8de33148829e14528494b73b" + integrity sha512-+J5D5ir763y+Am/QY6hXNRlwljIeRMZMGs0cT6qqZVVzzT3X3nFPXVyPOFRMOR4kupB0T8JnCdpWdp6Q/iXn3w== + uint8-varint@^2.0.1, uint8-varint@^2.0.2: version "2.0.4" resolved "https://registry.yarnpkg.com/uint8-varint/-/uint8-varint-2.0.4.tgz#85be52b3849eb30f2c3640a2df8a14364180affb" @@ -13520,7 +16449,14 @@ uint8arraylist@^2.0.0, uint8arraylist@^2.1.2, uint8arraylist@^2.4.3, uint8arrayl dependencies: uint8arrays "^5.0.1" -uint8arrays@^4.0.2, uint8arrays@^4.0.3: +uint8arrays@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-3.1.1.tgz#2d8762acce159ccd9936057572dade9459f65ae0" + integrity sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg== + dependencies: + multiformats "^9.4.2" + +uint8arrays@^4.0.2, uint8arrays@^4.0.3, uint8arrays@^4.0.6: version "4.0.10" resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-4.0.10.tgz#3ec5cde3348903c140e87532fc53f46b8f2e921f" integrity sha512-AnJNUGGDJAgFw/eWu/Xb9zrVKEGlwJJCaeInlf3BkecE/zcTobk5YXYIPNQJO1q5Hh1QZrQQHf0JvcHqz2hqoA== @@ -13561,6 +16497,20 @@ undici@^5.12.0, undici@^5.21.2: dependencies: "@fastify/busboy" "^2.0.0" +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== + dependencies: + imurmurhash "^0.1.4" + universalify@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" @@ -13584,7 +16534,7 @@ update-browserslist-db@^1.0.13: escalade "^3.1.1" picocolors "^1.0.0" -uri-js@^4.2.2: +uri-js@^4.2.2, uri-js@^4.4.1: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== @@ -13683,11 +16633,28 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" +value-or-promise@^1.0.11, value-or-promise@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/value-or-promise/-/value-or-promise-1.0.12.tgz#0e5abfeec70148c78460a849f6b003ea7986f15c" + integrity sha512-Z6Uz+TYwEqE7ZN50gwn+1LCVo9ZVrpxRPOhOLnncYkY1ZzOYtrX8Fwf/rFktZ8R5mJms6EZf5TqNOMeZmnPq9Q== + varint@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/varint/-/varint-6.0.0.tgz#9881eb0ce8feaea6512439d19ddf84bf551661d0" integrity sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg== +varintes@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/varintes/-/varintes-2.0.5.tgz#e5e2e53b10300ca4d5c0bacae2a826f7b3b2cab5" + integrity sha512-iF3jlHLko9NrYjaUZvT3VwypP3V20KNNhT1tzqblyIyrVjNiW7HseGOhuP+apgZBp9X/8+5pxa7kNikhJeZlIw== + +varuint-bitcoin@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/varuint-bitcoin/-/varuint-bitcoin-1.1.2.tgz#e76c138249d06138b480d4c5b40ef53693e24e92" + integrity sha512-4EVb+w4rx+YfVM32HQX42AbbT7/1f5zwAYhIujKXKk8NQK+JfRVl3pqT3hjNn/L+RstigmGGKVwHA/P0wgITZw== + dependencies: + safe-buffer "^5.1.1" + vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" @@ -13702,6 +16669,20 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" +viem@^1.21.4: + version "1.21.4" + resolved "https://registry.yarnpkg.com/viem/-/viem-1.21.4.tgz#883760e9222540a5a7e0339809202b45fe6a842d" + integrity sha512-BNVYdSaUjeS2zKQgPs+49e5JKocfo60Ib2yiXOWBT6LuVxY1I/6fFX3waEtpXvL1Xn4qu+BVitVtMh9lyThyhQ== + 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" + isows "1.0.3" + ws "8.13.0" + watchpack@^2.4.0: version "2.4.1" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.1.tgz#29308f2cac150fa8e4c92f90e0ec954a9fed7fff" @@ -13804,13 +16785,27 @@ which@^1.2.14: dependencies: isexe "^2.0.0" -which@^2.0.1: +which@^2.0.1, which@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" +wide-align@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" + integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== + dependencies: + string-width "^1.0.2 || 2 || 3 || 4" + +wif@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/wif/-/wif-2.0.6.tgz#08d3f52056c66679299726fade0d432ae74b4704" + integrity sha512-HIanZn1zmduSF+BQhkE+YXIbEiH0xPr1012QbFEGB0xsKqJii0/SqJjyn8dFv6y36kOznMgMB+LGcbZTJ1xACQ== + dependencies: + bs58check "<3.0.0" + word-wrap@^1.0.3: version "1.2.5" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" @@ -13868,6 +16863,11 @@ ws@7.4.6: resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== +ws@8.13.0: + version "8.13.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" + integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== + ws@^8.15.0, ws@^8.7.0: version "8.16.0" resolved "https://registry.yarnpkg.com/ws/-/ws-8.16.0.tgz#d1cd774f36fbc07165066a60e40323eab6446fd4" @@ -13911,6 +16911,13 @@ xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== +xxhashjs@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/xxhashjs/-/xxhashjs-0.2.2.tgz#8a6251567621a1c46a5ae204da0249c7f8caa9d8" + integrity sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw== + dependencies: + cuint "^0.2.2" + y18n@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" From dafc12f383ba948ed3222e725092b1deb48a7a36 Mon Sep 17 00:00:00 2001 From: m0ar Date: Tue, 18 Jun 2024 12:15:42 +0200 Subject: [PATCH 149/278] server: separate optimism RPC config to allow dynamic publish target selection --- .env.example | 3 -- .../src/controllers/nodes/createDpid.ts | 46 +++++++++++-------- nodes-lib/test/root.spec.ts | 2 +- 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/.env.example b/.env.example index 3bddd15a..89866b5d 100755 --- a/.env.example +++ b/.env.example @@ -115,9 +115,6 @@ GOOGLE_DEV_API_KEY= # Unnecessary for now, not doing serverside 2step ## Configure RPC nodes (open an issue/ping us to access DeSci Labs' nodes) ETHEREUM_RPC_URL=http://host.docker.internal:8545 -# Use this for Goerli testnet -# ETHEREUM_RPC_URL=https://eth-goerli.g.alchemy.com/v2/demo - # Use this for Sepolia testnet # ETHEREUM_RPC_URL=https://eth-sepolia.g.alchemy.com/v2/demo diff --git a/desci-server/src/controllers/nodes/createDpid.ts b/desci-server/src/controllers/nodes/createDpid.ts index 8dd498d7..cc6e4e1e 100644 --- a/desci-server/src/controllers/nodes/createDpid.ts +++ b/desci-server/src/controllers/nodes/createDpid.ts @@ -17,20 +17,43 @@ export type DpidErrorResponse = { error: string; }; -const CERAMIC_API = process.env.CERAMIC_API; +const CERAMIC_API_URLS = { + local: "http://localhost:7007", + dev: "https://ceramic-dev.desci.com", + prod: "https://ceramic-prod.desci.com", +} as const; + +const OPTIMISM_RPC_URLS = { + local: "http://localhost:8545", + dev: "https://reverse-proxy-dev.desci.com/rpc_opt_sepolia", + prod: "https://reverse-proxy-prod.desci.com/rpc_opt_mainnet", +} as const; /** Not secret: pre-seeded ganache account for local dev */ const GANACHE_PKEY = "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; -let aliasRegistryAddress: string; const apiServerUrl = process.env.SERVER_URL; +/** Manually set in this module since the envvar needs to support OG ethereum during migration */ +let optimismRpcUrl: string; +let aliasRegistryAddress: string; +let ceramicApiUrl: string; + if (apiServerUrl.includes("localhost")) { aliasRegistryAddress = contracts.localDpidAliasInfo.proxies.at(0).address; + ceramicApiUrl = CERAMIC_API_URLS.local; + optimismRpcUrl = OPTIMISM_RPC_URLS.local; } else if (apiServerUrl.includes("dev") || apiServerUrl.includes("staging")) { aliasRegistryAddress = contracts.devDpidAliasInfo.proxies.at(0).address; + ceramicApiUrl = CERAMIC_API_URLS.dev; + optimismRpcUrl = OPTIMISM_RPC_URLS.dev; } else if (process.env.NODE_ENV === "production") { aliasRegistryAddress = contracts.prodDpidAliasInfo.proxies.at(0).address; + ceramicApiUrl = CERAMIC_API_URLS.prod; + optimismRpcUrl = OPTIMISM_RPC_URLS.prod; +} else { + console.error("Cannot derive contract address due to ambiguous environment"); + throw new Error("Ambiguous environment"); }; export const createDpid = async (req: RequestWithNode, res: Response) => { @@ -55,11 +78,6 @@ export const createDpid = async (req: RequestWithNode, res: Response { - if (!CERAMIC_API) { - throw new Error("CERAMIC_API not configured"); - }; - - const client = newCeramicClient(CERAMIC_API); + const client = newCeramicClient(ceramicApiUrl); const [_owner, legacyVersions] = await registry.legacyLookup(dpid); const streamEvents = await resolveHistory(client, ceramicStream) diff --git a/nodes-lib/test/root.spec.ts b/nodes-lib/test/root.spec.ts index 8d43cdc1..e68baf8e 100644 --- a/nodes-lib/test/root.spec.ts +++ b/nodes-lib/test/root.spec.ts @@ -363,7 +363,7 @@ describe("nodes-lib", () => { const pubResult = await publishDraftNode(uuid, testSigner, did); // Allow graph node to index - await sleep(2_500); + await sleep(5_000); // make sure codex history is of equal length const dpidHistory = await getDpidHistory(uuid); From 7798198fad3e0d0c023ec045cc4abb07af043e27 Mon Sep 17 00:00:00 2001 From: m0ar Date: Tue, 18 Jun 2024 14:47:40 +0200 Subject: [PATCH 150/278] server: fix tests & dpid upgrade with history validation --- .../src/controllers/nodes/createDpid.ts | 38 ++++++++++++------- nodes-lib/src/codex.ts | 15 +++++++- nodes-lib/test/root.spec.ts | 37 +++++++++++++++--- 3 files changed, 71 insertions(+), 19 deletions(-) diff --git a/desci-server/src/controllers/nodes/createDpid.ts b/desci-server/src/controllers/nodes/createDpid.ts index cc6e4e1e..6eb388f9 100644 --- a/desci-server/src/controllers/nodes/createDpid.ts +++ b/desci-server/src/controllers/nodes/createDpid.ts @@ -18,13 +18,13 @@ export type DpidErrorResponse = { }; const CERAMIC_API_URLS = { - local: "http://localhost:7007", + local: "http://host.docker.internal:7007", dev: "https://ceramic-dev.desci.com", prod: "https://ceramic-prod.desci.com", } as const; const OPTIMISM_RPC_URLS = { - local: "http://localhost:8545", + local: "http://host.docker.internal:8545", dev: "https://reverse-proxy-dev.desci.com/rpc_opt_sepolia", prod: "https://reverse-proxy-prod.desci.com/rpc_opt_mainnet", } as const; @@ -56,6 +56,8 @@ if (apiServerUrl.includes("localhost")) { throw new Error("Ambiguous environment"); }; +console.log("Using new publish configuration:", { aliasRegistryAddress, optimismRpcUrl, ceramicApiUrl }); + export const createDpid = async (req: RequestWithNode, res: Response) => { const owner = req.user; const node = req.node; @@ -148,6 +150,7 @@ export const upgradeDpid = async ( const logger = parentLogger.child({ module: "NODE::upgradeDpid", ceramicStream, + dpid, }); const provider = new ethers.providers.JsonRpcProvider(optimismRpcUrl); @@ -167,7 +170,10 @@ export const upgradeDpid = async ( wallet, ); - if (!compareHistory(dpid, ceramicStream, dpidAliasRegistry, logger)) { + const historyValid = await validateHistory( + dpid, ceramicStream, dpidAliasRegistry, logger + ); + if (!historyValid) { logger.warn( { dpid, ceramicStream }, "version histories disagree; refusing to upgrade dPID", @@ -191,41 +197,47 @@ export const upgradeDpid = async ( * This should be checked before upgrading a dPID, to make sure * the new stream accurately represents the publish history. */ -const compareHistory = async ( +const validateHistory = async ( dpid: number, ceramicStream: string, registry: DpidAliasRegistry, logger: Logger ) => { const client = newCeramicClient(ceramicApiUrl); - const [_owner, legacyVersions] = await registry.legacyLookup(dpid); + const legacyEntry = await registry.legacyLookup(dpid); const streamEvents = await resolveHistory(client, ceramicStream) const streamStates = await Promise.all(streamEvents .map(s => s.commit) - .map(c => client.loadStream(c)) + .map(c => client.loadStream(c).then(state => state.content)) ); + const [_owner, legacyVersions ] = legacyEntry; + // Stream could have one or more additional entries - if (legacyVersions.length < streamStates.length) { + if (legacyVersions.length > streamStates.length) { logger.error( - "Stream history shorter than legacy history", - { legacyVersions, streamStates} + { legacyVersions, streamStates }, + "Stream has shorter history than legacy dPID", ); return false; }; - for (const [i, streamState] of streamStates.entries()) { + for (const [i, legacyVersion] of legacyVersions.entries()) { // Cant compare timestamp because anchor time WILL differ - const expectedCid = legacyVersions[i][0]; - if (expectedCid !== streamState.content.manifest) { + const expectedCid = legacyVersion[0]; + if (expectedCid !== streamStates[i].manifest) { logger.error( + { legacyVersions, streamStates}, "Manifest CID mismatch between legacy and stream history", - { legacyVersions, streamStates} ); return false; }; }; + logger.info( + { dpid, ceramicStream }, + "Legacy and stream history check passed", + ); return true; } diff --git a/nodes-lib/src/codex.ts b/nodes-lib/src/codex.ts index 8e748641..848f589b 100644 --- a/nodes-lib/src/codex.ts +++ b/nodes-lib/src/codex.ts @@ -15,6 +15,7 @@ import { getNodesLibInternalConfig } from "./config/index.js"; import { Signer } from "ethers"; import { authorizedSessionDidFromSigner } from "./util/signing.js"; import { type DID } from"dids"; +import { CID } from "multiformats"; const LOG_CTX = "[nodes-lib::codex]"; /** @@ -126,7 +127,19 @@ const backfillNewStream = async ( const title = "[BACKFILLED]"; // version.title is the title of the event, e.g. "Published" const license = "[BACKFILLED]"; - const manifest = convert0xHexToCid(nextVersion.cid); + + // When pulling history from new contract legacy entries, the CID + // is cleartext. Otherwise, it needs to be decoded from hex. + let manifest: string; + try { + // If this works, it was a plaintext CID + manifest = CID.parse(nextVersion.cid).toString(); + } catch (e) { + // Otherwise, fall back to hex decoding old style representation + console.log(LOG_CTX, `got non-plaintext CID for backfill: ${nextVersion.cid}`); + manifest = convert0xHexToCid(nextVersion.cid); + }; + const op = streamID === "" ? createResearchObject(compose, { title, manifest, license }) diff --git a/nodes-lib/test/root.spec.ts b/nodes-lib/test/root.spec.ts index e68baf8e..38ac4e3c 100644 --- a/nodes-lib/test/root.spec.ts +++ b/nodes-lib/test/root.spec.ts @@ -14,11 +14,10 @@ import { updateDescription, updateLicense, updateResearchFields, addContributor, removeContributor, addExternalCid, updateCoverImage, publishNode, - getPublishHistory, } from "../src/api.js"; import axios from "axios"; import { getCodexHistory, getCurrentState, getRawState } from "../src/codex.js"; -import { dpidPublish, findDpid, lookupLegacyDpid } from "../src/chain.js"; +import { dpidPublish, findDpid } from "../src/chain.js"; import { sleep } from "./util.js"; import { convert0xHexToCid } from "../src/util/converting.js"; import { @@ -35,6 +34,8 @@ import { import { authorizedSessionDidFromSigner, signerFromPkey } from "../src/util/signing.js"; import { NODESLIB_CONFIGS, getNodesLibInternalConfig, setApiKey, setNodesLibConfig } from "../src/index.js"; import { getResources } from "@desci-labs/desci-codex-lib"; +import { contracts, typechain as tc } from "@desci-labs/desci-contracts"; +import { Wallet, providers } from "ethers"; // Pre-funded ganache account const TEST_PKEY = "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; @@ -482,13 +483,39 @@ describe("nodes-lib", () => { uuid = node.uuid; // make a dpid-only publish - const { prepubResult: { updatedManifest }} = await dpidPublish(uuid, false, testSigner); - - legacyDpid = parseInt(updatedManifest.dpid!.id); + const { prepubResult: { updatedManifest, updatedManifestCid }} = await dpidPublish( + uuid, false, testSigner + ); // Allow graph node to index await sleep(2_500); + legacyDpid = parseInt(updatedManifest.dpid!.id); + + // Import as legacy entry (i.e., fake migration step) + // Publish uses this to validate history before migrating dPID + const wallet = new Wallet( + TEST_PKEY, + new providers.JsonRpcProvider(getNodesLibInternalConfig().chainConfig.rpcUrl), + ); + const aliasRegistry = tc.DpidAliasRegistry__factory.connect( + contracts.localDpidAliasInfo.proxies.at(0)!.address, + wallet, + ); + const tx = await aliasRegistry.importLegacyDpid( + legacyDpid, + { + owner: await testSigner.getAddress(), + versions: [ + { + cid: updatedManifestCid, + time: 1337 // Import fn can't validate this anyway + }, + ], + }, + ); + await tx.wait(); + // make a regular publish pubResult = await publishNode(uuid, did); await sleep(1000); From 0b7b18a931b65ff52ff8d5182a7d22f3aa6b5900 Mon Sep 17 00:00:00 2001 From: m0ar Date: Tue, 18 Jun 2024 14:58:05 +0200 Subject: [PATCH 151/278] server: add --ignore-engines to yarn cmds in workflows --- .github/workflows/build-and-test.yaml | 4 ++-- .github/workflows/build-server.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-and-test.yaml b/.github/workflows/build-and-test.yaml index ec9d7259..aae21bbc 100644 --- a/.github/workflows/build-and-test.yaml +++ b/.github/workflows/build-and-test.yaml @@ -54,7 +54,7 @@ jobs: docker info - name: Install dependencies - run: cd desci-models && npm i -g yarn && yarn && yarn build && cd ../desci-server && yarn && cd ../desci-repo && yarn + run: cd desci-models && npm i -g yarn && yarn && yarn build && cd ../desci-server && yarn && cd ../desci-repo && yarn --ignore-engines - name: Stub contract run: | @@ -63,7 +63,7 @@ jobs: - name: Run tests run: | - cd desci-server && export DOCKER_BUILDKIT=1 && yarn && yarn test + cd desci-server && export DOCKER_BUILDKIT=1 && yarn --ignore-engines && yarn test if [ $? -ne 0 ]; then exit 1 fi diff --git a/.github/workflows/build-server.yaml b/.github/workflows/build-server.yaml index 037c538a..b20942c0 100644 --- a/.github/workflows/build-server.yaml +++ b/.github/workflows/build-server.yaml @@ -56,7 +56,7 @@ jobs: docker info - name: Install dependencies - run: cd desci-models && npm i -g yarn && yarn && yarn build && cd ../desci-server && yarn + run: cd desci-models && npm i -g yarn && yarn && yarn build && cd ../desci-server && yarn --ignore-engines - name: Stub contract run: | @@ -65,7 +65,7 @@ jobs: - name: Run tests run: | - cd desci-server && export DOCKER_BUILDKIT=1 && yarn && yarn test + cd desci-server && export DOCKER_BUILDKIT=1 && yarn --ignore-engines && yarn test echo "exit code $?" if [ $? -ne 0 ]; then exit 1 From 19e1e3cd4a841648dd7c7ca4de3588032dde2337 Mon Sep 17 00:00:00 2001 From: m0ar Date: Tue, 18 Jun 2024 15:01:47 +0200 Subject: [PATCH 152/278] server: fix the fix xzibit --- .github/workflows/build-and-test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-and-test.yaml b/.github/workflows/build-and-test.yaml index aae21bbc..956ee306 100644 --- a/.github/workflows/build-and-test.yaml +++ b/.github/workflows/build-and-test.yaml @@ -54,7 +54,7 @@ jobs: docker info - name: Install dependencies - run: cd desci-models && npm i -g yarn && yarn && yarn build && cd ../desci-server && yarn && cd ../desci-repo && yarn --ignore-engines + run: cd desci-models && npm i -g yarn && yarn && yarn build && cd ../desci-server && yarn --ignore-engines && cd ../desci-repo && yarn - name: Stub contract run: | From 4f1829b2f9bae60236febb9a1b0e5f936caeb4d5 Mon Sep 17 00:00:00 2001 From: m0ar Date: Tue, 18 Jun 2024 15:23:10 +0200 Subject: [PATCH 153/278] server: add contract owner pkey to vault config --- desci-server/kubernetes/deployment_dev.yaml | 1 + desci-server/kubernetes/deployment_prod.yaml | 1 + desci-server/kubernetes/deployment_staging.yaml | 1 + 3 files changed, 3 insertions(+) diff --git a/desci-server/kubernetes/deployment_dev.yaml b/desci-server/kubernetes/deployment_dev.yaml index a9dec132..b1fae99d 100644 --- a/desci-server/kubernetes/deployment_dev.yaml +++ b/desci-server/kubernetes/deployment_dev.yaml @@ -63,6 +63,7 @@ spec: export AWS_S3_BUCKET_REGION={{ .Data.AWS_S3_BUCKET_REGION }} export THEGRAPH_API_URL={{ .Data.THEGRAPH_API_URL }} export HOT_WALLET_KEY={{ .Data.HOT_WALLET_KEY }} + export REGISTRY_OWNER_PKEY={{ .Data.REGISTRY_OWNER_PKEY }} export CSO_CLASSIFIER_API={{ .Data.CSO_CLASSIFIER_API }} export VSCODE_ACCESS_TOKEN={{ .Data.VSCODE_ACCESS_TOKEN }} export NODES_MEDIA_SERVER_URL={{ .Data.NODES_MEDIA_SERVER_URL }} diff --git a/desci-server/kubernetes/deployment_prod.yaml b/desci-server/kubernetes/deployment_prod.yaml index 433c06e9..855eabbe 100755 --- a/desci-server/kubernetes/deployment_prod.yaml +++ b/desci-server/kubernetes/deployment_prod.yaml @@ -63,6 +63,7 @@ spec: export AWS_S3_BUCKET_REGION={{ .Data.AWS_S3_BUCKET_REGION }} export THEGRAPH_API_URL={{ .Data.THEGRAPH_API_URL }} export HOT_WALLET_KEY={{ .Data.HOT_WALLET_KEY }} + export REGISTRY_OWNER_PKEY={{ .Data.REGISTRY_OWNER_PKEY }} export CSO_CLASSIFIER_API={{ .Data.CSO_CLASSIFIER_API }} export VSCODE_ACCESS_TOKEN={{ .Data.VSCODE_ACCESS_TOKEN }} export NODES_MEDIA_SERVER_URL={{ .Data.NODES_MEDIA_SERVER_URL }} diff --git a/desci-server/kubernetes/deployment_staging.yaml b/desci-server/kubernetes/deployment_staging.yaml index 37f173ed..b85b93ed 100644 --- a/desci-server/kubernetes/deployment_staging.yaml +++ b/desci-server/kubernetes/deployment_staging.yaml @@ -75,6 +75,7 @@ spec: export AWS_S3_BUCKET_REGION={{ .Data.AWS_S3_BUCKET_REGION }} export THEGRAPH_API_URL=http://graph-sepolia-prod.desci.com/subgraphs/name/nodes export HOT_WALLET_KEY={{ .Data.HOT_WALLET_KEY }} + export REGISTRY_OWNER_PKEY={{ .Data.REGISTRY_OWNER_PKEY }} export CSO_CLASSIFIER_API={{ .Data.CSO_CLASSIFIER_API }} export VSCODE_ACCESS_TOKEN={{ .Data.VSCODE_ACCESS_TOKEN }} export NODES_MEDIA_SERVER_URL={{ .Data.NODES_MEDIA_SERVER_URL }} From 7d2f750e3d2a21883c4195c073c06dd5c8cb9183 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Wed, 19 Jun 2024 11:11:45 +0200 Subject: [PATCH 154/278] feat: Implement crossref notification callback integration feat: Implement Doi registration queue and add database schema refactor: Doi service and some api routes chore: Update k8s config with new env variables --- .env.example | 6 +- .env.test | 6 +- desci-server/kubernetes/deployment_dev.yaml | 2 + desci-server/kubernetes/deployment_prod.yaml | 2 + .../kubernetes/deployment_staging.yaml | 2 + desci-server/prisma/schema.prisma | 33 +++++++--- desci-server/src/controllers/doi/check.ts | 4 +- desci-server/src/controllers/doi/mint.ts | 60 ++++++++++++++++-- desci-server/src/middleware/validator.ts | 4 +- .../src/routes/v1/attestations/index.ts | 34 +++++----- desci-server/src/routes/v1/auth.ts | 6 +- .../src/routes/v1/communities/index.ts | 18 +++--- desci-server/src/routes/v1/crossref.ts | 50 +++++++++++++++ desci-server/src/routes/v1/doi.ts | 8 +-- desci-server/src/routes/v1/index.ts | 4 +- desci-server/src/routes/v1/nodes.ts | 6 +- desci-server/src/services/Doi.ts | 42 +++++++++++-- desci-server/src/services/crossRef/client.ts | 63 ++++++++++++++++--- .../src/services/crossRef/definitions.ts | 2 + desci-server/src/types/ProcessEnv.d.ts | 2 + desci-server/src/utils/asyncHandler.ts | 10 +-- 21 files changed, 291 insertions(+), 73 deletions(-) create mode 100644 desci-server/src/routes/v1/crossref.ts diff --git a/.env.example b/.env.example index 990377c3..40b2e848 100755 --- a/.env.example +++ b/.env.example @@ -134,4 +134,8 @@ CROSSREF_ADMIN_API=https://test.crossref.org CROSSREF_API_KEY= CROSSREF_EMAIL= CROSSREF_LOGIN= -CROSSREF_PASSWORD= \ No newline at end of file +CROSSREF_PASSWORD= + +# Cross ref notification callback envs +CROSSREF_NOTIFY_ENDPOINT= +CROSSREF_NOTIFY_CALLBACK_PATH= \ No newline at end of file diff --git a/.env.test b/.env.test index a20b6959..b55bd1a3 100644 --- a/.env.test +++ b/.env.test @@ -84,4 +84,8 @@ CROSSREF_ADMIN_API=https://test.crossref.org CROSSREF_API_KEY= CROSSREF_EMAIL= CROSSREF_LOGIN= -CROSSREF_PASSWORD= \ No newline at end of file +CROSSREF_PASSWORD= + +# Cross ref notification callback envs +CROSSREF_NOTIFY_ENDPOINT= +CROSSREF_NOTIFY_CALLBACK_PATH= \ No newline at end of file diff --git a/desci-server/kubernetes/deployment_dev.yaml b/desci-server/kubernetes/deployment_dev.yaml index 310af9ac..50828dd2 100644 --- a/desci-server/kubernetes/deployment_dev.yaml +++ b/desci-server/kubernetes/deployment_dev.yaml @@ -88,6 +88,8 @@ spec: export CROSSREF_PASSWORD={{ .Data.CROSSREF_PASSWORD }} export CROSSREF_METADATA_API={{ .Data.CROSSREF_METADATA_API }} export CROSSREF_ADMIN_API={{ .Data.CROSSREF_ADMIN_API }} + export CROSSREF_NOTIFY_ENDPOINT={{ .Data.CROSSREF_NOTIFY_ENDPOINT }} + export CROSSREF_NOTIFY_CALLBACK_PATH={{ .Data.CROSSREF_NOTIFY_CALLBACK_PATH }} export DEBUG_TEST=0; echo "appfinish"; {{- end -}} diff --git a/desci-server/kubernetes/deployment_prod.yaml b/desci-server/kubernetes/deployment_prod.yaml index 881f1ce7..87574540 100755 --- a/desci-server/kubernetes/deployment_prod.yaml +++ b/desci-server/kubernetes/deployment_prod.yaml @@ -88,6 +88,8 @@ spec: export CROSSREF_PASSWORD={{ .Data.CROSSREF_PASSWORD }} export CROSSREF_METADATA_API={{ .Data.CROSSREF_METADATA_API }} export CROSSREF_ADMIN_API={{ .Data.CROSSREF_ADMIN_API }} + export CROSSREF_NOTIFY_ENDPOINT={{ .Data.CROSSREF_NOTIFY_ENDPOINT }} + export CROSSREF_NOTIFY_CALLBACK_PATH={{ .Data.CROSSREF_NOTIFY_CALLBACK_PATH }} export IGNORE_LINE=0; export DEBUG_TEST=0; echo "appfinish"; diff --git a/desci-server/kubernetes/deployment_staging.yaml b/desci-server/kubernetes/deployment_staging.yaml index ae799615..5bbe48ae 100644 --- a/desci-server/kubernetes/deployment_staging.yaml +++ b/desci-server/kubernetes/deployment_staging.yaml @@ -100,6 +100,8 @@ spec: export CROSSREF_PASSWORD={{ .Data.CROSSREF_PASSWORD }} export CROSSREF_METADATA_API={{ .Data.CROSSREF_METADATA_API }} export CROSSREF_ADMIN_API={{ .Data.CROSSREF_ADMIN_API }} + export CROSSREF_NOTIFY_ENDPOINT={{ .Data.CROSSREF_NOTIFY_ENDPOINT }} + export CROSSREF_NOTIFY_CALLBACK_PATH={{ .Data.CROSSREF_NOTIFY_CALLBACK_PATH }} export DEBUG_TEST=0; echo "appfinish"; {{- end -}} diff --git a/desci-server/prisma/schema.prisma b/desci-server/prisma/schema.prisma index 9890e9c0..599eb911 100755 --- a/desci-server/prisma/schema.prisma +++ b/desci-server/prisma/schema.prisma @@ -835,13 +835,26 @@ model OrcidPutCodes { } model DoiRecord { - id Int @id @default(autoincrement()) - doi String @unique - dpid String @unique - uuid String - node Node @relation(fields: [uuid], references: [uuid]) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt + id Int @id @default(autoincrement()) + doi String @unique + dpid String @unique // remove unique constrant + // add dpid or resource path the doi is registered for + uuid String + node Node @relation(fields: [uuid], references: [uuid]) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + DoiSubmission DoiSubmissionQueue[] +} + +model DoiSubmissionQueue { + id Int @id @default(autoincrement()) + batchId String @unique + createdAt DateTime @default(now()) + doiRecordId Int + doi DoiRecord @relation(fields: [doiRecordId], references: [id]) + notification Json? + status DoiStatus @default(PENDING) + updatedAt DateTime @updatedAt } enum ORCIDRecord { @@ -961,3 +974,9 @@ enum PublishTaskQueueStatus { enum AuthTokenSource { ORCID } + +enum DoiStatus { + PENDING + FAILED + SUCCESS +} diff --git a/desci-server/src/controllers/doi/check.ts b/desci-server/src/controllers/doi/check.ts index 88a459a0..241279e3 100644 --- a/desci-server/src/controllers/doi/check.ts +++ b/desci-server/src/controllers/doi/check.ts @@ -1,9 +1,9 @@ import { NextFunction, Request, Response } from 'express'; import { DoiError } from '../../core/doi/error.js'; -import { BadRequestError, SuccessResponse, doiService, logger } from '../../internal.js'; +import { BadRequestError, RequestWithNode, SuccessResponse, doiService, logger } from '../../internal.js'; -export const checkMintability = async (req: Request, res: Response, _next: NextFunction) => { +export const checkMintability = async (req: RequestWithNode, res: Response, _next: NextFunction) => { const { uuid } = req.params; if (!uuid) throw new BadRequestError(); try { diff --git a/desci-server/src/controllers/doi/mint.ts b/desci-server/src/controllers/doi/mint.ts index 9852d495..137c9da2 100644 --- a/desci-server/src/controllers/doi/mint.ts +++ b/desci-server/src/controllers/doi/mint.ts @@ -1,11 +1,63 @@ +import { DoiStatus } from '@prisma/client'; import { Request, Response, NextFunction } from 'express'; +import _ from 'lodash'; -import { BadRequestError, SuccessResponse, doiService, ensureUuidEndsWithDot } from '../../internal.js'; +import { MintError } from '../../core/doi/error.js'; +import { + BadRequestError, + SuccessMessageResponse, + SuccessResponse, + crossRefClient, + doiService, + ensureUuidEndsWithDot, + logger, +} from '../../internal.js'; -export const mintDoi = async (req: Request, res: Response, next: NextFunction) => { +export const mintDoi = async (req: Request, res: Response, _next: NextFunction) => { const { uuid } = req.params; if (!uuid) throw new BadRequestError(); const sanitizedUuid = ensureUuidEndsWithDot(uuid); - const doi = await doiService.mintDoi(sanitizedUuid); - new SuccessResponse(doi).send(res); + const isPending = await doiService.hasPendingSubmission(sanitizedUuid); + if (isPending) { + throw new MintError('You have a pending submission'); + } else { + const submission = await doiService.mintDoi(sanitizedUuid); + const data = _.pick(submission, ['id', 'status']); + new SuccessResponse(data).send(res); + } +}; + +export interface RequestWithCrossRefPayload extends Request { + payload: { + notifyEndpoint: string; + externalId: string; + internalId: string; + retrieveUrl: string; + serviceDate: string; + retrieveUrlExpirationDate: string; + }; +} + +export const handleCrossrefNotificationCallback = async ( + req: RequestWithCrossRefPayload, + _res: Response, + _next: NextFunction, +) => { + const submission = await doiService.getPendingSubmission(req.payload.externalId); + + if (!submission) { + logger.error({ payload: req.payload }, 'Crossref Notifiication: pending submission not found'); + return; + } + + await doiService.updateSubmission({ id: submission.id }, { notification: req.payload }); + + new SuccessMessageResponse(); + + // check retrieve url to get submission result + const response = await crossRefClient.retrieveSubmission(req.payload.retrieveUrl); + await doiService.updateSubmission( + { id: submission.id }, + { status: response.success ? DoiStatus.SUCCESS : response.failure ? DoiStatus.FAILED : DoiStatus.PENDING }, + ); }; diff --git a/desci-server/src/middleware/validator.ts b/desci-server/src/middleware/validator.ts index 0737e303..2acafc15 100644 --- a/desci-server/src/middleware/validator.ts +++ b/desci-server/src/middleware/validator.ts @@ -1,10 +1,10 @@ import { NextFunction, Request, Response } from 'express'; import { ZodError, z } from 'zod'; -import { BadRequestError, InternalError, asyncHander } from '../internal.js'; +import { BadRequestError, InternalError, asyncHandler } from '../internal.js'; export const validate = (schema: z.ZodObject) => - asyncHander(async (req: Request, res: Response, next: NextFunction) => { + asyncHandler(async (req: Request, res: Response, next: NextFunction) => { try { await schema.parseAsync(req); next(); diff --git a/desci-server/src/routes/v1/attestations/index.ts b/desci-server/src/routes/v1/attestations/index.ts index 359e3693..4333c2b1 100644 --- a/desci-server/src/routes/v1/attestations/index.ts +++ b/desci-server/src/routes/v1/attestations/index.ts @@ -1,7 +1,7 @@ import { Router } from 'express'; import { - asyncHander, + asyncHandler, addComment, addReaction, addVerification, @@ -41,37 +41,37 @@ import { const router = Router(); -router.get('/suggestions/all', [ensureUser], asyncHander(getAllRecommendations)); -router.get('/suggestions/protected', [ensureUser], asyncHander(getValidatedRecommendations)); +router.get('/suggestions/all', [ensureUser], asyncHandler(getAllRecommendations)); +router.get('/suggestions/protected', [ensureUser], asyncHandler(getValidatedRecommendations)); router.get( '/claims/:communityId/:dpid', [ensureUser, validate(showCommunityClaimsSchema)], - asyncHander(showCommunityClaims), + asyncHandler(showCommunityClaims), ); -router.get('/:dpid', [validate(showNodeAttestationsSchema)], asyncHander(showNodeAttestations)); -router.get('/:claimId/reactions', [validate(getAttestationReactionsSchema)], asyncHander(getAttestationReactions)); +router.get('/:dpid', [validate(showNodeAttestationsSchema)], asyncHandler(showNodeAttestations)); +router.get('/:claimId/reactions', [validate(getAttestationReactionsSchema)], asyncHandler(getAttestationReactions)); router.get( '/:claimId/verifications', [validate(getAttestationVerificationsSchema)], - asyncHander(getAttestationVerifications), + asyncHandler(getAttestationVerifications), ); -router.get('/:claimId/comments', [validate(getAttestationCommentsSchema)], asyncHander(getAttestationComments)); +router.get('/:claimId/comments', [validate(getAttestationCommentsSchema)], asyncHandler(getAttestationComments)); -router.post('/claim', [ensureUser, validate(claimAttestationSchema)], asyncHander(claimAttestation)); -router.post('/unclaim', [ensureUser, validate(removeClaimSchema)], asyncHander(removeClaim)); -router.post('/claimAll', [ensureUser, validate(claimEntryAttestationsSchema)], asyncHander(claimEntryRequirements)); +router.post('/claim', [ensureUser, validate(claimAttestationSchema)], asyncHandler(claimAttestation)); +router.post('/unclaim', [ensureUser, validate(removeClaimSchema)], asyncHandler(removeClaim)); +router.post('/claimAll', [ensureUser, validate(claimEntryAttestationsSchema)], asyncHandler(claimEntryRequirements)); -router.post('/comment', [ensureUser, validate(createCommentSchema)], asyncHander(addComment)); -router.post('/reaction', [ensureUser, validate(addReactionSchema)], asyncHander(addReaction)); -router.post('/verification', [ensureUser, validate(addVerificationSchema)], asyncHander(addVerification)); +router.post('/comment', [ensureUser, validate(createCommentSchema)], asyncHandler(addComment)); +router.post('/reaction', [ensureUser, validate(addReactionSchema)], asyncHandler(addReaction)); +router.post('/verification', [ensureUser, validate(addVerificationSchema)], asyncHandler(addVerification)); -router.delete('/comments/:commentId', [ensureUser, validate(deleteCommentSchema)], asyncHander(removeComment)); -router.delete('/reactions/:reactionId', [ensureUser, validate(deleteReactionSchema)], asyncHander(removeReaction)); +router.delete('/comments/:commentId', [ensureUser, validate(deleteCommentSchema)], asyncHandler(removeComment)); +router.delete('/reactions/:reactionId', [ensureUser, validate(deleteReactionSchema)], asyncHandler(removeReaction)); router.delete( '/verifications/:verificationId', [ensureUser, validate(deleteVerificationSchema)], - asyncHander(removeVerification), + asyncHandler(removeVerification), ); export default router; diff --git a/desci-server/src/routes/v1/auth.ts b/desci-server/src/routes/v1/auth.ts index 5075aa97..96f0d6a0 100755 --- a/desci-server/src/routes/v1/auth.ts +++ b/desci-server/src/routes/v1/auth.ts @@ -17,15 +17,15 @@ import { check, } from '../../controllers/auth/index.js'; import { walletLogin, walletNonce } from '../../controllers/users/associateWallet.js'; -import { asyncHander } from '../../internal.js'; +import { asyncHandler } from '../../internal.js'; import { ensureUser } from '../../middleware/permissions.js'; const router = Router(); router.get('/check', [ensureUser], check); router.post('/login', login); -router.post('/login/did', asyncHander(walletLogin)); -router.get('/login/did/:walletAddress', asyncHander(walletNonce)); +router.post('/login/did', asyncHandler(walletLogin)); +router.get('/login/did/:walletAddress', asyncHandler(walletNonce)); router.delete('/logout', logout); router.get('/profile', [ensureUser], profile); router.post('/register', register); diff --git a/desci-server/src/routes/v1/communities/index.ts b/desci-server/src/routes/v1/communities/index.ts index 5153e240..f3719544 100644 --- a/desci-server/src/routes/v1/communities/index.ts +++ b/desci-server/src/routes/v1/communities/index.ts @@ -1,7 +1,7 @@ import { Router } from 'express'; import { - asyncHander, + asyncHandler, checkMemberGuard, ensureUser, getAllFeeds, @@ -19,24 +19,24 @@ import { getCommunityDetailsSchema, getCommunityFeedSchema, memberGuardSchema } const router = Router(); // list all communities and curated nodes() -router.get('/list', [], asyncHander(listCommunities)); -router.get('/feeds', [], asyncHander(getAllFeeds)); -router.get('/:communityName', [validate(getCommunityDetailsSchema)], asyncHander(getCommunityDetails)); +router.get('/list', [], asyncHandler(listCommunities)); +router.get('/feeds', [], asyncHandler(getAllFeeds)); +router.get('/:communityName', [validate(getCommunityDetailsSchema)], asyncHandler(getCommunityDetails)); router.get( '/:communityName/attestations', [validate(getCommunityDetailsSchema)], - asyncHander(getCommunityRecommendations), + asyncHandler(getCommunityRecommendations), ); router.get( '/:communityName/validatedAttestations', [validate(getCommunityDetailsSchema)], - asyncHander(getValidatedAttestations), + asyncHandler(getValidatedAttestations), ); -router.get('/:communityId/feed', [validate(getCommunityFeedSchema)], asyncHander(getCommunityFeed)); -router.get('/:communityId/radar', [validate(getCommunityFeedSchema)], asyncHander(getCommunityRadar)); +router.get('/:communityId/feed', [validate(getCommunityFeedSchema)], asyncHandler(getCommunityFeed)); +router.get('/:communityId/radar', [validate(getCommunityFeedSchema)], asyncHandler(getCommunityRadar)); -router.post('/:communityId/memberGuard', [ensureUser, validate(memberGuardSchema)], asyncHander(checkMemberGuard)); +router.post('/:communityId/memberGuard', [ensureUser, validate(memberGuardSchema)], asyncHandler(checkMemberGuard)); export default router; diff --git a/desci-server/src/routes/v1/crossref.ts b/desci-server/src/routes/v1/crossref.ts new file mode 100644 index 00000000..c3f31c4a --- /dev/null +++ b/desci-server/src/routes/v1/crossref.ts @@ -0,0 +1,50 @@ +// crossref/callback +import { NextFunction, Request, Response, Router } from 'express'; + +import { + RequestWithCrossRefPayload, + asyncHandler, + handleCrossrefNotificationCallback, + logger, +} from '../../internal.js'; + +// assert required env are available +if (!process.env.CROSSREF_NOTIFY_CALLBACK_PATH) throw Error('Env `CROSSREF_NOTIFY_CALLBACK_PATH` not set.'); +if (!process.env.CROSSREF_NOTIFY_ENDPOINT) throw Error('Env `CROSSREF_NOTIFY_ENDPOINT` not set.'); + +const notifierCallbackUrl = process.env.CROSSREF_NOTIFY_CALLBACK_PATH; + +const router = Router(); + +const ensureCrossrefNotifier = (req: Request, _res: Response, next: NextFunction) => { + // parse the follwing headers and attach it to the request's context; + // CROSSREF-NOTIFY-ENDPOINT + // CROSSREF-EXTERNAL-ID + // CROSSREF-INTERNAL-ID + // CROSSREF-RETRIEVE-URL + // CROSSREF-SERVICE-DATE + // CROSSREF-RETRIEVE-URL-EXPIRATION-DATE + + const payload = { + notifyEndpoint: req.headers['CROSSREF-NOTIFY-ENDPOINT'] as string, + externalId: req.headers[' CROSSREF-EXTERNAL-ID'] as string, + internalId: req.headers['CROSSREF-INTERNAL-ID'] as string, + retrieveUrl: req.headers['CROSSREF-RETRIEVE-URL'] as string, + serviceDate: req.headers['CROSSREF-SERVICE-DATE'] as string, + retrieveUrlExpirationDate: req.headers['CROSSREF-RETRIEVE-URL-EXPIRATION-DATE'] as string, + }; + + logger.info({ payload, headers: req.headers }, 'CROSSREF NOTIFICATION'); + // verify notification endpoint + if (payload.notifyEndpoint !== process.env.CROSSREF_NOTIFY_ENDPOINT) { + return; + } + + (req as RequestWithCrossRefPayload).payload = payload; + // validate caller is crossref client using provided endpoint and check if + next(); +}; + +router.post(notifierCallbackUrl, [ensureCrossrefNotifier], asyncHandler(handleCrossrefNotificationCallback)); + +export default router; diff --git a/desci-server/src/routes/v1/doi.ts b/desci-server/src/routes/v1/doi.ts index d80a6e49..06055255 100644 --- a/desci-server/src/routes/v1/doi.ts +++ b/desci-server/src/routes/v1/doi.ts @@ -1,11 +1,11 @@ import { Router } from 'express'; -import { asyncHander, checkMintability, ensureNodeAccess, ensureUser, getDoi, mintDoi } from '../../internal.js'; +import { asyncHandler, checkMintability, ensureNodeAccess, ensureUser, getDoi, mintDoi } from '../../internal.js'; const router = Router(); -router.post('/check/:uuid', [ensureUser, ensureNodeAccess], asyncHander(checkMintability)); -router.post('/mint/:uuid', [ensureUser, ensureNodeAccess], asyncHander(mintDoi)); -router.get('/:identifier', [ensureUser], asyncHander(getDoi)); +router.post('/check/:uuid', [ensureUser, ensureNodeAccess], asyncHandler(checkMintability)); +router.post('/mint/:uuid', [ensureUser, ensureNodeAccess], asyncHandler(mintDoi)); +router.get('/:identifier', [ensureUser], asyncHandler(getDoi)); export default router; diff --git a/desci-server/src/routes/v1/index.ts b/desci-server/src/routes/v1/index.ts index 2d9d20d9..e624a07f 100755 --- a/desci-server/src/routes/v1/index.ts +++ b/desci-server/src/routes/v1/index.ts @@ -6,7 +6,7 @@ import { queryResearchFields } from '../../controllers/data/index.js'; import { queryRor } from '../../controllers/proxy/index.js'; import { ipfsReadGatewayProxy } from '../../controllers/proxy/ipfsReadGateway.js'; import { nft } from '../../controllers/raw/nft.js'; -import { asyncHander } from '../../internal.js'; +import { asyncHandler } from '../../internal.js'; import { ensureUser } from '../../middleware/permissions.js'; import admin from './admin.js'; @@ -28,7 +28,7 @@ const router = Router(); router.get( '/nonce', [ensureUser], - asyncHander(async function (req, res) { + asyncHandler(async function (req, res) { const nonce = generateNonce(); const user = (req as any).user; await prisma.user.update({ diff --git a/desci-server/src/routes/v1/nodes.ts b/desci-server/src/routes/v1/nodes.ts index 57268d9d..ea411df2 100755 --- a/desci-server/src/routes/v1/nodes.ts +++ b/desci-server/src/routes/v1/nodes.ts @@ -38,7 +38,7 @@ import { prepublish } from '../../controllers/nodes/prepublish.js'; import { listSharedNodes } from '../../controllers/nodes/sharedNodes.js'; import { thumbnails } from '../../controllers/nodes/thumbnails.js'; import { versionDetails } from '../../controllers/nodes/versionDetails.js'; -import { asyncHander, attachUser, validate } from '../../internal.js'; +import { asyncHandler, attachUser, validate } from '../../internal.js'; import { ensureNodeAccess, ensureWriteNodeAccess } from '../../middleware/authorisation.js'; import { ensureUser } from '../../middleware/permissions.js'; @@ -55,11 +55,11 @@ router.get('/', [ensureUser], list); router.post('/doi', [ensureUser], retrieveDoi); router.get('/pdf', proxyPdf); router.post('/consent', [], consent); -router.post('/consent/publish', [ensureUser, validate(publishConsentSchema)], asyncHander(publishConsent)); +router.post('/consent/publish', [ensureUser, validate(publishConsentSchema)], asyncHandler(publishConsent)); router.get( '/consent/publish/:uuid', [ensureUser, validate(checkPublishConsentSchema)], - asyncHander(checkUserPublishConsent), + asyncHandler(checkUserPublishConsent), ); router.post('/terms', [ensureUser], consent); router.get('/share/verify/:shareId', checkPrivateShareId); diff --git a/desci-server/src/services/Doi.ts b/desci-server/src/services/Doi.ts index e5eb2970..91ec1ba7 100644 --- a/desci-server/src/services/Doi.ts +++ b/desci-server/src/services/Doi.ts @@ -1,5 +1,5 @@ import { PdfComponent, ResearchObjectComponentType, ResearchObjectV1 } from '@desci-labs/desci-models'; -import { PrismaClient } from '@prisma/client'; +import { DoiStatus, DoiSubmissionQueue, Prisma, PrismaClient } from '@prisma/client'; import { v4 } from 'uuid'; import { DuplicateMintError, BadManifestError, AttestationsError, MintError } from '../core/doi/error.js'; @@ -132,25 +132,35 @@ export class DoiService { const [month, day, year] = publicationDate.split('-'); - const metadataResponse = await crossRefClient.postMetadata({ + const metadataResponse = await crossRefClient.registerDoi({ manifest, doi, publicationDate: { day, month, year }, }); if (!metadataResponse.ok) { - throw new MintError(metadataResponse.message || 'A doi could not be registered for this node'); + throw new MintError("We couldn't register a DOI for this research object"); } // todo: add submissionId and doi to DoiSubmissionLog table to keep track of status - logger.info({ doiSuffix, doi, uuid, metadataResponse }, 'MINT DOI'); - return await this.dbClient.doiRecord.create({ + logger.info({ doiSuffix, doi, uuid, metadataResponse }, 'DOI SUBMITTED'); + + // todo: + const doiRecord = await this.dbClient.doiRecord.create({ data: { uuid, dpid, doi, }, }); + // only create doi if submission status is success + const submission = await crossRefClient.addSubmissiontoQueue({ + doi: doiRecord.id, + batchId: metadataResponse.batchId, + }); + + // return submission queue data + return submission; } async getDoiByDpidOrUuid(identifier: string) { @@ -158,4 +168,26 @@ export class DoiService { where: { OR: [{ dpid: identifier }, { uuid: ensureUuidEndsWithDot(identifier) }] }, }); } + + async hasPendingSubmission(uuid: string) { + const pending = await this.dbClient.doiRecord.findFirst({ + where: { uuid: ensureUuidEndsWithDot(uuid) }, + include: { DoiSubmission: { where: { status: DoiStatus.PENDING } } }, + }); + + return pending.DoiSubmission.length > 0 ? true : false; + } + + async getPendingSubmission(batchId: string) { + return await this.dbClient.doiSubmissionQueue.findFirst({ + where: { batchId, status: DoiStatus.PENDING }, + }); + } + + async updateSubmission( + filter: Prisma.DoiSubmissionQueueWhereInput, + data: Prisma.DoiSubmissionQueueUncheckedUpdateManyInput, + ) { + return await this.dbClient.doiSubmissionQueue.updateMany({ where: filter, data }); + } } diff --git a/desci-server/src/services/crossRef/client.ts b/desci-server/src/services/crossRef/client.ts index 930e8dd6..06f2e9ce 100644 --- a/desci-server/src/services/crossRef/client.ts +++ b/desci-server/src/services/crossRef/client.ts @@ -9,7 +9,7 @@ import { logger as parentLogger } from '../../logger.js'; import { ONE_DAY_TTL, getFromCache, setToCache } from '../../redisClient.js'; import { asyncMap } from '../../utils.js'; -import { CrossRefHttpResponse, Items, QueryWorkParams, Work } from './definitions.js'; +import { CrossRefHttpResponse, Items, QueryWorkParams, RegisterDoiResponse, Work } from './definitions.js'; import { keysToDotsAndDashses } from './utils.js'; const logger = parentLogger.child({ module: '[CrossRefClient]' }); @@ -25,7 +25,7 @@ const metadataTemplate = ` xmlns:fr="http://www.crossref.org/fundref.xsd" xmlns:mml="http://www.w3.org/1998/Math/MathML" version="5.3.1"> - &_.submissionId; + &_.batchId; &_.timestamp; &depositor.name; @@ -180,7 +180,16 @@ class CrossRefClient { } } - async postMetadata(query: { manifest: ResearchObjectV1; doi: string; publicationDate: PublicationDate }) { + // check if there's a pending submission for a dpid + async getPendingSubmission(dpid: string) { + // todo: retrieve doi whose submission log is pending + } + + async registerDoi(query: { + manifest: ResearchObjectV1; + doi: string; + publicationDate: PublicationDate; + }): Promise { const contributors = await asyncMap(query.manifest.authors ?? [], async (author) => { const user = author.orcid ? await prisma.user.findUnique({ where: { orcid: author.orcid } }) : null; logger.info({ user: { orcid: user?.orcid } }); @@ -204,11 +213,11 @@ class CrossRefClient { }; }); - const submissionId = v4(); + const batchId = v4(); const param = { _: { - submissionId, + batchId, timestamp: Date.now(), dpid: query.manifest.dpid.id, doi: query.doi, @@ -232,7 +241,7 @@ class CrossRefClient { // prefix filename with `@` as seen from the crossref documentation // https://www.crossref.org/documentation/register-maintain-records/direct-deposit-xml/https-post/#00230 - const filename = `@dpid_${param._.dpid}_upload_xml.xml`; + const filename = `dpid_${param._.dpid}_upload.xml`; // save file for debugging purposes // await fs.writeFile(path.join(process.cwd(), filename), buffer); const form = new FormData(); @@ -252,12 +261,14 @@ class CrossRefClient { logger.info({ body }, 'BODY'); if (!response.ok || response.status !== 200) { - return { ok: false, message: body }; + // attach custom alert here + logger.error(body, 'METADATA SUBMISSION ERROR'); + return { ok: false }; } - return { ok: true, submissionId }; + return { ok: true, batchId }; } catch (error) { logger.error(error, 'Post metadata Api Error'); - return { ok: false, submissionId }; + return { ok: false }; } } @@ -277,6 +288,40 @@ class CrossRefClient { } return response; } + + async addSubmissiontoQueue({ doi, batchId }: { doi: number; batchId: string }) { + // check if there is no pending submission log + return await prisma.doiSubmissionQueue.create({ data: { doiRecordId: doi, batchId } }); + } + + async retrieveSubmission(retrieveUrl: string) { + // retrieve submission log whose batchId == param.['CROSSREF-EXTERNAL-ID'] + // update with notifiication payload + // query submssion payload from param.CROSSREF-RETRIEVE-URL + // only create doi if submission status is success + + const response = (await fetch(retrieveUrl).then((res) => res.json())) as NotificationResult; + logger.info(response, 'CROSSREF NOTIFICATION: retrieveSubmission'); + // return interprete the response from the api to determine if the + // submission status has either `success | pending | failed` + return { success: true, pending: true, failure: true }; + } } export default CrossRefClient; + +type NotificationResult = { + id: number; + status: string; + completed: string | null; + serviced: string; + notifyEndpoint: string; + notifyPayloadId: string; + notifyPayloadExpiration: string; + internalTrackingId: string; + externalTrackingId: string; + recordCreated: string; + recordUpdated: string | null; +}; + +// TODO: run yarn generate diff --git a/desci-server/src/services/crossRef/definitions.ts b/desci-server/src/services/crossRef/definitions.ts index 09f4c35c..719f457f 100644 --- a/desci-server/src/services/crossRef/definitions.ts +++ b/desci-server/src/services/crossRef/definitions.ts @@ -61,3 +61,5 @@ export enum WorkSelectOptions { TITLE = 'title', AUTHOR = 'author', } + +export type RegisterDoiResponse = { ok: true; batchId: string } | { ok: false; batchId?: never }; diff --git a/desci-server/src/types/ProcessEnv.d.ts b/desci-server/src/types/ProcessEnv.d.ts index 84e6a17f..658b8f56 100755 --- a/desci-server/src/types/ProcessEnv.d.ts +++ b/desci-server/src/types/ProcessEnv.d.ts @@ -18,5 +18,7 @@ declare namespace NodeJS { ORCID_API_DOMAIN: string; CROSSREF_LOGIN: string; CROSSREF_PASSWORD: string; + CROSSREF_NOTIFY_ENDPOINT: string; + CROSSREF_NOTIFY_CALLBACK_PATH: string; } } diff --git a/desci-server/src/utils/asyncHandler.ts b/desci-server/src/utils/asyncHandler.ts index dc761165..18ae132d 100644 --- a/desci-server/src/utils/asyncHandler.ts +++ b/desci-server/src/utils/asyncHandler.ts @@ -1,7 +1,9 @@ import { NextFunction, Request, Response } from 'express'; -export type AsyncFunction = (req: Request, res: Response, next: NextFunction) => Promise; +export type AsyncFunction = (req: R, res: Response, next: NextFunction) => Promise; -export const asyncHander = (execution: AsyncFunction) => (req: Request, res: Response, next: NextFunction) => { - execution(req, res, next).catch(next); -}; +export const asyncHandler = + (execution: AsyncFunction) => + (req: Request, res: Response, next: NextFunction) => { + execution(req as R, res, next).catch(next); + }; From 3b932d116ea71344d7acdc43decf283cbad9b4f4 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Wed, 19 Jun 2024 11:28:31 +0200 Subject: [PATCH 155/278] run db migration for doi submission queue --- .../migration.sql | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 desci-server/prisma/migrations/20240619091530_add_doi_submission_queue/migration.sql diff --git a/desci-server/prisma/migrations/20240619091530_add_doi_submission_queue/migration.sql b/desci-server/prisma/migrations/20240619091530_add_doi_submission_queue/migration.sql new file mode 100644 index 00000000..659866a3 --- /dev/null +++ b/desci-server/prisma/migrations/20240619091530_add_doi_submission_queue/migration.sql @@ -0,0 +1,21 @@ +-- CreateEnum +CREATE TYPE "DoiStatus" AS ENUM ('PENDING', 'FAILED', 'SUCCESS'); + +-- CreateTable +CREATE TABLE "DoiSubmissionQueue" ( + "id" SERIAL NOT NULL, + "batchId" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "doiRecordId" INTEGER NOT NULL, + "notification" JSONB, + "status" "DoiStatus" NOT NULL DEFAULT 'PENDING', + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "DoiSubmissionQueue_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "DoiSubmissionQueue_batchId_key" ON "DoiSubmissionQueue"("batchId"); + +-- AddForeignKey +ALTER TABLE "DoiSubmissionQueue" ADD CONSTRAINT "DoiSubmissionQueue_doiRecordId_fkey" FOREIGN KEY ("doiRecordId") REFERENCES "DoiRecord"("id") ON DELETE RESTRICT ON UPDATE CASCADE; From c8ed676993b10257937f1608c6b0653b45e90a76 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Wed, 19 Jun 2024 12:49:58 +0200 Subject: [PATCH 156/278] support updating node attestations with dpid --- desci-server/src/controllers/nodes/publish.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/desci-server/src/controllers/nodes/publish.ts b/desci-server/src/controllers/nodes/publish.ts index 47e5c18e..6ac3a4dc 100644 --- a/desci-server/src/controllers/nodes/publish.ts +++ b/desci-server/src/controllers/nodes/publish.ts @@ -41,7 +41,21 @@ export type PublishResBody = | { error: string; }; - +async function updateAssociatedAttestations(nodeUuid: string, dpid: string) { + const logger = parentLogger.child({ + // id: req.id, + module: 'NODE::publishController', + }); + logger.info({ nodeUuid, dpid }, `[updateAssociatedAttestations]`); + return await prisma.nodeAttestation.updateMany({ + where: { + nodeUuid, + }, + data: { + nodeDpid10: dpid, + }, + }); +} // call node publish service and add job to queue export const publish = async (req: PublishRequest, res: Response, _next: NextFunction) => { const { uuid, cid, manifest, transactionId, ceramicStream, commitId } = req.body; @@ -132,7 +146,7 @@ export const publish = async (req: PublishRequest, res: Response status: PublishTaskQueueStatus.WAITING, }, }); - + updateAssociatedAttestations(node.uuid, manifest.dpid.id); return res.send({ ok: true, taskId: publishTask.id, From 493d93340ccd89a03a3ebbb298e9ffcf4fc4ca37 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Wed, 19 Jun 2024 14:31:47 +0000 Subject: [PATCH 157/278] local dev fixes --- desci-server/Makefile | 2 +- .../src/controllers/nodes/createDpid.ts | 167 ++++++++---------- 2 files changed, 70 insertions(+), 99 deletions(-) diff --git a/desci-server/Makefile b/desci-server/Makefile index 7047abba..2896cde1 100644 --- a/desci-server/Makefile +++ b/desci-server/Makefile @@ -1,7 +1,7 @@ .PHONY: install clean install: - yarn --frozen-lockfile + yarn --ignore-engines --frozen-lockfile clean: rm -rf node_modules diff --git a/desci-server/src/controllers/nodes/createDpid.ts b/desci-server/src/controllers/nodes/createDpid.ts index 6eb388f9..e5ec6d61 100644 --- a/desci-server/src/controllers/nodes/createDpid.ts +++ b/desci-server/src/controllers/nodes/createDpid.ts @@ -1,12 +1,16 @@ -import { Response } from "express"; -import { ethers } from "ethers"; +import { newCeramicClient, resolveHistory } from '@desci-labs/desci-codex-lib'; +import { contracts, typechain as tc } from '@desci-labs/desci-contracts'; +import { + DpidAliasRegistry, + type DpidMintedEvent, +} from '@desci-labs/desci-contracts/dist/typechain-types/DpidAliasRegistry.js'; +import { ethers } from 'ethers'; +import { Response } from 'express'; +import { Logger } from 'pino'; + import { logger as parentLogger } from '../../logger.js'; -import { RequestWithNode } from "../../middleware/authorisation.js"; -import { contracts, typechain as tc } from "@desci-labs/desci-contracts"; -import { DpidAliasRegistry, type DpidMintedEvent } from "@desci-labs/desci-contracts/dist/typechain-types/DpidAliasRegistry.js"; -import { setDpidAlias } from "../../services/nodeManager.js"; -import { newCeramicClient, resolveHistory } from "@desci-labs/desci-codex-lib"; -import { Logger } from "pino"; +import { RequestWithNode } from '../../middleware/authorisation.js'; +import { setDpidAlias } from '../../services/nodeManager.js'; type DpidResponse = DpidSuccessResponse | DpidErrorResponse; export type DpidSuccessResponse = { @@ -18,19 +22,19 @@ export type DpidErrorResponse = { }; const CERAMIC_API_URLS = { - local: "http://host.docker.internal:7007", - dev: "https://ceramic-dev.desci.com", - prod: "https://ceramic-prod.desci.com", + local: 'http://host.docker.internal:7007', + dev: 'https://ceramic-dev.desci.com', + prod: 'https://ceramic-prod.desci.com', } as const; const OPTIMISM_RPC_URLS = { - local: "http://host.docker.internal:8545", - dev: "https://reverse-proxy-dev.desci.com/rpc_opt_sepolia", - prod: "https://reverse-proxy-prod.desci.com/rpc_opt_mainnet", + local: 'http://host.docker.internal:8545', + dev: 'https://reverse-proxy-dev.desci.com/rpc_opt_sepolia', + prod: 'https://reverse-proxy-prod.desci.com/rpc_opt_mainnet', } as const; /** Not secret: pre-seeded ganache account for local dev */ -const GANACHE_PKEY = "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; +const GANACHE_PKEY = 'ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'; const apiServerUrl = process.env.SERVER_URL; @@ -39,24 +43,24 @@ let optimismRpcUrl: string; let aliasRegistryAddress: string; let ceramicApiUrl: string; -if (apiServerUrl.includes("localhost")) { +if (apiServerUrl.includes('localhost') || apiServerUrl.includes('host.docker.internal')) { aliasRegistryAddress = contracts.localDpidAliasInfo.proxies.at(0).address; ceramicApiUrl = CERAMIC_API_URLS.local; optimismRpcUrl = OPTIMISM_RPC_URLS.local; -} else if (apiServerUrl.includes("dev") || apiServerUrl.includes("staging")) { +} else if (apiServerUrl.includes('dev') || apiServerUrl.includes('staging')) { aliasRegistryAddress = contracts.devDpidAliasInfo.proxies.at(0).address; ceramicApiUrl = CERAMIC_API_URLS.dev; optimismRpcUrl = OPTIMISM_RPC_URLS.dev; -} else if (process.env.NODE_ENV === "production") { +} else if (process.env.NODE_ENV === 'production') { aliasRegistryAddress = contracts.prodDpidAliasInfo.proxies.at(0).address; ceramicApiUrl = CERAMIC_API_URLS.prod; optimismRpcUrl = OPTIMISM_RPC_URLS.prod; } else { - console.error("Cannot derive contract address due to ambiguous environment"); - throw new Error("Ambiguous environment"); -}; + console.error('Cannot derive contract address due to ambiguous environment'); + throw new Error('Ambiguous environment'); +} -console.log("Using new publish configuration:", { aliasRegistryAddress, optimismRpcUrl, ceramicApiUrl }); +console.log('Using new publish configuration:', { aliasRegistryAddress, optimismRpcUrl, ceramicApiUrl }); export const createDpid = async (req: RequestWithNode, res: Response) => { const owner = req.user; @@ -64,7 +68,7 @@ export const createDpid = async (req: RequestWithNode, res: Response => { +export const getOrCreateDpid = async (streamId: string): Promise => { const logger = parentLogger.child({ - module: "NODE::mintDpid", + module: 'NODE::mintDpid', ceramicStream: streamId, }); @@ -104,14 +106,11 @@ export const getOrCreateDpid = async ( await provider.ready; const wallet = new ethers.Wallet( - apiServerUrl.includes("localhost") ? GANACHE_PKEY : process.env.HOT_WALLET_KEY, + apiServerUrl.includes('localhost') ? GANACHE_PKEY : process.env.HOT_WALLET_KEY, provider, ); - const dpidAliasRegistry = tc.DpidAliasRegistry__factory.connect( - aliasRegistryAddress, - wallet, - ); + const dpidAliasRegistry = tc.DpidAliasRegistry__factory.connect(aliasRegistryAddress, wallet); // Not exists will return the zero value, i.e. 0 const checkDpid = await dpidAliasRegistry.find(streamId); @@ -120,16 +119,16 @@ export const getOrCreateDpid = async ( if (existingDpid !== 0) { logger.info(`Skipping alias creation, stream ${streamId} already bound to ${existingDpid}`); return existingDpid; - }; + } const tx = await dpidAliasRegistry.mintDpid(streamId); const receipt = await tx.wait(); - const { args: [ dpidBn ] } = receipt.events[0] as DpidMintedEvent; + const { + args: [dpidBn], + } = receipt.events[0] as DpidMintedEvent; const dpid = ethers.BigNumber.from(dpidBn).toNumber(); - logger.info( - `Created dPID alias ${dpid} for stream ${streamId}`, - ); + logger.info(`Created dPID alias ${dpid} for stream ${streamId}`); return dpid; }; @@ -142,13 +141,10 @@ export const getOrCreateDpid = async ( * * Note: this method in the registry contract is only callable by contract * owner, so this is not generally available. -*/ -export const upgradeDpid = async ( - dpid: number, - ceramicStream: string, -): Promise => { + */ +export const upgradeDpid = async (dpid: number, ceramicStream: string): Promise => { const logger = parentLogger.child({ - module: "NODE::upgradeDpid", + module: 'NODE::upgradeDpid', ceramicStream, dpid, }); @@ -156,37 +152,27 @@ export const upgradeDpid = async ( const provider = new ethers.providers.JsonRpcProvider(optimismRpcUrl); if (!process.env.REGISTRY_OWNER_PKEY) { - throw new Error("REGISTRY_OWNER_PKEY missing, cannot upgrade dpid"); - }; + throw new Error('REGISTRY_OWNER_PKEY missing, cannot upgrade dpid'); + } await provider.ready; const wallet = new ethers.Wallet( - apiServerUrl.includes("localhost") ? GANACHE_PKEY : process.env.REGISTRY_OWNER_PKEY, + apiServerUrl.includes('localhost') ? GANACHE_PKEY : process.env.REGISTRY_OWNER_PKEY, provider, ); - const dpidAliasRegistry = tc.DpidAliasRegistry__factory.connect( - aliasRegistryAddress, - wallet, - ); + const dpidAliasRegistry = tc.DpidAliasRegistry__factory.connect(aliasRegistryAddress, wallet); - const historyValid = await validateHistory( - dpid, ceramicStream, dpidAliasRegistry, logger - ); + const historyValid = await validateHistory(dpid, ceramicStream, dpidAliasRegistry, logger); if (!historyValid) { - logger.warn( - { dpid, ceramicStream }, - "version histories disagree; refusing to upgrade dPID", - ); - throw new Error("dPID history mismatch"); - }; + logger.warn({ dpid, ceramicStream }, 'version histories disagree; refusing to upgrade dPID'); + throw new Error('dPID history mismatch'); + } const tx = await dpidAliasRegistry.upgradeDpid(dpid, ceramicStream); await tx.wait(); - logger.info( - `Upgraded dPID ${dpid} to track stream ${ceramicStream}`, - ); + logger.info(`Upgraded dPID ${dpid} to track stream ${ceramicStream}`); return dpid; }; @@ -196,48 +182,33 @@ export const upgradeDpid = async ( * CID's as they were imported into the alias registry contract. * This should be checked before upgrading a dPID, to make sure * the new stream accurately represents the publish history. -*/ -const validateHistory = async ( - dpid: number, - ceramicStream: string, - registry: DpidAliasRegistry, - logger: Logger -) => { + */ +const validateHistory = async (dpid: number, ceramicStream: string, registry: DpidAliasRegistry, logger: Logger) => { const client = newCeramicClient(ceramicApiUrl); const legacyEntry = await registry.legacyLookup(dpid); - const streamEvents = await resolveHistory(client, ceramicStream) - const streamStates = await Promise.all(streamEvents - .map(s => s.commit) - .map(c => client.loadStream(c).then(state => state.content)) + const streamEvents = await resolveHistory(client, ceramicStream); + const streamStates = await Promise.all( + streamEvents.map((s) => s.commit).map((c) => client.loadStream(c).then((state) => state.content)), ); - const [_owner, legacyVersions ] = legacyEntry; + const [_owner, legacyVersions] = legacyEntry; // Stream could have one or more additional entries if (legacyVersions.length > streamStates.length) { - logger.error( - { legacyVersions, streamStates }, - "Stream has shorter history than legacy dPID", - ); + logger.error({ legacyVersions, streamStates }, 'Stream has shorter history than legacy dPID'); return false; - }; + } for (const [i, legacyVersion] of legacyVersions.entries()) { // Cant compare timestamp because anchor time WILL differ const expectedCid = legacyVersion[0]; if (expectedCid !== streamStates[i].manifest) { - logger.error( - { legacyVersions, streamStates}, - "Manifest CID mismatch between legacy and stream history", - ); + logger.error({ legacyVersions, streamStates }, 'Manifest CID mismatch between legacy and stream history'); return false; - }; - }; + } + } - logger.info( - { dpid, ceramicStream }, - "Legacy and stream history check passed", - ); + logger.info({ dpid, ceramicStream }, 'Legacy and stream history check passed'); return true; -} +}; From 0fd35bd4108f7ea3c8e7ff176997a54a6931a6a6 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Wed, 19 Jun 2024 15:29:59 +0000 Subject: [PATCH 158/278] enable demo prepub generations --- desci-server/src/services/PublishPackage.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/desci-server/src/services/PublishPackage.ts b/desci-server/src/services/PublishPackage.ts index 19ced63d..8901dc7c 100644 --- a/desci-server/src/services/PublishPackage.ts +++ b/desci-server/src/services/PublishPackage.ts @@ -47,19 +47,23 @@ class PublishPackageService { this.logger.error('process.env.ISOLATED_MEDIA_SERVER_URL is not defined'); return null; } + // debugger; const title = manifest.title; - const dpid = manifest.dpid.id; + const demoMode = manifest?.dpid?.id === undefined; + const dpid = !demoMode ? manifest?.dpid?.id : 'UNPUBLISHED_DEMO'; if (dpid === undefined) { this.logger.warn({ dpid, nodeId: node.id }, 'Failed generating a publish package for node, dpid is undefined'); throw new Error('DPID is undefined'); } const license = PublishPackageService.extractManuscriptLicense(manifest, pdfCid); - const publishTime = await publishServices.retrieveBlockTimeByManifestCid(node.uuid, manifestCid); + const publishTime = demoMode + ? Date.now().toString().slice(0, 8) + : await publishServices.retrieveBlockTimeByManifestCid(node.uuid, manifestCid); const publishDate = PublishPackageService.convertUnixTimestampToDate(publishTime); const authors = manifest.authors?.map((author) => author.name); - const attestations = await attestationService.getAllNodeAttestations(dpid); + const attestations = await attestationService.getAllNodeAttestations(node.uuid); const openCodeAttestation = attestations.find((a) => a.attestationId === 15); const openDataAttestation = attestations.find((a) => a.attestationId === 16); From f75040c39bf511b69e41f30de37c02545d089705 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Wed, 19 Jun 2024 19:42:13 +0200 Subject: [PATCH 159/278] fix claim attestation --- desci-server/src/services/Attestation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desci-server/src/services/Attestation.ts b/desci-server/src/services/Attestation.ts index 5e8604d6..8bb73734 100644 --- a/desci-server/src/services/Attestation.ts +++ b/desci-server/src/services/Attestation.ts @@ -83,7 +83,7 @@ export class AttestationService { attestationId, attestationVersionId: attestationVersionEntry.id, desciCommunityId: attestationVersionEntry.attestation.communityId, - nodeDpid10: nodeDpid, + nodeUuid: nodeUuid, nodeVersion, }, }); From 078afb2572c3d94667733ce8df80d74ab8a71869 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Wed, 19 Jun 2024 18:59:14 +0000 Subject: [PATCH 160/278] change attestation badge hyperlinks for new routing --- desci-server/src/services/PublishPackage.ts | 7 ++++--- desci-server/src/utils.ts | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/desci-server/src/services/PublishPackage.ts b/desci-server/src/services/PublishPackage.ts index 8901dc7c..12c32397 100644 --- a/desci-server/src/services/PublishPackage.ts +++ b/desci-server/src/services/PublishPackage.ts @@ -4,7 +4,7 @@ import axios from 'axios'; import { prisma } from '../client.js'; import { logger as parentLogger } from '../logger.js'; -import { ensureUuidEndsWithDot } from '../utils.js'; +import { ensureUuidEndsWithDot, toKebabCase } from '../utils.js'; import { attestationService } from './Attestation.js'; import { pinFile } from './ipfs.js'; @@ -70,10 +70,10 @@ class PublishPackageService { const attestationLinks = { ...(openCodeAttestation && { - codeAvailableDpid: `https://beta.dpid.org/${dpid}/attestations/${openCodeAttestation.id}`, + codeAvailableDpid: `https://beta.dpid.org/${dpid}/attestations/${toKebabCase(openCodeAttestation.attestationVersion.name)}`, }), ...(openDataAttestation && { - dataAvailableDpid: `https://beta.dpid.org/${dpid}/attestations/${openDataAttestation.id}`, + dataAvailableDpid: `https://beta.dpid.org/${dpid}/attestations/${toKebabCase(openDataAttestation.attestationVersion.name)}`, }), }; @@ -100,6 +100,7 @@ class PublishPackageService { } static convertUnixTimestampToDate(unixTimestamp: string): string { + debugger const date = new Date(Number(unixTimestamp) * 1000); const formattedDate = date.toLocaleString('en-US', { month: 'long', diff --git a/desci-server/src/utils.ts b/desci-server/src/utils.ts index 75fb8002..87f12168 100644 --- a/desci-server/src/utils.ts +++ b/desci-server/src/utils.ts @@ -256,3 +256,18 @@ export function formatOrcidString(orcidId: string): string { return formattedOrcid; } + +export function toKebabCase(name: string) { + const lowercaseName = name.toLowerCase(); + + // Replace spaces, underscores, and dashes with a single dash + const dashedName = lowercaseName.replace(/[\s_-]+/g, '-'); + + // Remove any non-alphanumeric characters except dashes + const urlSafeName = dashedName.replace(/[^a-z0-9-]/g, ''); + + // Remove any leading or trailing dashes + const trimmedName = urlSafeName.replace(/^-+|-+$/g, ''); + + return trimmedName; +} From f003be80d51a20d7f0969f9e4a9a34ada185e46c Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Wed, 19 Jun 2024 19:04:17 +0000 Subject: [PATCH 161/278] adjust all instances of localhost check usage to also test for host.docker.internal --- desci-server/src/controllers/nodes/createDpid.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/desci-server/src/controllers/nodes/createDpid.ts b/desci-server/src/controllers/nodes/createDpid.ts index e5ec6d61..5811227c 100644 --- a/desci-server/src/controllers/nodes/createDpid.ts +++ b/desci-server/src/controllers/nodes/createDpid.ts @@ -106,7 +106,9 @@ export const getOrCreateDpid = async (streamId: string): Promise => { await provider.ready; const wallet = new ethers.Wallet( - apiServerUrl.includes('localhost') ? GANACHE_PKEY : process.env.HOT_WALLET_KEY, + apiServerUrl.includes('localhost') || apiServerUrl.includes('host.docker.internal') + ? GANACHE_PKEY + : process.env.HOT_WALLET_KEY, provider, ); @@ -157,7 +159,9 @@ export const upgradeDpid = async (dpid: number, ceramicStream: string): Promise< await provider.ready; const wallet = new ethers.Wallet( - apiServerUrl.includes('localhost') ? GANACHE_PKEY : process.env.REGISTRY_OWNER_PKEY, + apiServerUrl.includes('localhost') || apiServerUrl.includes('host.docker.internal') + ? GANACHE_PKEY + : process.env.REGISTRY_OWNER_PKEY, provider, ); From 2bb2bf798cab09d3d5b8f8bf0eeff4a8b413713f Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Thu, 20 Jun 2024 01:56:36 +0200 Subject: [PATCH 162/278] feat: implement am client --- .../src/services/AutomatedMetadata.ts | 145 ++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 desci-server/src/services/AutomatedMetadata.ts diff --git a/desci-server/src/services/AutomatedMetadata.ts b/desci-server/src/services/AutomatedMetadata.ts new file mode 100644 index 00000000..da8e319b --- /dev/null +++ b/desci-server/src/services/AutomatedMetadata.ts @@ -0,0 +1,145 @@ +import { logger as parentLogger } from '../logger.js'; +import { ONE_DAY_TTL, getFromCache, setToCache } from '../redisClient.js'; + +const logger = parentLogger.child({ module: '[AutomatedMetadataClient]' }); + +export const delay = async (timeMs: number) => { + return new Promise((resolve) => setTimeout(resolve, timeMs)); +}; + +export type MetadataParam = { + cid?: string; + doi?: string; +}; + +export type AutomatedMetadataResponse = { + output: { + creator: { + [k in string]: { + '@id': string; + affiliation: string; + name: string; + role: string; + }; + }; + datePublished: [number, number, number]; // [year, month, day] + keywords: Array<{ display_name: string; id: string; score: number }>; + license: Array<{ + url: string; + 'content-version': string; + 'delay-in-days': number; + start: { + 'date-parts': Array<[number, number, number]>; + 'date-time': string; + timestamp: number; + }; + }>; + oa_url: string | null; + title: string; + }; +}; + +type MetadataResponse = { + authors: Array<{ orcid: string; name: string; affiliation: string }>; + title: string; + pdfUrl: string | null; + keywords: string[]; +}; + +/** + * A wrapper http client for querying, caching and parsing requests + * from the CrossRef Rest Api https://www.crossref.org/documentation/retrieve-metadata/rest-api/ + * Initialize constructor with CrossRef Api url https://api.crossref.org, Api token and a polite Mail + */ +class AutomatedMetadataClient { + baseurl: string; + + constructor( + baseUrl: string, + private _accessToken: string, + ) { + if (!baseUrl) { + logger.error('Pass Cross ref api as argument to AutomatedMetadataClient'); + throw Error('Pass Cross ref api as argument to AutomatedMetadataClient'); + } + this.baseurl = baseUrl; + } + + /** + * Returns all the metadata associated with a pdf cid or doi url + */ + async getResourceMetadata(query: MetadataParam): Promise { + if (!query.cid && !query.doi) throw new Error('Invalid data'); + + const body: { pdf: string; doi?: string } | { doi: string; pdf?: string } = { pdf: '' }; + + if (query.cid) { + body.pdf = query.cid; + } + + if (query.doi) { + body.doi = query.doi; + } + logger.info(body, 'API INFO'); + + // config.body = body; + + const url = `${this.baseurl}/invoke-script`; + logger.info(url, 'url params'); + const config: RequestInit = { + method: 'POST', + mode: 'cors', + headers: {}, + body: JSON.stringify(body), + }; + + // add plus token if available + if (this._accessToken && config.headers) { + config.headers['X-API-Key'] = `${this._accessToken}`; + } + + const request = new Request(url, config); + try { + const response = await this.performFetch(request, body.doi || body.pdf); + return response ? this.transformResponse(response) : null; + } catch (error) { + logger.error(error, 'ERROR'); + return null; + } + } + + async performFetch(request: Request, cacheKey: string): Promise { + const responseFromCache = await getFromCache(request.url); + logger.info(responseFromCache, 'METADATA From Cache'); + if (responseFromCache) return responseFromCache; + + const response = (await fetch(request)) as Response; + let data: T; + + if (response.ok && response.status === 200) { + if (response.headers.get('content-type')?.includes('application/json')) { + data = (await response.json()) as T; + logger.info(response.ok, 'SET TO CACHE'); + await setToCache(cacheKey, data, ONE_DAY_TTL); + return data; + } + } + return null as T; + } + + transformResponse(data: AutomatedMetadataResponse): MetadataResponse { + const authors = data.output?.creator + ? Object.entries(data.output.creator).map(([name, creator]) => ({ + orcid: creator['@id'], + affiliation: creator.affiliation, + name, + })) + : []; + const keywords = data.output?.keywords ? data.output.keywords.map((keyword) => keyword.display_name) : []; + const metadata: MetadataResponse = { authors, keywords, title: data.output.title, pdfUrl: data.output.oa_url }; + logger.info(metadata, 'METADATA'); + return metadata; + } +} + +export default AutomatedMetadataClient; From 84faecc91c8a7007ae05c392be5c8570206f4ed1 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Thu, 20 Jun 2024 04:43:48 +0200 Subject: [PATCH 163/278] use existing key --- desci-repo/src/middleware/permissions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desci-repo/src/middleware/permissions.ts b/desci-repo/src/middleware/permissions.ts index 87cce971..553ea5fa 100644 --- a/desci-repo/src/middleware/permissions.ts +++ b/desci-repo/src/middleware/permissions.ts @@ -33,7 +33,7 @@ const AUTH_COOKIE_DOMAIN_MAPPING = { // auth, auth-stage, auth-dev export const AUTH_COOKIE_FIELDNAME = - AUTH_COOKIE_DOMAIN_MAPPING[process.env.DESCI_SERVER_URL || 'https://nodes-api.desci.com'] || 'auth'; + AUTH_COOKIE_DOMAIN_MAPPING[process.env.SERVER_URL || 'https://nodes-api.desci.com'] || 'auth'; /** * Extract JWT Authorisation token from IncommingRequest From 598dbc6390648eaf4ac4e71a0637a36c327c9ba3 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Thu, 20 Jun 2024 06:17:28 +0200 Subject: [PATCH 164/278] feat: integrate automated metadata client into prepublication upload routes --- .env.example | 4 ++ .env.test | 6 ++- desci-models/package.json | 2 +- desci-models/src/automerge.ts | 1 + desci-repo/package.json | 4 +- desci-repo/src/services/manifestRepo.ts | 9 ++++ desci-repo/src/validators/schema.ts | 3 +- desci-repo/yarn.lock | 37 ++----------- desci-server/package.json | 2 +- desci-server/src/controllers/data/update.ts | 39 +++++++++++++- .../src/controllers/data/updateExternalCid.ts | 52 ++++++++++++------- desci-server/src/controllers/data/utils.ts | 20 ++++++- .../src/services/AutomatedMetadata.ts | 43 +++++++++++++-- .../services/data/externalCidProcessing.ts | 8 ++- desci-server/src/services/index.ts | 5 ++ desci-server/src/types/ProcessEnv.d.ts | 2 + desci-server/yarn.lock | 2 +- 17 files changed, 169 insertions(+), 70 deletions(-) diff --git a/.env.example b/.env.example index 89866b5d..c1beb2d7 100755 --- a/.env.example +++ b/.env.example @@ -131,3 +131,7 @@ DOI_PREFIX=https://doi.org/10.62891 CROSSREF_API=https://api.crossref.org CROSSREF_API_KEY= CROSSREF_EMAIL= + +# Automated metadata +AUTOMATED_METADATA_API= +AUTOMATED_METADATA_API_KEY= \ No newline at end of file diff --git a/.env.test b/.env.test index 8e78ffe8..1a38ecaa 100644 --- a/.env.test +++ b/.env.test @@ -79,4 +79,8 @@ DOI_PREFIX=https://doi.org/10.62891 # Cross ref api CROSSREF_API=https://api.crossref.org CROSSREF_API_KEY= -CROSSREF_EMAIL= \ No newline at end of file +CROSSREF_EMAIL= + +# Automated metadata +AUTOMATED_METADATA_API= +AUTOMATED_METADATA_API_KEY= \ No newline at end of file diff --git a/desci-models/package.json b/desci-models/package.json index 354f6b9f..7026b8aa 100644 --- a/desci-models/package.json +++ b/desci-models/package.json @@ -1,6 +1,6 @@ { "name": "@desci-labs/desci-models", - "version": "0.2.7-rc5", + "version": "0.2.7-rc6", "description": "Data models for DeSci Nodes", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/desci-models/src/automerge.ts b/desci-models/src/automerge.ts index f0e91e14..924bc903 100644 --- a/desci-models/src/automerge.ts +++ b/desci-models/src/automerge.ts @@ -39,6 +39,7 @@ export type ManifestActions = | { type: 'Upsert Components'; components: ResearchObjectV1Component[] } | { type: 'Delete Component'; path: string } | { type: 'Add Contributor'; author: ResearchObjectV1Author } + | { type: 'Add Contributors'; contributors: ResearchObjectV1Author[] } | { type: 'Remove Contributor'; contributorIndex: number } | { type: 'Pin Component'; path: string } | { type: 'UnPin Component'; path: string } diff --git a/desci-repo/package.json b/desci-repo/package.json index 3d5bd7bc..c6627425 100644 --- a/desci-repo/package.json +++ b/desci-repo/package.json @@ -68,7 +68,7 @@ "typescript": "5.1.6" }, "dependencies": { - "@desci-labs/desci-models": "0.2.7-rc3", + "@desci-labs/desci-models": "file:../desci-models", "@sentry/node": "^7.84.0", "@sentry/tracing": "^7.84.0", "axios": "^1.6.2", @@ -87,4 +87,4 @@ "ws": "^8.14.2", "zod": "^3.22.4" } -} \ No newline at end of file +} diff --git a/desci-repo/src/services/manifestRepo.ts b/desci-repo/src/services/manifestRepo.ts index 72d8a361..de883cdb 100644 --- a/desci-repo/src/services/manifestRepo.ts +++ b/desci-repo/src/services/manifestRepo.ts @@ -281,6 +281,15 @@ export const getDocumentUpdater = (documentId: DocumentId) => { { time: Date.now(), message: action.type }, ); break; + case 'Add Contributors': + handle.change( + (document) => { + if (!document.manifest.authors) document.manifest.authors = []; + document.manifest.authors?.push(...action.contributors); + }, + { time: Date.now(), message: action.type }, + ); + break; case 'Update CoverImage': handle.change( (document) => { diff --git a/desci-repo/src/validators/schema.ts b/desci-repo/src/validators/schema.ts index e8052883..dac1fe4f 100644 --- a/desci-repo/src/validators/schema.ts +++ b/desci-repo/src/validators/schema.ts @@ -65,7 +65,7 @@ type Action = ManifestActions["type"]; export const actionsSchema = z.array( z.discriminatedUnion('type', [ z.object({ type: z.literal('Publish Dpid'), dpid: dpid }), - z.object({ type: z.literal('Remove Dpid')}), + z.object({ type: z.literal('Remove Dpid') }), z.object({ type: z.literal('Update Title'), title: z.string() }), z.object({ type: z.literal('Update Description'), description: z.string() }), z.object({ type: z.literal('Update License'), defaultLicense: z.string() }), @@ -74,6 +74,7 @@ export const actionsSchema = z.array( z.object({ type: z.literal('Delete Component'), path: z.string() }), z.object({ type: z.literal('Update Component'), component: componentSchema }), z.object({ type: z.literal('Add Contributor'), author: contributor }), + z.object({ type: z.literal('Add Contributors'), contributors: z.array(contributor) }), z.object({ type: z.literal('Remove Contributor'), contributorIndex: z.number() }), z.object({ type: z.literal('Pin Component'), componentIndex: z.number() }), z.object({ type: z.literal('UnPin Component'), componentIndex: z.number() }), diff --git a/desci-repo/yarn.lock b/desci-repo/yarn.lock index a87fb260..039088e3 100644 --- a/desci-repo/yarn.lock +++ b/desci-repo/yarn.lock @@ -131,10 +131,8 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@desci-labs/desci-models@0.2.7-rc3": - version "0.2.7-rc3" - resolved "https://registry.yarnpkg.com/@desci-labs/desci-models/-/desci-models-0.2.7-rc3.tgz#b033073e6b77edde85491731d5c03469f443aaa1" - integrity sha512-RL1vwUHTumpmj7goX6+AcSVt0MGpdm4QWZ20gkmE9+BlL1eIxX+oQzQFmW92XXHWUQOETIaL1YnHsGCVz4gJNw== +"@desci-labs/desci-models@file:../desci-models": + version "0.2.7-rc6" dependencies: jsonld "^8.1.1" schema-dts "^1.1.2" @@ -3920,16 +3918,7 @@ string-argv@0.3.1: resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz" integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.1.0, string-width@^4.2.0: +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -3999,14 +3988,7 @@ stringify-object@^3.3.0: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -4401,7 +4383,7 @@ workerpool@6.2.1: resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz" integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -4419,15 +4401,6 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz" diff --git a/desci-server/package.json b/desci-server/package.json index d30ffece..30a98e4f 100755 --- a/desci-server/package.json +++ b/desci-server/package.json @@ -57,7 +57,7 @@ "@aws-sdk/client-s3": "^3.537.0", "@desci-labs/desci-codex-lib": "^1.1.7", "@desci-labs/desci-contracts": "0.2.5-rc7", - "@desci-labs/desci-models": "0.2.7-rc5", + "@desci-labs/desci-models": "^0.2.7-rc5", "@honeycombio/opentelemetry-node": "^0.3.2", "@ipld/dag-pb": "^4.0.0", "@opentelemetry/api": "^1.8.0", diff --git a/desci-server/src/controllers/data/update.ts b/desci-server/src/controllers/data/update.ts index c7491808..aaffb91b 100644 --- a/desci-server/src/controllers/data/update.ts +++ b/desci-server/src/controllers/data/update.ts @@ -2,11 +2,15 @@ import { ResearchObjectV1, DriveObject } from '@desci-labs/desci-models'; import { Response } from 'express'; import { prisma } from '../../client.js'; +import { metadataClient } from '../../internal.js'; import { logger as parentLogger } from '../../logger.js'; import { RequestWithNode } from '../../middleware/authorisation.js'; +import { MetadataResponse } from '../../services/AutomatedMetadata.js'; import { processExternalUrlDataToIpfs } from '../../services/data/externalUrlProcessing.js'; import { processNewFolder, processS3DataToIpfs } from '../../services/data/processing.js'; import { arrayXor, ensureUuidEndsWithDot } from '../../utils.js'; + +import { isDoiLink } from './utils.js'; export interface UpdateResponse { status?: number; rootDataCid?: string; @@ -24,7 +28,15 @@ export interface ErrorResponse { export const update = async (req: RequestWithNode, res: Response) => { const owner = req.user; let node = req.node; - const { uuid, manifest: draftManifest, componentType, componentSubtype, newFolderName, autoStar } = req.body; + const { + uuid, + manifest: draftManifest, + componentType, + componentSubtype, + newFolderName, + autoStar, + prepublication, + } = req.body; let { contextPath } = req.body; // debugger; if (contextPath.endsWith('/')) contextPath = contextPath.slice(0, -1); @@ -105,6 +117,18 @@ export const update = async (req: RequestWithNode, res: Response, - res: Response + res: Response, ) => { const owner = (req as any).user as User; - const { - uuid, - contextPath, - externalCids, - componentType, - componentSubtype - } = req.body; + const { uuid, contextPath, externalCids, componentType, componentSubtype, prepublication } = req.body; const logger = parentLogger.child({ // id: req.id, @@ -73,7 +77,7 @@ export const updateExternalCid = async ( externalCids, contextPath, componentType, - componentSubtype + componentSubtype, }); if (ok) { @@ -83,6 +87,18 @@ export const updateExternalCid = async ( tree: tree, date: date, } = value as UpdateResponse; + + if (prepublication) { + // pre-cache automated metadata response + const metadata = await metadataClient.getResourceMetadata({ cid: externalCids[0].cid }); + + if (metadata) { + await metadataClient.automateMetadata(metadata, { + uuid: node.uuid, + documentId: node.manifestDocumentId as DocumentId, + }); + } + } return res.status(200).json({ manifest: updatedManifest, manifestCid: persistedManifestCid, diff --git a/desci-server/src/controllers/data/utils.ts b/desci-server/src/controllers/data/utils.ts index b35c411a..ac1bba40 100644 --- a/desci-server/src/controllers/data/utils.ts +++ b/desci-server/src/controllers/data/utils.ts @@ -1,4 +1,9 @@ -import { DRIVE_NODE_ROOT_PATH, DataComponent, ResearchObjectComponentType, ResearchObjectV1 } from '@desci-labs/desci-models'; +import { + DRIVE_NODE_ROOT_PATH, + DataComponent, + ResearchObjectComponentType, + ResearchObjectV1, +} from '@desci-labs/desci-models'; import { Node } from '@prisma/client'; import axios from 'axios'; import { v4 as uuid } from 'uuid'; @@ -30,7 +35,7 @@ function addDataToManifest({ manifest, dataFields, rootCid }: UpdatingManifestPa cid: rootCid, subMetadata: {}, description: dataFields.description || undefined, - path: DRIVE_NODE_ROOT_PATH + `/${dataFields.title}` + path: DRIVE_NODE_ROOT_PATH + `/${dataFields.title}`, }, }; manifest.components.push(newDataComponent); @@ -102,3 +107,14 @@ export function separateFileNameAndExtension(fileName: string): { const name = splitName.join('.'); return { fileName: name, extension }; } + +export const DOI_REGEX = /(https:\/\/doi.org\/)?(?10.\d{4,9}\/[-._;()/:A-Z0-9]+$)/i; +export function isDoiLink(url: string): boolean { + try { + const matches = url.match(DOI_REGEX); + console.log('matches', matches); + return DOI_REGEX.test(url); + } catch (e) { + return false; + } +} diff --git a/desci-server/src/services/AutomatedMetadata.ts b/desci-server/src/services/AutomatedMetadata.ts index da8e319b..c2e57c9b 100644 --- a/desci-server/src/services/AutomatedMetadata.ts +++ b/desci-server/src/services/AutomatedMetadata.ts @@ -1,6 +1,11 @@ +import { DocumentId } from '@automerge/automerge-repo'; +import { ManifestActions, ResearchObjectV1Author, ResearchObjectV1AuthorRole } from '@desci-labs/desci-models'; + import { logger as parentLogger } from '../logger.js'; import { ONE_DAY_TTL, getFromCache, setToCache } from '../redisClient.js'; +import repoService from './repoService.js'; + const logger = parentLogger.child({ module: '[AutomatedMetadataClient]' }); export const delay = async (timeMs: number) => { @@ -39,7 +44,7 @@ export type AutomatedMetadataResponse = { }; }; -type MetadataResponse = { +export type MetadataResponse = { authors: Array<{ orcid: string; name: string; affiliation: string }>; title: string; pdfUrl: string | null; @@ -51,7 +56,7 @@ type MetadataResponse = { * from the CrossRef Rest Api https://www.crossref.org/documentation/retrieve-metadata/rest-api/ * Initialize constructor with CrossRef Api url https://api.crossref.org, Api token and a polite Mail */ -class AutomatedMetadataClient { +export class AutomatedMetadataClient { baseurl: string; constructor( @@ -119,7 +124,7 @@ class AutomatedMetadataClient { if (response.ok && response.status === 200) { if (response.headers.get('content-type')?.includes('application/json')) { data = (await response.json()) as T; - logger.info(response.ok, 'SET TO CACHE'); + logger.info(data, 'SET TO CACHE'); await setToCache(cacheKey, data, ONE_DAY_TTL); return data; } @@ -140,6 +145,34 @@ class AutomatedMetadataClient { logger.info(metadata, 'METADATA'); return metadata; } -} -export default AutomatedMetadataClient; + async automateMetadata(metadata: MetadataResponse, node: { uuid: string; documentId: string }) { + const actions: ManifestActions[] = []; + if (metadata.title) { + actions.push({ type: 'Update Title', title: metadata.title }); + } + + if (metadata.authors) { + actions.push({ + type: 'Add Contributors', + contributors: metadata.authors.map( + (author) => + ({ + name: author.name, + orcid: author.orcid, + role: ResearchObjectV1AuthorRole.AUTHOR, + organisations: [{ id: author.affiliation, name: author.affiliation }], + }) as ResearchObjectV1Author, + ), + }); // + } + + const response = await repoService.dispatchAction({ + uuid: node.uuid, + documentId: node.documentId as DocumentId, + actions, + }); + logger.info(response, 'AUTOMATE METADATA'); + return response; + } +} diff --git a/desci-server/src/services/data/externalCidProcessing.ts b/desci-server/src/services/data/externalCidProcessing.ts index 8d88a049..d5c1c994 100644 --- a/desci-server/src/services/data/externalCidProcessing.ts +++ b/desci-server/src/services/data/externalCidProcessing.ts @@ -9,6 +9,7 @@ import { import { User, Node, Prisma } from '@prisma/client'; import { prisma } from '../../client.js'; +import { ExternalCid } from '../../controllers/data/updateExternalCid.js'; import { persistManifest } from '../../controllers/data/utils.js'; import { logger as parentLogger } from '../../logger.js'; import { ensureUniquePathsDraftTree, getLatestDriveTime } from '../../services/draftTrees.js'; @@ -28,7 +29,6 @@ import { createManifestPersistFailError, createUnhandledError, } from './processingErrors.js'; -import { ExternalCid } from '../../controllers/data/updateExternalCid.js'; const logger = parentLogger.child({ module: 'Services::ExternalCidProcessing', @@ -48,7 +48,7 @@ interface ProcessExternalCidDataToIpfsParams { /** * Processes external CIDs, to pin the file or leafless UnixFS DAG. -*/ + */ export async function processExternalCidDataToIpfs({ externalCids, user, @@ -63,9 +63,7 @@ export async function processExternalCidDataToIpfs({ */ const cidTypesSizes: Record = {}; try { - externalCids = externalCids.map( - (extCid) => ({ ...extCid, cid: convertToCidV1(extCid.cid) }) - ); + externalCids = externalCids.map((extCid) => ({ ...extCid, cid: convertToCidV1(extCid.cid) })); for (const extCid of externalCids) { const { isDirectory, size } = await getExternalCidSizeAndType(extCid.cid); if (size !== undefined && isDirectory !== undefined) { diff --git a/desci-server/src/services/index.ts b/desci-server/src/services/index.ts index 28aceb35..d751bd94 100644 --- a/desci-server/src/services/index.ts +++ b/desci-server/src/services/index.ts @@ -1,5 +1,6 @@ import { prisma } from '../client.js'; +import { AutomatedMetadataClient } from './AutomatedMetadata.js'; import CrossRefClient from './crossRef/client.js'; import { DoiService } from './Doi.js'; @@ -9,3 +10,7 @@ export const crossRefClient = new CrossRefClient( '', // process.env.CROSSREF_API_KEY, process.env.CROSSREF_EMAIL, ); +export const metadataClient = new AutomatedMetadataClient( + process.env.AUTOMATED_METADATA_API, + process.env.AUTOMATED_METADATA_API_KEY, +); diff --git a/desci-server/src/types/ProcessEnv.d.ts b/desci-server/src/types/ProcessEnv.d.ts index b7bbcda1..cb5c8da9 100755 --- a/desci-server/src/types/ProcessEnv.d.ts +++ b/desci-server/src/types/ProcessEnv.d.ts @@ -13,5 +13,7 @@ declare namespace NodeJS { CROSSREF_API: string; CROSSREF_EMAIL: string; CROSSREF_API_KEY: string; + AUTOMATED_METADATA_API: string; + AUTOMATED_METADATA_API_KEY: string; } } diff --git a/desci-server/yarn.lock b/desci-server/yarn.lock index f0a507ed..d1564b9f 100644 --- a/desci-server/yarn.lock +++ b/desci-server/yarn.lock @@ -2210,7 +2210,7 @@ resolved "https://registry.yarnpkg.com/@desci-labs/desci-contracts/-/desci-contracts-0.2.5-rc7.tgz#a8a49c9518107305be712bcbdbb352faa4057a44" integrity sha512-W1hf+mv5KWnqCuXX3uBiBsll+iMD82GJbsGs3huzH6qY2TySVFUCLov017B0RGz2Ap1WRB9w7h3o9CEwDuV5lQ== -"@desci-labs/desci-models@0.2.7-rc5": +"@desci-labs/desci-models@^0.2.7-rc5": version "0.2.7-rc5" resolved "https://registry.yarnpkg.com/@desci-labs/desci-models/-/desci-models-0.2.7-rc5.tgz#fec8cd3372eaa22fd727d87fa8967a7c093e6d5f" integrity sha512-mA3rpgaWfDAxO6BXejijP+mvmzvVTHPQ/vEyWkzeZ/V8DGUHzcScYAa6W5RD5mWRmFIAXGAg/zQuwaxw7PaOSg== From 4112943655a85666d5cde013aa9c3ac460a1ac2b Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Thu, 20 Jun 2024 06:34:26 +0200 Subject: [PATCH 165/278] upgrade node version to 22 --- .nvmrc | 2 +- Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.nvmrc b/.nvmrc index 23cc58a7..a1e47e58 100755 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -18.20.0 \ No newline at end of file +22.0.0 \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 4ae02c58..e2a9eb47 100755 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18.20.0-bullseye +FROM node:22.0.0-bullseye VOLUME /root/.yarn From e5cd5dfa3c94d011b6c168ff33672bdf00cee80b Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Thu, 20 Jun 2024 06:46:37 +0200 Subject: [PATCH 166/278] feat: add support for multiple contributors to automerge repo service, upgrade desci-models --- desci-models/package.json | 2 +- desci-models/src/automerge.ts | 1 + desci-repo/src/services/manifestRepo.ts | 9 +++++++++ desci-repo/src/validators/schema.ts | 3 ++- desci-repo/src/validators/test/schema.spec.ts | 10 ++++++++-- 5 files changed, 21 insertions(+), 4 deletions(-) diff --git a/desci-models/package.json b/desci-models/package.json index 354f6b9f..7026b8aa 100644 --- a/desci-models/package.json +++ b/desci-models/package.json @@ -1,6 +1,6 @@ { "name": "@desci-labs/desci-models", - "version": "0.2.7-rc5", + "version": "0.2.7-rc6", "description": "Data models for DeSci Nodes", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/desci-models/src/automerge.ts b/desci-models/src/automerge.ts index f0e91e14..e0d03e55 100644 --- a/desci-models/src/automerge.ts +++ b/desci-models/src/automerge.ts @@ -40,6 +40,7 @@ export type ManifestActions = | { type: 'Delete Component'; path: string } | { type: 'Add Contributor'; author: ResearchObjectV1Author } | { type: 'Remove Contributor'; contributorIndex: number } + | { type: 'Add Contributors'; contributors: ResearchObjectV1Author[] } | { type: 'Pin Component'; path: string } | { type: 'UnPin Component'; path: string } | { diff --git a/desci-repo/src/services/manifestRepo.ts b/desci-repo/src/services/manifestRepo.ts index 72d8a361..de883cdb 100644 --- a/desci-repo/src/services/manifestRepo.ts +++ b/desci-repo/src/services/manifestRepo.ts @@ -281,6 +281,15 @@ export const getDocumentUpdater = (documentId: DocumentId) => { { time: Date.now(), message: action.type }, ); break; + case 'Add Contributors': + handle.change( + (document) => { + if (!document.manifest.authors) document.manifest.authors = []; + document.manifest.authors?.push(...action.contributors); + }, + { time: Date.now(), message: action.type }, + ); + break; case 'Update CoverImage': handle.change( (document) => { diff --git a/desci-repo/src/validators/schema.ts b/desci-repo/src/validators/schema.ts index e8052883..dac1fe4f 100644 --- a/desci-repo/src/validators/schema.ts +++ b/desci-repo/src/validators/schema.ts @@ -65,7 +65,7 @@ type Action = ManifestActions["type"]; export const actionsSchema = z.array( z.discriminatedUnion('type', [ z.object({ type: z.literal('Publish Dpid'), dpid: dpid }), - z.object({ type: z.literal('Remove Dpid')}), + z.object({ type: z.literal('Remove Dpid') }), z.object({ type: z.literal('Update Title'), title: z.string() }), z.object({ type: z.literal('Update Description'), description: z.string() }), z.object({ type: z.literal('Update License'), defaultLicense: z.string() }), @@ -74,6 +74,7 @@ export const actionsSchema = z.array( z.object({ type: z.literal('Delete Component'), path: z.string() }), z.object({ type: z.literal('Update Component'), component: componentSchema }), z.object({ type: z.literal('Add Contributor'), author: contributor }), + z.object({ type: z.literal('Add Contributors'), contributors: z.array(contributor) }), z.object({ type: z.literal('Remove Contributor'), contributorIndex: z.number() }), z.object({ type: z.literal('Pin Component'), componentIndex: z.number() }), z.object({ type: z.literal('UnPin Component'), componentIndex: z.number() }), diff --git a/desci-repo/src/validators/test/schema.spec.ts b/desci-repo/src/validators/test/schema.spec.ts index 58ea7a8a..26a0cda0 100644 --- a/desci-repo/src/validators/test/schema.spec.ts +++ b/desci-repo/src/validators/test/schema.spec.ts @@ -136,7 +136,7 @@ describe('ManifestActions Schema', () => { payload: { path: 'root/external links/', cid: 'bafybeicrsddlvfbbo5s3upvjbtb5flc73iupxfy2kf3rv43kkbvegbqbwq', - language: 'typescript' + language: 'typescript', }, }; @@ -188,7 +188,7 @@ describe('ManifestActions Schema', () => { payload: { path: 'root/external links/', cid: 'bafybeicrsddlvfbbo5s3upvjbtb5flc73iupxfy2kf3rv43kkbvegbqbwq', - language: 'typescript' + language: 'typescript', }, }; @@ -232,6 +232,12 @@ describe('ManifestActions Schema', () => { expect(validated.success).to.be.true; }); + it('should validate Add Contributors', async () => { + const validated = await actionsSchema.safeParseAsync([{ type: 'Add Contributors', contributors: [author] }]); + console.log(validated.success ? validated.data : validated.error); + expect(validated.success).to.be.true; + }); + it('should validate Remove Contributor', async () => { const validated = await actionsSchema.safeParseAsync([{ type: 'Remove Contributor', contributorIndex: 0 }]); console.log(validated.success ? validated.data : validated.error); From 706940369a7186e5a41659bda37940e049bc13aa Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Thu, 20 Jun 2024 07:53:32 +0200 Subject: [PATCH 167/278] add paging to /nodes collection list call --- desci-server/src/controllers/nodes/list.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/desci-server/src/controllers/nodes/list.ts b/desci-server/src/controllers/nodes/list.ts index 34aa0069..0f4ac403 100755 --- a/desci-server/src/controllers/nodes/list.ts +++ b/desci-server/src/controllers/nodes/list.ts @@ -18,6 +18,10 @@ export const list = async (req: Request, res: Response, next: NextFunction) => { const owner = (req as any).user; const ipfsQuery = req.query.g; + // implement paging + const page = req.query.page || 1; + const limit = req.query.limit || 20; + logger.info({ body: req.body, user: (req as any).user, @@ -41,6 +45,8 @@ export const list = async (req: Request, res: Response, next: NextFunction) => { isDeleted: false, }, orderBy: { updatedAt: 'desc' }, + limit: limit, + skip: (page - 1) * limit, }); // transition UUID From 59cc29eec3f1bb63963a0fd0c93a40140d39a073 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Thu, 20 Jun 2024 08:56:04 +0200 Subject: [PATCH 168/278] fix paging --- desci-server/src/controllers/nodes/list.ts | 6 +++--- desci-server/src/services/Attestation.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/desci-server/src/controllers/nodes/list.ts b/desci-server/src/controllers/nodes/list.ts index 0f4ac403..340ed7b7 100755 --- a/desci-server/src/controllers/nodes/list.ts +++ b/desci-server/src/controllers/nodes/list.ts @@ -19,8 +19,8 @@ export const list = async (req: Request, res: Response, next: NextFunction) => { const ipfsQuery = req.query.g; // implement paging - const page = req.query.page || 1; - const limit = req.query.limit || 20; + const page: number = req.query.page ? parseInt(req.query.page as string) : 1; + const limit: number = req.query.limit ? parseInt(req.query.limit as string) : 20; logger.info({ body: req.body, @@ -45,7 +45,7 @@ export const list = async (req: Request, res: Response, next: NextFunction) => { isDeleted: false, }, orderBy: { updatedAt: 'desc' }, - limit: limit, + take: limit, skip: (page - 1) * limit, }); diff --git a/desci-server/src/services/Attestation.ts b/desci-server/src/services/Attestation.ts index 8bb73734..60352229 100644 --- a/desci-server/src/services/Attestation.ts +++ b/desci-server/src/services/Attestation.ts @@ -83,7 +83,7 @@ export class AttestationService { attestationId, attestationVersionId: attestationVersionEntry.id, desciCommunityId: attestationVersionEntry.attestation.communityId, - nodeUuid: nodeUuid, + nodeUuid, nodeVersion, }, }); From 5c695eb7efa538d609602e5ac6498d34c1213551 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Thu, 20 Jun 2024 09:46:13 +0200 Subject: [PATCH 169/278] disable paging until app issues resolved --- desci-server/src/controllers/nodes/list.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/desci-server/src/controllers/nodes/list.ts b/desci-server/src/controllers/nodes/list.ts index 340ed7b7..f84cfc15 100755 --- a/desci-server/src/controllers/nodes/list.ts +++ b/desci-server/src/controllers/nodes/list.ts @@ -45,8 +45,8 @@ export const list = async (req: Request, res: Response, next: NextFunction) => { isDeleted: false, }, orderBy: { updatedAt: 'desc' }, - take: limit, - skip: (page - 1) * limit, + // take: limit, + // skip: (page - 1) * limit, }); // transition UUID From 89dc59f009bb8e15a996f3d9fe72be8147adcfcb Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Thu, 20 Jun 2024 10:40:29 +0000 Subject: [PATCH 170/278] publish package attestation targetting adjustment, using string match instead --- desci-server/src/services/PublishPackage.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/desci-server/src/services/PublishPackage.ts b/desci-server/src/services/PublishPackage.ts index 12c32397..35ec494c 100644 --- a/desci-server/src/services/PublishPackage.ts +++ b/desci-server/src/services/PublishPackage.ts @@ -65,8 +65,8 @@ class PublishPackageService { const attestations = await attestationService.getAllNodeAttestations(node.uuid); - const openCodeAttestation = attestations.find((a) => a.attestationId === 15); - const openDataAttestation = attestations.find((a) => a.attestationId === 16); + const openCodeAttestation = attestations.find((a) => a.attestationVersion.name === 'Open Code'); + const openDataAttestation = attestations.find((a) => a.attestationVersion.name === 'Open Data'); const attestationLinks = { ...(openCodeAttestation && { @@ -100,7 +100,7 @@ class PublishPackageService { } static convertUnixTimestampToDate(unixTimestamp: string): string { - debugger + debugger; const date = new Date(Number(unixTimestamp) * 1000); const formattedDate = date.toLocaleString('en-US', { month: 'long', From 14f4c611dada16637e216a6b7ea7c23415b679b8 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Thu, 20 Jun 2024 16:18:51 +0200 Subject: [PATCH 171/278] implement routes for generating and automating metadata, db migration and upgrade, upgrade node version to 20, update ipfs import script to install neded commands --- .nvmrc | 2 +- Dockerfile | 2 +- desci-repo/package.json | 4 +- desci-repo/yarn.lock | 4 +- desci-server/package.json | 2 +- desci-server/prisma/schema.prisma | 1 + desci-server/scripts/import-ipfs-content.sh | 12 ++++ desci-server/src/controllers/data/update.ts | 37 +---------- .../src/controllers/data/updateExternalCid.ts | 25 +------- desci-server/src/controllers/nodes/index.ts | 1 + .../src/controllers/nodes/metadata.ts | 61 +++++++++++++++++++ desci-server/src/routes/v1/nodes.ts | 12 +++- .../src/services/AutomatedMetadata.ts | 28 +++++---- desci-server/src/services/index.ts | 3 +- desci-server/yarn.lock | 8 +-- 15 files changed, 119 insertions(+), 83 deletions(-) create mode 100644 desci-server/src/controllers/nodes/metadata.ts diff --git a/.nvmrc b/.nvmrc index a1e47e58..5bacb9a1 100755 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -22.0.0 \ No newline at end of file +20.8.1 \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index e2a9eb47..6e2e5331 100755 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:22.0.0-bullseye +FROM node:20.8.1-bullseye-slim VOLUME /root/.yarn diff --git a/desci-repo/package.json b/desci-repo/package.json index c6627425..2986927f 100644 --- a/desci-repo/package.json +++ b/desci-repo/package.json @@ -68,7 +68,7 @@ "typescript": "5.1.6" }, "dependencies": { - "@desci-labs/desci-models": "file:../desci-models", + "@desci-labs/desci-models": "0.2.7-rc6", "@sentry/node": "^7.84.0", "@sentry/tracing": "^7.84.0", "axios": "^1.6.2", @@ -87,4 +87,4 @@ "ws": "^8.14.2", "zod": "^3.22.4" } -} +} \ No newline at end of file diff --git a/desci-repo/yarn.lock b/desci-repo/yarn.lock index 039088e3..24f76740 100644 --- a/desci-repo/yarn.lock +++ b/desci-repo/yarn.lock @@ -131,8 +131,10 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@desci-labs/desci-models@file:../desci-models": +"@desci-labs/desci-models@0.2.7-rc6": version "0.2.7-rc6" + resolved "https://registry.yarnpkg.com/@desci-labs/desci-models/-/desci-models-0.2.7-rc6.tgz#f7f7fed6dc6acda3a90650d1977fa3acb4c2a2a4" + integrity sha512-A1eWbHJqbs9YEnsJzOzgRdoCpsBzlYa4yacXApBmZmVHk6EwqtMJRjwAsQ0/YIQcLbyYCptSenPXhOSlw4FESw== dependencies: jsonld "^8.1.1" schema-dts "^1.1.2" diff --git a/desci-server/package.json b/desci-server/package.json index 30a98e4f..a281242e 100755 --- a/desci-server/package.json +++ b/desci-server/package.json @@ -57,7 +57,7 @@ "@aws-sdk/client-s3": "^3.537.0", "@desci-labs/desci-codex-lib": "^1.1.7", "@desci-labs/desci-contracts": "0.2.5-rc7", - "@desci-labs/desci-models": "^0.2.7-rc5", + "@desci-labs/desci-models": "^0.2.7-rc6", "@honeycombio/opentelemetry-node": "^0.3.2", "@ipld/dag-pb": "^4.0.0", "@opentelemetry/api": "^1.8.0", diff --git a/desci-server/prisma/schema.prisma b/desci-server/prisma/schema.prisma index de96007a..72f4656f 100755 --- a/desci-server/prisma/schema.prisma +++ b/desci-server/prisma/schema.prisma @@ -918,6 +918,7 @@ enum ActionType { UPDATE_ORCID_RECORD REMOVE_ORCID_WORK_RECORD ORCID_API_ERROR + AUTOMATE_METADATA } enum ChainTransactionType { diff --git a/desci-server/scripts/import-ipfs-content.sh b/desci-server/scripts/import-ipfs-content.sh index 56dfc408..976f2f03 100755 --- a/desci-server/scripts/import-ipfs-content.sh +++ b/desci-server/scripts/import-ipfs-content.sh @@ -1,4 +1,16 @@ # import required images from ipfs to local +check_and_install() { + echo "check and install: $1" + # local shell_cmd = $1 + if ! command -v $1 &> /dev/null; + then + apt-get install -y $1 + fi +} + +check_and_install "wget" +check_and_install "curl" + wget https://ipfs.desci.com/ipfs/bafkreih6yx7ywj7trvpp45vergrnytad7ezsku75tefyro4qrrcfrrmrt4 -O /tmp/cover.png curl -F file=@/tmp/cover.png "http://host.docker.internal:5001/api/v0/add?cid-version=1" \ No newline at end of file diff --git a/desci-server/src/controllers/data/update.ts b/desci-server/src/controllers/data/update.ts index aaffb91b..96358f5e 100644 --- a/desci-server/src/controllers/data/update.ts +++ b/desci-server/src/controllers/data/update.ts @@ -2,15 +2,12 @@ import { ResearchObjectV1, DriveObject } from '@desci-labs/desci-models'; import { Response } from 'express'; import { prisma } from '../../client.js'; -import { metadataClient } from '../../internal.js'; import { logger as parentLogger } from '../../logger.js'; import { RequestWithNode } from '../../middleware/authorisation.js'; -import { MetadataResponse } from '../../services/AutomatedMetadata.js'; import { processExternalUrlDataToIpfs } from '../../services/data/externalUrlProcessing.js'; import { processNewFolder, processS3DataToIpfs } from '../../services/data/processing.js'; import { arrayXor, ensureUuidEndsWithDot } from '../../utils.js'; -import { isDoiLink } from './utils.js'; export interface UpdateResponse { status?: number; rootDataCid?: string; @@ -28,15 +25,7 @@ export interface ErrorResponse { export const update = async (req: RequestWithNode, res: Response) => { const owner = req.user; let node = req.node; - const { - uuid, - manifest: draftManifest, - componentType, - componentSubtype, - newFolderName, - autoStar, - prepublication, - } = req.body; + const { uuid, manifest: draftManifest, componentType, componentSubtype, newFolderName, autoStar } = req.body; let { contextPath } = req.body; // debugger; if (contextPath.endsWith('/')) contextPath = contextPath.slice(0, -1); @@ -117,18 +106,6 @@ export const update = async (req: RequestWithNode, res: Response, ) => { const owner = (req as any).user as User; - const { uuid, contextPath, externalCids, componentType, componentSubtype, prepublication } = req.body; + const { uuid, contextPath, externalCids, componentType, componentSubtype } = req.body; const logger = parentLogger.child({ // id: req.id, @@ -88,17 +78,6 @@ export const updateExternalCid = async ( date: date, } = value as UpdateResponse; - if (prepublication) { - // pre-cache automated metadata response - const metadata = await metadataClient.getResourceMetadata({ cid: externalCids[0].cid }); - - if (metadata) { - await metadataClient.automateMetadata(metadata, { - uuid: node.uuid, - documentId: node.manifestDocumentId as DocumentId, - }); - } - } return res.status(200).json({ manifest: updatedManifest, manifestCid: persistedManifestCid, diff --git a/desci-server/src/controllers/nodes/index.ts b/desci-server/src/controllers/nodes/index.ts index 1dccea38..3a4e56dc 100755 --- a/desci-server/src/controllers/nodes/index.ts +++ b/desci-server/src/controllers/nodes/index.ts @@ -11,3 +11,4 @@ export * from './prepublish.js'; export * from './share.js'; export * from './nodesCover.js'; export * from './manager.js'; +export * from './metadata.js'; diff --git a/desci-server/src/controllers/nodes/metadata.ts b/desci-server/src/controllers/nodes/metadata.ts new file mode 100644 index 00000000..7c696032 --- /dev/null +++ b/desci-server/src/controllers/nodes/metadata.ts @@ -0,0 +1,61 @@ +import { DocumentId } from '@automerge/automerge-repo'; +import { ActionType } from '@prisma/client'; +import { NextFunction, Response } from 'express'; +import { z } from 'zod'; + +import { BadRequestError, RequestWithNode, SuccessResponse, metadataClient } from '../../internal.js'; +import { MetadataResponse } from '../../services/AutomatedMetadata.js'; +import { saveInteraction } from '../../services/interactionLog.js'; +import { isDoiLink } from '../data/utils.js'; + +export const automateMetadataSchema = z.object({ + params: z.object({ + uuid: z.string(), + }), + body: z.object({ + authors: z.array( + z.object({ + orcid: z.string().optional(), + name: z.string(), + affiliation: z.string().optional(), + }), + ), + title: z.string(), + pdfUrl: z.string().optional(), + keywords: z.array(z.string()).optional(), + }), +}); + +export const automateMetadata = async (req: RequestWithNode, res: Response, _next: NextFunction) => { + const node = req.node; + const metadata = req.body as MetadataResponse; + + if (metadata) { + const response = await metadataClient.automateMetadata(metadata, { + uuid: node.uuid, + documentId: node.manifestDocumentId as DocumentId, + }); + + await saveInteraction(req, ActionType.AUTOMATE_METADATA, { uuid: node.uuid }); + + new SuccessResponse(response.manifest).send(res); + } else { + throw new BadRequestError(); + } +}; + +export const generateMetadataSchema = z.object({ + body: z.object({ + cid: z.string().optional(), + doi: z.string().optional(), + }), +}); + +export const generateMetadata = async (req: RequestWithNode, res: Response, _next: NextFunction) => { + const { cid, doi } = req.body; + if (!cid && !isDoiLink(doi)) throw new BadRequestError('Invalid DOI url'); + const metadata = await metadataClient.getResourceMetadata({ cid, doi }); + // await saveInteraction(req, ActionType.GENERATE_METADATA, { uuid: node.uuid, cid, status: !!metadata }); + + return new SuccessResponse(metadata).send(res); +}; diff --git a/desci-server/src/routes/v1/nodes.ts b/desci-server/src/routes/v1/nodes.ts index 85d487eb..02073f5b 100755 --- a/desci-server/src/routes/v1/nodes.ts +++ b/desci-server/src/routes/v1/nodes.ts @@ -7,6 +7,7 @@ import { getUserContributions } from '../../controllers/nodes/contributions/getU import { getUserContributionsAuthed } from '../../controllers/nodes/contributions/getUserContributionsAuthed.js'; import { updateContributor } from '../../controllers/nodes/contributions/update.js'; import { verifyContribution } from '../../controllers/nodes/contributions/verify.js'; +import { createDpid } from '../../controllers/nodes/createDpid.js'; import { dispatchDocumentChange, getNodeDocument } from '../../controllers/nodes/documents.js'; import { feed } from '../../controllers/nodes/feed.js'; import { frontmatterPreview } from '../../controllers/nodes/frontmatterPreview.js'; @@ -31,6 +32,10 @@ import { publishConsent, checkUserPublishConsent, checkPublishConsentSchema, + automateMetadata, + generateMetadata, + automateMetadataSchema, + generateMetadataSchema, } from '../../controllers/nodes/index.js'; import { retrieveTitle } from '../../controllers/nodes/legacyManifestApi.js'; import { preparePublishPackage } from '../../controllers/nodes/preparePublishPackage.js'; @@ -41,7 +46,6 @@ import { versionDetails } from '../../controllers/nodes/versionDetails.js'; import { asyncHander, attachUser, validate } from '../../internal.js'; import { ensureNodeAccess, ensureWriteNodeAccess } from '../../middleware/authorisation.js'; import { ensureUser } from '../../middleware/permissions.js'; -import { createDpid } from '../../controllers/nodes/createDpid.js'; const router = Router(); @@ -83,6 +87,12 @@ router.get('/contributions/user/:userId', [], getUserContributions); router.get('/contributions/user', [ensureUser], getUserContributionsAuthed); router.post('/distribution', preparePublishPackage); router.post('/distribution/preview', [ensureUser], frontmatterPreview); +router.post( + '/:uuid/automate-metadata', + [ensureUser, ensureNodeAccess, validate(automateMetadataSchema)], + automateMetadata, +); +router.post('/generate-metadata', [ensureUser, validate(generateMetadataSchema)], generateMetadata); router.delete('/:uuid', [ensureUser], deleteNode); diff --git a/desci-server/src/services/AutomatedMetadata.ts b/desci-server/src/services/AutomatedMetadata.ts index c2e57c9b..6e8f1d95 100644 --- a/desci-server/src/services/AutomatedMetadata.ts +++ b/desci-server/src/services/AutomatedMetadata.ts @@ -18,7 +18,7 @@ export type MetadataParam = { }; export type AutomatedMetadataResponse = { - output: { + output: Array<{ creator: { [k in string]: { '@id': string; @@ -41,7 +41,7 @@ export type AutomatedMetadataResponse = { }>; oa_url: string | null; title: string; - }; + }>; }; export type MetadataResponse = { @@ -85,16 +85,16 @@ export class AutomatedMetadataClient { if (query.doi) { body.doi = query.doi; } - logger.info(body, 'API INFO'); + logger.info({ body }, 'API INFO'); // config.body = body; const url = `${this.baseurl}/invoke-script`; - logger.info(url, 'url params'); + logger.info({ url }, 'url params'); const config: RequestInit = { method: 'POST', mode: 'cors', - headers: {}, + headers: { Accept: '*/*', 'content-type': 'application/json' }, body: JSON.stringify(body), }; @@ -115,12 +115,12 @@ export class AutomatedMetadataClient { async performFetch(request: Request, cacheKey: string): Promise { const responseFromCache = await getFromCache(request.url); - logger.info(responseFromCache, 'METADATA From Cache'); + logger.info({ responseFromCache, request: request.headers, cacheKey }, 'METADATA From Cache'); if (responseFromCache) return responseFromCache; const response = (await fetch(request)) as Response; let data: T; - + logger.info({ status: response.status, header: response.headers.get('content-type') }, 'RESPONSE FROM METADATA'); if (response.ok && response.status === 200) { if (response.headers.get('content-type')?.includes('application/json')) { data = (await response.json()) as T; @@ -128,20 +128,24 @@ export class AutomatedMetadataClient { await setToCache(cacheKey, data, ONE_DAY_TTL); return data; } + } else { + logger.info({ body: await response.text() }, 'ERROR RESPONSE'); } return null as T; } transformResponse(data: AutomatedMetadataResponse): MetadataResponse { - const authors = data.output?.creator - ? Object.entries(data.output.creator).map(([name, creator]) => ({ - orcid: creator['@id'], + const output = data.output?.[0]; + + const authors = output?.creator + ? Object.entries(output.creator).map(([name, creator]) => ({ affiliation: creator.affiliation, name, + ...(creator['@id'] && { orcid: creator['@id'] }), })) : []; - const keywords = data.output?.keywords ? data.output.keywords.map((keyword) => keyword.display_name) : []; - const metadata: MetadataResponse = { authors, keywords, title: data.output.title, pdfUrl: data.output.oa_url }; + const keywords = output?.keywords ? output.keywords.map((keyword) => keyword.display_name) : []; + const metadata: MetadataResponse = { authors, keywords, title: output.title, pdfUrl: output.oa_url }; logger.info(metadata, 'METADATA'); return metadata; } diff --git a/desci-server/src/services/index.ts b/desci-server/src/services/index.ts index d751bd94..293c3c11 100644 --- a/desci-server/src/services/index.ts +++ b/desci-server/src/services/index.ts @@ -11,6 +11,7 @@ export const crossRefClient = new CrossRefClient( process.env.CROSSREF_EMAIL, ); export const metadataClient = new AutomatedMetadataClient( - process.env.AUTOMATED_METADATA_API, + // 'process.env.AUTOMATED_METADATA_API', + 'http://host.docker.internal:5005', process.env.AUTOMATED_METADATA_API_KEY, ); diff --git a/desci-server/yarn.lock b/desci-server/yarn.lock index d1564b9f..d0f41a17 100644 --- a/desci-server/yarn.lock +++ b/desci-server/yarn.lock @@ -2210,10 +2210,10 @@ resolved "https://registry.yarnpkg.com/@desci-labs/desci-contracts/-/desci-contracts-0.2.5-rc7.tgz#a8a49c9518107305be712bcbdbb352faa4057a44" integrity sha512-W1hf+mv5KWnqCuXX3uBiBsll+iMD82GJbsGs3huzH6qY2TySVFUCLov017B0RGz2Ap1WRB9w7h3o9CEwDuV5lQ== -"@desci-labs/desci-models@^0.2.7-rc5": - version "0.2.7-rc5" - resolved "https://registry.yarnpkg.com/@desci-labs/desci-models/-/desci-models-0.2.7-rc5.tgz#fec8cd3372eaa22fd727d87fa8967a7c093e6d5f" - integrity sha512-mA3rpgaWfDAxO6BXejijP+mvmzvVTHPQ/vEyWkzeZ/V8DGUHzcScYAa6W5RD5mWRmFIAXGAg/zQuwaxw7PaOSg== +"@desci-labs/desci-models@^0.2.7-rc6": + version "0.2.7-rc6" + resolved "https://registry.yarnpkg.com/@desci-labs/desci-models/-/desci-models-0.2.7-rc6.tgz#f7f7fed6dc6acda3a90650d1977fa3acb4c2a2a4" + integrity sha512-A1eWbHJqbs9YEnsJzOzgRdoCpsBzlYa4yacXApBmZmVHk6EwqtMJRjwAsQ0/YIQcLbyYCptSenPXhOSlw4FESw== dependencies: jsonld "^8.1.1" schema-dts "^1.1.2" From e0a6abf9827f9b39de1964860e22ba520e9ffbd7 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Thu, 20 Jun 2024 17:00:54 +0000 Subject: [PATCH 172/278] date fix for drafts --- desci-server/src/services/PublishPackage.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/desci-server/src/services/PublishPackage.ts b/desci-server/src/services/PublishPackage.ts index 35ec494c..4a14f005 100644 --- a/desci-server/src/services/PublishPackage.ts +++ b/desci-server/src/services/PublishPackage.ts @@ -57,9 +57,11 @@ class PublishPackageService { } const license = PublishPackageService.extractManuscriptLicense(manifest, pdfCid); + // const paddedTimestamp = unixTimestamp.padEnd(13, '0'); const publishTime = demoMode - ? Date.now().toString().slice(0, 8) + ? Date.now().toString().slice(0, 10) : await publishServices.retrieveBlockTimeByManifestCid(node.uuid, manifestCid); + const publishDate = PublishPackageService.convertUnixTimestampToDate(publishTime); const authors = manifest.authors?.map((author) => author.name); @@ -100,7 +102,6 @@ class PublishPackageService { } static convertUnixTimestampToDate(unixTimestamp: string): string { - debugger; const date = new Date(Number(unixTimestamp) * 1000); const formattedDate = date.toLocaleString('en-US', { month: 'long', From 68b7e364abca9763d829545622b280ede9eaa224 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Fri, 21 Jun 2024 12:58:46 +0200 Subject: [PATCH 173/278] add api to generate and automate metadata --- desci-server/src/controllers/nodes/metadata.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/desci-server/src/controllers/nodes/metadata.ts b/desci-server/src/controllers/nodes/metadata.ts index 7c696032..0f6ec983 100644 --- a/desci-server/src/controllers/nodes/metadata.ts +++ b/desci-server/src/controllers/nodes/metadata.ts @@ -3,7 +3,14 @@ import { ActionType } from '@prisma/client'; import { NextFunction, Response } from 'express'; import { z } from 'zod'; -import { BadRequestError, RequestWithNode, SuccessResponse, metadataClient } from '../../internal.js'; +import { + BadRequestError, + InternalError, + RequestWithNode, + SuccessMessageResponse, + SuccessResponse, + metadataClient, +} from '../../internal.js'; import { MetadataResponse } from '../../services/AutomatedMetadata.js'; import { saveInteraction } from '../../services/interactionLog.js'; import { isDoiLink } from '../data/utils.js'; @@ -36,9 +43,10 @@ export const automateMetadata = async (req: RequestWithNode, res: Response, _nex documentId: node.manifestDocumentId as DocumentId, }); - await saveInteraction(req, ActionType.AUTOMATE_METADATA, { uuid: node.uuid }); + if (!response) throw new InternalError('Ran into an error while applying metadata'); + // await saveInteraction(req, ActionType.AUTOMATE_METADATA, { uuid: node.uuid }); - new SuccessResponse(response.manifest).send(res); + new SuccessMessageResponse().send(res); } else { throw new BadRequestError(); } From f4983d978269f9525096a9cd4d1c7ff9dd7c24f5 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Fri, 21 Jun 2024 13:00:30 +0200 Subject: [PATCH 174/278] update dependencies --- desci-server/package.json | 2 +- desci-server/yarn.lock | 39 ++++++++++++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/desci-server/package.json b/desci-server/package.json index d30ffece..952bdda3 100755 --- a/desci-server/package.json +++ b/desci-server/package.json @@ -57,7 +57,7 @@ "@aws-sdk/client-s3": "^3.537.0", "@desci-labs/desci-codex-lib": "^1.1.7", "@desci-labs/desci-contracts": "0.2.5-rc7", - "@desci-labs/desci-models": "0.2.7-rc5", + "@desci-labs/desci-models": "0.2.7-rc6", "@honeycombio/opentelemetry-node": "^0.3.2", "@ipld/dag-pb": "^4.0.0", "@opentelemetry/api": "^1.8.0", diff --git a/desci-server/yarn.lock b/desci-server/yarn.lock index f0a507ed..b2225085 100644 --- a/desci-server/yarn.lock +++ b/desci-server/yarn.lock @@ -2210,10 +2210,10 @@ resolved "https://registry.yarnpkg.com/@desci-labs/desci-contracts/-/desci-contracts-0.2.5-rc7.tgz#a8a49c9518107305be712bcbdbb352faa4057a44" integrity sha512-W1hf+mv5KWnqCuXX3uBiBsll+iMD82GJbsGs3huzH6qY2TySVFUCLov017B0RGz2Ap1WRB9w7h3o9CEwDuV5lQ== -"@desci-labs/desci-models@0.2.7-rc5": - version "0.2.7-rc5" - resolved "https://registry.yarnpkg.com/@desci-labs/desci-models/-/desci-models-0.2.7-rc5.tgz#fec8cd3372eaa22fd727d87fa8967a7c093e6d5f" - integrity sha512-mA3rpgaWfDAxO6BXejijP+mvmzvVTHPQ/vEyWkzeZ/V8DGUHzcScYAa6W5RD5mWRmFIAXGAg/zQuwaxw7PaOSg== +"@desci-labs/desci-models@0.2.7-rc6": + version "0.2.7-rc6" + resolved "https://registry.yarnpkg.com/@desci-labs/desci-models/-/desci-models-0.2.7-rc6.tgz#f7f7fed6dc6acda3a90650d1977fa3acb4c2a2a4" + integrity sha512-A1eWbHJqbs9YEnsJzOzgRdoCpsBzlYa4yacXApBmZmVHk6EwqtMJRjwAsQ0/YIQcLbyYCptSenPXhOSlw4FESw== dependencies: jsonld "^8.1.1" schema-dts "^1.1.2" @@ -15706,7 +15706,16 @@ string-template@~0.2.1: resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" integrity sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw== -"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -15779,7 +15788,7 @@ stringify-object@3.3.0: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -15793,6 +15802,13 @@ strip-ansi@^3.0.0: dependencies: ansi-regex "^2.0.0" +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-ansi@^7.0.1: version "7.1.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" @@ -16816,7 +16832,7 @@ workerpool@6.2.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -16834,6 +16850,15 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" From b71e38c60f53b72bef6929692196b8c0b3d09857 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Fri, 21 Jun 2024 13:27:43 +0200 Subject: [PATCH 175/278] bump model version to latest rc --- desci-repo/package.json | 2 +- desci-repo/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/desci-repo/package.json b/desci-repo/package.json index 3d5bd7bc..2986927f 100644 --- a/desci-repo/package.json +++ b/desci-repo/package.json @@ -68,7 +68,7 @@ "typescript": "5.1.6" }, "dependencies": { - "@desci-labs/desci-models": "0.2.7-rc3", + "@desci-labs/desci-models": "0.2.7-rc6", "@sentry/node": "^7.84.0", "@sentry/tracing": "^7.84.0", "axios": "^1.6.2", diff --git a/desci-repo/yarn.lock b/desci-repo/yarn.lock index a87fb260..411cfd27 100644 --- a/desci-repo/yarn.lock +++ b/desci-repo/yarn.lock @@ -131,10 +131,10 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@desci-labs/desci-models@0.2.7-rc3": - version "0.2.7-rc3" - resolved "https://registry.yarnpkg.com/@desci-labs/desci-models/-/desci-models-0.2.7-rc3.tgz#b033073e6b77edde85491731d5c03469f443aaa1" - integrity sha512-RL1vwUHTumpmj7goX6+AcSVt0MGpdm4QWZ20gkmE9+BlL1eIxX+oQzQFmW92XXHWUQOETIaL1YnHsGCVz4gJNw== +"@desci-labs/desci-models@0.2.7-rc6": + version "0.2.7-rc6" + resolved "https://registry.yarnpkg.com/@desci-labs/desci-models/-/desci-models-0.2.7-rc6.tgz#f7f7fed6dc6acda3a90650d1977fa3acb4c2a2a4" + integrity sha512-A1eWbHJqbs9YEnsJzOzgRdoCpsBzlYa4yacXApBmZmVHk6EwqtMJRjwAsQ0/YIQcLbyYCptSenPXhOSlw4FESw== dependencies: jsonld "^8.1.1" schema-dts "^1.1.2" From 0bb4c4027b3e35897300768315f471ec2f0a6d9c Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Fri, 21 Jun 2024 14:28:30 +0200 Subject: [PATCH 176/278] merged --- desci-server/src/routes/v1/nodes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desci-server/src/routes/v1/nodes.ts b/desci-server/src/routes/v1/nodes.ts index 3f8e0e25..3fc60545 100755 --- a/desci-server/src/routes/v1/nodes.ts +++ b/desci-server/src/routes/v1/nodes.ts @@ -7,6 +7,7 @@ import { getUserContributions } from '../../controllers/nodes/contributions/getU import { getUserContributionsAuthed } from '../../controllers/nodes/contributions/getUserContributionsAuthed.js'; import { updateContributor } from '../../controllers/nodes/contributions/update.js'; import { verifyContribution } from '../../controllers/nodes/contributions/verify.js'; +import { createDpid } from '../../controllers/nodes/createDpid.js'; import { dispatchDocumentChange, getNodeDocument } from '../../controllers/nodes/documents.js'; import { feed } from '../../controllers/nodes/feed.js'; import { frontmatterPreview } from '../../controllers/nodes/frontmatterPreview.js'; @@ -41,7 +42,6 @@ import { versionDetails } from '../../controllers/nodes/versionDetails.js'; import { asyncHandler, attachUser, validate } from '../../internal.js'; import { ensureNodeAccess, ensureWriteNodeAccess } from '../../middleware/authorisation.js'; import { ensureUser } from '../../middleware/permissions.js'; -import { createDpid } from '../../controllers/nodes/createDpid.js'; const router = Router(); From 1417507d6ee0354510f18be19a66762c6c30ab98 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Fri, 21 Jun 2024 19:09:22 +0200 Subject: [PATCH 177/278] make doi field an array --- desci-models/package.json | 2 +- desci-models/src/ResearchObject.ts | 2 +- desci-server/package.json | 2 +- desci-server/src/controllers/doi/check.ts | 13 +++++-- desci-server/yarn.lock | 44 +++++++---------------- 5 files changed, 25 insertions(+), 38 deletions(-) diff --git a/desci-models/package.json b/desci-models/package.json index 7026b8aa..5db9cb00 100644 --- a/desci-models/package.json +++ b/desci-models/package.json @@ -1,6 +1,6 @@ { "name": "@desci-labs/desci-models", - "version": "0.2.7-rc6", + "version": "0.2.7-rc7", "description": "Data models for DeSci Nodes", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/desci-models/src/ResearchObject.ts b/desci-models/src/ResearchObject.ts index 536d8c6e..1f4f1ba8 100644 --- a/desci-models/src/ResearchObject.ts +++ b/desci-models/src/ResearchObject.ts @@ -247,7 +247,7 @@ export interface PdfComponentPayload { /** Annotations on the document */ annotations?: PdfAnnotation[]; /** DOI of the pdf or manuscript */ - doi?: string; + doi?: string[]; } export interface ExternalLinkComponentPayload { diff --git a/desci-server/package.json b/desci-server/package.json index 952bdda3..dea0a448 100755 --- a/desci-server/package.json +++ b/desci-server/package.json @@ -57,7 +57,7 @@ "@aws-sdk/client-s3": "^3.537.0", "@desci-labs/desci-codex-lib": "^1.1.7", "@desci-labs/desci-contracts": "0.2.5-rc7", - "@desci-labs/desci-models": "0.2.7-rc6", + "@desci-labs/desci-models": "file:../desci-models", "@honeycombio/opentelemetry-node": "^0.3.2", "@ipld/dag-pb": "^4.0.0", "@opentelemetry/api": "^1.8.0", diff --git a/desci-server/src/controllers/doi/check.ts b/desci-server/src/controllers/doi/check.ts index 95bda635..324d86aa 100644 --- a/desci-server/src/controllers/doi/check.ts +++ b/desci-server/src/controllers/doi/check.ts @@ -1,5 +1,10 @@ import { DocumentId } from '@automerge/automerge-repo'; -import { CommonComponentPayload, PdfComponent, ResearchObjectComponentType } from '@desci-labs/desci-models'; +import { + CommonComponentPayload, + PdfComponent, + PdfComponentPayload, + ResearchObjectComponentType, +} from '@desci-labs/desci-models'; import { NextFunction, Request, Response } from 'express'; import { DoiError } from '../../core/doi/error.js'; @@ -77,7 +82,9 @@ export const attachDoi = async (req: RequestWithNode, res: Response, _next: Next select: [WorkSelectOptions.DOI, WorkSelectOptions.TITLE, WorkSelectOptions.AUTHOR], }); - const doi = works?.data?.message?.items.find((item) => item.title.some((t) => t === queryTitle)); + const doi = works?.data?.message?.items.find((item) => + item.title.some((t) => t.toLowerCase() === queryTitle.toLowerCase()), + ); logger.info({ doi, queryTitle }, 'DOI Response'); @@ -92,7 +99,7 @@ export const attachDoi = async (req: RequestWithNode, res: Response, _next: Next actions: [ { type: 'Update Component', - component: { ...component, payload: { ...component.payload, doi: doi.DOI } }, + component: { ...component, payload: { ...component.payload, doi: [doi.DOI] } as PdfComponentPayload }, componentIndex, }, ], diff --git a/desci-server/yarn.lock b/desci-server/yarn.lock index b2225085..edc7d534 100644 --- a/desci-server/yarn.lock +++ b/desci-server/yarn.lock @@ -2210,10 +2210,8 @@ resolved "https://registry.yarnpkg.com/@desci-labs/desci-contracts/-/desci-contracts-0.2.5-rc7.tgz#a8a49c9518107305be712bcbdbb352faa4057a44" integrity sha512-W1hf+mv5KWnqCuXX3uBiBsll+iMD82GJbsGs3huzH6qY2TySVFUCLov017B0RGz2Ap1WRB9w7h3o9CEwDuV5lQ== -"@desci-labs/desci-models@0.2.7-rc6": +"@desci-labs/desci-models@file:../desci-models": version "0.2.7-rc6" - resolved "https://registry.yarnpkg.com/@desci-labs/desci-models/-/desci-models-0.2.7-rc6.tgz#f7f7fed6dc6acda3a90650d1977fa3acb4c2a2a4" - integrity sha512-A1eWbHJqbs9YEnsJzOzgRdoCpsBzlYa4yacXApBmZmVHk6EwqtMJRjwAsQ0/YIQcLbyYCptSenPXhOSlw4FESw== dependencies: jsonld "^8.1.1" schema-dts "^1.1.2" @@ -15706,16 +15704,7 @@ string-template@~0.2.1: resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" integrity sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw== -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -15788,7 +15777,7 @@ stringify-object@3.3.0: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -15802,13 +15791,6 @@ strip-ansi@^3.0.0: dependencies: ansi-regex "^2.0.0" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^7.0.1: version "7.1.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" @@ -16506,13 +16488,20 @@ undici-types@~5.26.4: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== -undici@^5.12.0, undici@^5.21.2: +undici@^5.12.0: version "5.28.3" resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.3.tgz#a731e0eff2c3fcfd41c1169a869062be222d1e5b" integrity sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA== dependencies: "@fastify/busboy" "^2.0.0" +undici@^5.21.2: + version "5.28.4" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.4.tgz#6b280408edb6a1a604a9b20340f45b422e373068" + integrity sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g== + dependencies: + "@fastify/busboy" "^2.0.0" + unique-filename@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" @@ -16832,7 +16821,7 @@ workerpool@6.2.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -16850,15 +16839,6 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" From 3ee055a1da5c2008963410fe9ddcb72e39c805a7 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Sat, 22 Jun 2024 09:18:32 +0000 Subject: [PATCH 178/278] prepub email controller added, removed email step from preparePublishPackage controller --- .../nodes/contributions/prepubEmail.ts | 67 +++++++++++++++++++ .../nodes/preparePublishPackage.ts | 2 +- 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 desci-server/src/controllers/nodes/contributions/prepubEmail.ts diff --git a/desci-server/src/controllers/nodes/contributions/prepubEmail.ts b/desci-server/src/controllers/nodes/contributions/prepubEmail.ts new file mode 100644 index 00000000..a67e1e57 --- /dev/null +++ b/desci-server/src/controllers/nodes/contributions/prepubEmail.ts @@ -0,0 +1,67 @@ +import type { Request, Response } from 'express'; + +import { prisma } from '../../../client.js'; +import { logger as parentLogger } from '../../../logger.js'; +import { publishServices } from '../../../services/PublishServices.js'; +import { CidString } from '../../../services/Thumbnails.js'; +import { ensureUuidEndsWithDot } from '../../../utils.js'; + +export type EmailPublishPackageReqBodyParams = { + prepubDistPdfCid: CidString; + nodeUuid: string; +}; + +type EmailPublishPackageResponse = { + ok: true; +}; + +type EmailPublishPackageErrorResponse = { + ok: false; + error: string; + status?: number; +}; + +/** + * Generates a prepublish package for a published node (at the moment just the distro PDF) + */ +export const emailPublishPackage = async ( + req: Request<{ emailAllContributors?: boolean }, any, EmailPublishPackageReqBodyParams>, + res: Response, +) => { + const { prepubDistPdfCid, nodeUuid } = req.body; + const { emailAllContributors } = req.query; + const logger = parentLogger.child({ + module: 'NODES::emailPublishPackageController', + prepubDistPdfCid, + emailAllContributors, + nodeUuid, + }); + // debugger; + logger.trace({ fn: 'Distributing Publish Package' }); + + if (!nodeUuid) return res.status(400).json({ ok: false, error: 'nodeUuid is required.' }); + if (!prepubDistPdfCid) return res.status(400).json({ ok: false, error: 'pdfCid is required.' }); + + try { + const node = await prisma.node.findFirst({ + where: { + uuid: ensureUuidEndsWithDot(nodeUuid), + }, + }); + + if (!node) return res.status(404).json({ ok: false, error: 'Node not found' }); + + const distPdfEntry = await prisma.distributionPdfs.findFirst({ + where: { distPdfCid: prepubDistPdfCid, nodeUuid: node.uuid }, + }); + if (!distPdfEntry) return res.status(404).json({ ok: false, error: 'Distribution PDF not found' }); + + // Fire off email to all contributors + await publishServices.sendVersionUpdateEmailToAllContributors({ node, manuscriptCid: prepubDistPdfCid }); + + return res.status(200).json({ ok: true }); + } catch (e) { + logger.error({ error: e.message }); + return res.status(500).json({ ok: false, error: 'Failed sending distribution package' }); + } +}; diff --git a/desci-server/src/controllers/nodes/preparePublishPackage.ts b/desci-server/src/controllers/nodes/preparePublishPackage.ts index 3ae17af2..62c52ee1 100644 --- a/desci-server/src/controllers/nodes/preparePublishPackage.ts +++ b/desci-server/src/controllers/nodes/preparePublishPackage.ts @@ -70,7 +70,7 @@ export const preparePublishPackage = async ( }); // Fire off email to all contributors - await publishServices.sendVersionUpdateEmailToAllContributors({ node, manuscriptCid: distPdfCid }); + // await publishServices.sendVersionUpdateEmailToAllContributors({ node, manuscriptCid: distPdfCid }); return res.status(200).json({ ok: true, distPdfCid }); } catch (e) { From 6cfe1c7c35928eb2038ff0aa4ddce8a52e6a1fe9 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Mon, 24 Jun 2024 09:55:05 +0200 Subject: [PATCH 179/278] update doi field to an array of strings --- desci-models/package.json | 2 +- desci-models/src/ResearchObject.ts | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/desci-models/package.json b/desci-models/package.json index 7026b8aa..5db9cb00 100644 --- a/desci-models/package.json +++ b/desci-models/package.json @@ -1,6 +1,6 @@ { "name": "@desci-labs/desci-models", - "version": "0.2.7-rc6", + "version": "0.2.7-rc7", "description": "Data models for DeSci Nodes", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/desci-models/src/ResearchObject.ts b/desci-models/src/ResearchObject.ts index ece6739d..b504bf86 100644 --- a/desci-models/src/ResearchObject.ts +++ b/desci-models/src/ResearchObject.ts @@ -246,6 +246,8 @@ export interface PdfComponentPayload { cid: string; /** Annotations on the document */ annotations?: PdfAnnotation[]; + /** Store an optional list of associated DOIs */ + doi?: string[]; } export interface ExternalLinkComponentPayload { From fd81de7dc950a67ee2ad19ea95bfae72539306d4 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Mon, 24 Jun 2024 10:00:15 +0200 Subject: [PATCH 180/278] move model update to another branch --- desci-models/package.json | 2 +- desci-server/package.json | 2 +- desci-server/src/controllers/doi/check.ts | 2 +- yarn.lock | 4 ++++ 4 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 yarn.lock diff --git a/desci-models/package.json b/desci-models/package.json index 5db9cb00..7026b8aa 100644 --- a/desci-models/package.json +++ b/desci-models/package.json @@ -1,6 +1,6 @@ { "name": "@desci-labs/desci-models", - "version": "0.2.7-rc7", + "version": "0.2.7-rc6", "description": "Data models for DeSci Nodes", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/desci-server/package.json b/desci-server/package.json index dea0a448..952bdda3 100755 --- a/desci-server/package.json +++ b/desci-server/package.json @@ -57,7 +57,7 @@ "@aws-sdk/client-s3": "^3.537.0", "@desci-labs/desci-codex-lib": "^1.1.7", "@desci-labs/desci-contracts": "0.2.5-rc7", - "@desci-labs/desci-models": "file:../desci-models", + "@desci-labs/desci-models": "0.2.7-rc6", "@honeycombio/opentelemetry-node": "^0.3.2", "@ipld/dag-pb": "^4.0.0", "@opentelemetry/api": "^1.8.0", diff --git a/desci-server/src/controllers/doi/check.ts b/desci-server/src/controllers/doi/check.ts index 324d86aa..8aab96b0 100644 --- a/desci-server/src/controllers/doi/check.ts +++ b/desci-server/src/controllers/doi/check.ts @@ -99,7 +99,7 @@ export const attachDoi = async (req: RequestWithNode, res: Response, _next: Next actions: [ { type: 'Update Component', - component: { ...component, payload: { ...component.payload, doi: [doi.DOI] } as PdfComponentPayload }, + component: { ...component, payload: { ...component.payload, doi: doi.DOI } as PdfComponentPayload }, componentIndex, }, ], diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 00000000..fb57ccd1 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,4 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + From 9b8c6bf6f59e82d79bce9ee1b715112fa4d3cfcc Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Mon, 24 Jun 2024 10:34:44 +0200 Subject: [PATCH 181/278] bump version number --- desci-models/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desci-models/package.json b/desci-models/package.json index 5db9cb00..8da34169 100644 --- a/desci-models/package.json +++ b/desci-models/package.json @@ -1,6 +1,6 @@ { "name": "@desci-labs/desci-models", - "version": "0.2.7-rc7", + "version": "0.2.8", "description": "Data models for DeSci Nodes", "main": "dist/index.js", "types": "dist/index.d.ts", From d06110bc5d11d028870b97df0ec973ee5d096925 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Mon, 24 Jun 2024 10:57:59 +0200 Subject: [PATCH 182/278] upgrade model --- desci-server/package.json | 2 +- desci-server/src/controllers/doi/check.ts | 2 +- desci-server/yarn.lock | 6 ++++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/desci-server/package.json b/desci-server/package.json index 952bdda3..4c65949c 100755 --- a/desci-server/package.json +++ b/desci-server/package.json @@ -57,7 +57,7 @@ "@aws-sdk/client-s3": "^3.537.0", "@desci-labs/desci-codex-lib": "^1.1.7", "@desci-labs/desci-contracts": "0.2.5-rc7", - "@desci-labs/desci-models": "0.2.7-rc6", + "@desci-labs/desci-models": "0.2.8", "@honeycombio/opentelemetry-node": "^0.3.2", "@ipld/dag-pb": "^4.0.0", "@opentelemetry/api": "^1.8.0", diff --git a/desci-server/src/controllers/doi/check.ts b/desci-server/src/controllers/doi/check.ts index 8aab96b0..324d86aa 100644 --- a/desci-server/src/controllers/doi/check.ts +++ b/desci-server/src/controllers/doi/check.ts @@ -99,7 +99,7 @@ export const attachDoi = async (req: RequestWithNode, res: Response, _next: Next actions: [ { type: 'Update Component', - component: { ...component, payload: { ...component.payload, doi: doi.DOI } as PdfComponentPayload }, + component: { ...component, payload: { ...component.payload, doi: [doi.DOI] } as PdfComponentPayload }, componentIndex, }, ], diff --git a/desci-server/yarn.lock b/desci-server/yarn.lock index edc7d534..32777b7a 100644 --- a/desci-server/yarn.lock +++ b/desci-server/yarn.lock @@ -2210,8 +2210,10 @@ resolved "https://registry.yarnpkg.com/@desci-labs/desci-contracts/-/desci-contracts-0.2.5-rc7.tgz#a8a49c9518107305be712bcbdbb352faa4057a44" integrity sha512-W1hf+mv5KWnqCuXX3uBiBsll+iMD82GJbsGs3huzH6qY2TySVFUCLov017B0RGz2Ap1WRB9w7h3o9CEwDuV5lQ== -"@desci-labs/desci-models@file:../desci-models": - version "0.2.7-rc6" +"@desci-labs/desci-models@0.2.8": + version "0.2.8" + resolved "https://registry.yarnpkg.com/@desci-labs/desci-models/-/desci-models-0.2.8.tgz#3dc2aa5d386435af678aaa931e842b71f95a6952" + integrity sha512-mjVnAxEvU+AOFY/O1HdfE62OfLDij9V6DVjLpl/JweEZxomDTiTHSMckmuHC5A7n0i1krlM7gRtLcTu5LrkH5g== dependencies: jsonld "^8.1.1" schema-dts "^1.1.2" From b3d6a7c0e975ccad75118d124d82879162468044 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Mon, 24 Jun 2024 11:11:12 +0200 Subject: [PATCH 183/278] refactor: move new routes to /nodes --- desci-server/src/controllers/doi/check.ts | 81 +------------------ desci-server/src/controllers/nodes/doi.ts | 89 +++++++++++++++++++++ desci-server/src/controllers/nodes/index.ts | 1 + desci-server/src/routes/v1/doi.ts | 13 +-- desci-server/src/routes/v1/nodes.ts | 12 ++- 5 files changed, 102 insertions(+), 94 deletions(-) create mode 100644 desci-server/src/controllers/nodes/doi.ts diff --git a/desci-server/src/controllers/doi/check.ts b/desci-server/src/controllers/doi/check.ts index 324d86aa..f046e789 100644 --- a/desci-server/src/controllers/doi/check.ts +++ b/desci-server/src/controllers/doi/check.ts @@ -1,26 +1,7 @@ -import { DocumentId } from '@automerge/automerge-repo'; -import { - CommonComponentPayload, - PdfComponent, - PdfComponentPayload, - ResearchObjectComponentType, -} from '@desci-labs/desci-models'; import { NextFunction, Request, Response } from 'express'; import { DoiError } from '../../core/doi/error.js'; -import { - BadRequestError, - ForbiddenError, - NotFoundError, - RequestWithNode, - SuccessResponse, - crossRefClient, - doiService, - getLatestManifestFromNode, - logger as parentLogger, -} from '../../internal.js'; -import { WorkSelectOptions } from '../../services/crossRef/definitions.js'; -import repoService from '../../services/repoService.js'; +import { BadRequestError, SuccessResponse, doiService, logger as parentLogger } from '../../internal.js'; export const checkMintability = async (req: Request, res: Response, _next: NextFunction) => { const { uuid } = req.params; @@ -49,63 +30,3 @@ export const getDoi = async (req: Request, res: Response, next: NextFunction) => const doi = await doiService.getDoiByDpidOrUuid(identifier); new SuccessResponse(doi).send(res); }; - -export const attachDoi = async (req: RequestWithNode, res: Response, _next: NextFunction) => { - const { uuid, path } = req.body; - - const logger = parentLogger.child({ - module: 'DOI::AttachDOI', - }); - - const node = req.node; - - const latestManifest = await getLatestManifestFromNode(node); - const componentIndex = latestManifest.components.findIndex( - (component) => - component.type === ResearchObjectComponentType.PDF && (component.payload as CommonComponentPayload).path === path, - ); - - if (componentIndex === -1) throw new BadRequestError('Component to attach DOI not a valid pdf'); - - const component = latestManifest.components[componentIndex] as PdfComponent; - - if (component.payload.doi) throw new ForbiddenError(`${component.subtype || component.type} already has a DOI`); - - const queryTitle = - component.payload.path.split('/').pop().replace(/\.pdf/g, '') || - component.name.replace(/\.pdf/g, '') || - component.payload.title; - - const works = await crossRefClient.listWorks({ - queryTitle, - rows: 5, - select: [WorkSelectOptions.DOI, WorkSelectOptions.TITLE, WorkSelectOptions.AUTHOR], - }); - - const doi = works?.data?.message?.items.find((item) => - item.title.some((t) => t.toLowerCase() === queryTitle.toLowerCase()), - ); - - logger.info({ doi, queryTitle }, 'DOI Response'); - - if (!(doi && works.ok)) { - logger.info({ data: works?.data?.message?.items }, 'DOI Not Found'); - throw new NotFoundError('DOI not found'); - } - - const response = await repoService.dispatchAction({ - uuid, - documentId: node.manifestDocumentId as DocumentId, - actions: [ - { - type: 'Update Component', - component: { ...component, payload: { ...component.payload, doi: [doi.DOI] } as PdfComponentPayload }, - componentIndex, - }, - ], - }); - - logger.info(response.manifest.components[componentIndex], 'component updated'); - - new SuccessResponse(true).send(res); -}; diff --git a/desci-server/src/controllers/nodes/doi.ts b/desci-server/src/controllers/nodes/doi.ts new file mode 100644 index 00000000..65b5672a --- /dev/null +++ b/desci-server/src/controllers/nodes/doi.ts @@ -0,0 +1,89 @@ +import { DocumentId } from '@automerge/automerge-repo'; +import { + CommonComponentPayload, + PdfComponent, + PdfComponentPayload, + ResearchObjectComponentType, +} from '@desci-labs/desci-models'; +import { NextFunction, Response } from 'express'; +import { z } from 'zod'; + +import { + BadRequestError, + ForbiddenError, + NotFoundError, + RequestWithNode, + SuccessResponse, + crossRefClient, + getLatestManifestFromNode, + logger as parentLogger, +} from '../../internal.js'; +import { WorkSelectOptions } from '../../services/crossRef/definitions.js'; +import repoService from '../../services/repoService.js'; + +export const attachDoiSchema = z.object({ + body: z.object({ + uuid: z.string(), + path: z.string().startsWith('root/', 'Invalid component path'), + }), +}); + +export const automateManuscriptDoi = async (req: RequestWithNode, res: Response, _next: NextFunction) => { + const { uuid, path } = req.body; + + const logger = parentLogger.child({ + module: 'DOI::AttachDOI', + }); + + const node = req.node; + + const latestManifest = await getLatestManifestFromNode(node); + const componentIndex = latestManifest.components.findIndex( + (component) => + component.type === ResearchObjectComponentType.PDF && (component.payload as CommonComponentPayload).path === path, + ); + + if (componentIndex === -1) throw new BadRequestError('Component to attach DOI not a valid pdf'); + + const component = latestManifest.components[componentIndex] as PdfComponent; + + if (component.payload.doi) throw new ForbiddenError(`${component.subtype || component.type} already has a DOI`); + + const queryTitle = + component.payload.path.split('/').pop().replace(/\.pdf/g, '') || + component.name.replace(/\.pdf/g, '') || + component.payload.title; + + const works = await crossRefClient.listWorks({ + queryTitle, + rows: 5, + select: [WorkSelectOptions.DOI, WorkSelectOptions.TITLE, WorkSelectOptions.AUTHOR], + }); + + const doi = works?.data?.message?.items.find((item) => + item.title.some((t) => t.toLowerCase() === queryTitle.toLowerCase()), + ); + + logger.info({ doi, queryTitle }, 'DOI Response'); + + if (!(doi && works.ok)) { + logger.info({ data: works?.data?.message?.items }, 'DOI Not Found'); + throw new NotFoundError('DOI not found'); + } + + const response = await repoService.dispatchAction({ + uuid, + documentId: node.manifestDocumentId as DocumentId, + actions: [ + { + type: 'Update Component', + component: { ...component, payload: { ...component.payload, doi: [doi.DOI] } as PdfComponentPayload }, + componentIndex, + }, + ], + }); + + logger.info(response.manifest.components[componentIndex], 'component updated'); + + new SuccessResponse(true).send(res); +}; diff --git a/desci-server/src/controllers/nodes/index.ts b/desci-server/src/controllers/nodes/index.ts index 1dccea38..f7618e26 100755 --- a/desci-server/src/controllers/nodes/index.ts +++ b/desci-server/src/controllers/nodes/index.ts @@ -11,3 +11,4 @@ export * from './prepublish.js'; export * from './share.js'; export * from './nodesCover.js'; export * from './manager.js'; +export * from './doi.js'; diff --git a/desci-server/src/routes/v1/doi.ts b/desci-server/src/routes/v1/doi.ts index 841597bc..8b8111aa 100644 --- a/desci-server/src/routes/v1/doi.ts +++ b/desci-server/src/routes/v1/doi.ts @@ -1,21 +1,10 @@ import { Router } from 'express'; -import { - asyncHander, - attachDoi, - attachDoiSchema, - checkMintability, - ensureNodeAccess, - ensureUser, - getDoi, - mintDoi, - validate, -} from '../../internal.js'; +import { asyncHander, checkMintability, ensureNodeAccess, ensureUser, getDoi, mintDoi } from '../../internal.js'; const router = Router(); router.post('/check/:uuid', [ensureUser, ensureNodeAccess], asyncHander(checkMintability)); router.post('/mint/:uuid', [ensureUser, ensureNodeAccess], asyncHander(mintDoi)); -router.post('/attach', [ensureUser, ensureNodeAccess, validate(attachDoiSchema)], asyncHander(attachDoi)); router.get('/:identifier', [ensureUser], asyncHander(getDoi)); export default router; diff --git a/desci-server/src/routes/v1/nodes.ts b/desci-server/src/routes/v1/nodes.ts index 85d487eb..db929ebd 100755 --- a/desci-server/src/routes/v1/nodes.ts +++ b/desci-server/src/routes/v1/nodes.ts @@ -7,6 +7,7 @@ import { getUserContributions } from '../../controllers/nodes/contributions/getU import { getUserContributionsAuthed } from '../../controllers/nodes/contributions/getUserContributionsAuthed.js'; import { updateContributor } from '../../controllers/nodes/contributions/update.js'; import { verifyContribution } from '../../controllers/nodes/contributions/verify.js'; +import { createDpid } from '../../controllers/nodes/createDpid.js'; import { dispatchDocumentChange, getNodeDocument } from '../../controllers/nodes/documents.js'; import { feed } from '../../controllers/nodes/feed.js'; import { frontmatterPreview } from '../../controllers/nodes/frontmatterPreview.js'; @@ -31,6 +32,7 @@ import { publishConsent, checkUserPublishConsent, checkPublishConsentSchema, + automateManuscriptDoi, } from '../../controllers/nodes/index.js'; import { retrieveTitle } from '../../controllers/nodes/legacyManifestApi.js'; import { preparePublishPackage } from '../../controllers/nodes/preparePublishPackage.js'; @@ -38,10 +40,9 @@ import { prepublish } from '../../controllers/nodes/prepublish.js'; import { listSharedNodes } from '../../controllers/nodes/sharedNodes.js'; import { thumbnails } from '../../controllers/nodes/thumbnails.js'; import { versionDetails } from '../../controllers/nodes/versionDetails.js'; -import { asyncHander, attachUser, validate } from '../../internal.js'; +import { asyncHander, attachDoiSchema, attachUser, validate } from '../../internal.js'; import { ensureNodeAccess, ensureWriteNodeAccess } from '../../middleware/authorisation.js'; import { ensureUser } from '../../middleware/permissions.js'; -import { createDpid } from '../../controllers/nodes/createDpid.js'; const router = Router(); @@ -84,6 +85,13 @@ router.get('/contributions/user', [ensureUser], getUserContributionsAuthed); router.post('/distribution', preparePublishPackage); router.post('/distribution/preview', [ensureUser], frontmatterPreview); +// doi automation +router.post( + '/attachManuscriptDoi', + [ensureUser, ensureNodeAccess, validate(attachDoiSchema)], + asyncHander(automateManuscriptDoi), +); + router.delete('/:uuid', [ensureUser], deleteNode); router.get('/feed', [], feed); From 30c1709dd76ba9ecce56b4bb0c5b0b0f930564c3 Mon Sep 17 00:00:00 2001 From: m0ar Date: Sat, 22 Jun 2024 11:46:37 +0200 Subject: [PATCH 184/278] Fix models publish script, bump version + publish --- desci-models/package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/desci-models/package.json b/desci-models/package.json index 8da34169..79d61787 100644 --- a/desci-models/package.json +++ b/desci-models/package.json @@ -1,12 +1,12 @@ { "name": "@desci-labs/desci-models", - "version": "0.2.8", + "version": "0.2.9", "description": "Data models for DeSci Nodes", "main": "dist/index.js", "types": "dist/index.d.ts", "repository": { "type": "git", - "url": "https://github.com/desci-labs/nodes.git", + "url": "git+https://github.com/desci-labs/nodes.git", "directory": "desci-models" }, "files": [ @@ -16,7 +16,7 @@ "test": "mocha -r ts-node/register --inspect tests/**/*.test.ts", "coverage": "nyc -r lcov -e .ts -x \"*.test.ts\" npm run test", "build": "tsc && npm run generate", - "doPublish": "npm publish --access public", + "doPublish": "npm run build && npm publish --access public", "generate": "ts-interface-builder src/ResearchObject.ts src/RoCrate.ts --ignore-generics" }, "author": "", From 7fcefbfcee3f3d252a227715e4703bed57b2b568 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Mon, 24 Jun 2024 11:49:38 +0200 Subject: [PATCH 185/278] install fixed model --- desci-server/package.json | 2 +- desci-server/src/controllers/nodes/doi.ts | 5 ++++- desci-server/yarn.lock | 8 ++++---- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/desci-server/package.json b/desci-server/package.json index 4c65949c..5bcb6d41 100755 --- a/desci-server/package.json +++ b/desci-server/package.json @@ -57,7 +57,7 @@ "@aws-sdk/client-s3": "^3.537.0", "@desci-labs/desci-codex-lib": "^1.1.7", "@desci-labs/desci-contracts": "0.2.5-rc7", - "@desci-labs/desci-models": "0.2.8", + "@desci-labs/desci-models": "0.2.9", "@honeycombio/opentelemetry-node": "^0.3.2", "@ipld/dag-pb": "^4.0.0", "@opentelemetry/api": "^1.8.0", diff --git a/desci-server/src/controllers/nodes/doi.ts b/desci-server/src/controllers/nodes/doi.ts index 65b5672a..0e4671bd 100644 --- a/desci-server/src/controllers/nodes/doi.ts +++ b/desci-server/src/controllers/nodes/doi.ts @@ -77,7 +77,10 @@ export const automateManuscriptDoi = async (req: RequestWithNode, res: Response, actions: [ { type: 'Update Component', - component: { ...component, payload: { ...component.payload, doi: [doi.DOI] } as PdfComponentPayload }, + component: { + ...component, + payload: { ...component.payload, doi: component.payload.doi.concat(doi.DOI) } as PdfComponentPayload, + }, componentIndex, }, ], diff --git a/desci-server/yarn.lock b/desci-server/yarn.lock index 32777b7a..96236887 100644 --- a/desci-server/yarn.lock +++ b/desci-server/yarn.lock @@ -2210,10 +2210,10 @@ resolved "https://registry.yarnpkg.com/@desci-labs/desci-contracts/-/desci-contracts-0.2.5-rc7.tgz#a8a49c9518107305be712bcbdbb352faa4057a44" integrity sha512-W1hf+mv5KWnqCuXX3uBiBsll+iMD82GJbsGs3huzH6qY2TySVFUCLov017B0RGz2Ap1WRB9w7h3o9CEwDuV5lQ== -"@desci-labs/desci-models@0.2.8": - version "0.2.8" - resolved "https://registry.yarnpkg.com/@desci-labs/desci-models/-/desci-models-0.2.8.tgz#3dc2aa5d386435af678aaa931e842b71f95a6952" - integrity sha512-mjVnAxEvU+AOFY/O1HdfE62OfLDij9V6DVjLpl/JweEZxomDTiTHSMckmuHC5A7n0i1krlM7gRtLcTu5LrkH5g== +"@desci-labs/desci-models@0.2.9": + version "0.2.9" + resolved "https://registry.yarnpkg.com/@desci-labs/desci-models/-/desci-models-0.2.9.tgz#a4a88958f23bebfdc544db6dff2458566fbe7830" + integrity sha512-6yK8CSiT9P1lZfPBd16w2N+th0/hR1whHPiAw1Bec+WMsGnRixGWxiU45j1z7EtmoZR4h8mbE2BAq+CyH754fQ== dependencies: jsonld "^8.1.1" schema-dts "^1.1.2" From 625a15279d3e19fed916e4c9019160da6d16b152 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Mon, 24 Jun 2024 11:17:31 +0000 Subject: [PATCH 186/278] adjustments to published node email service, add options for sending to all contributors/owner, verifiedOnly, etc --- .../nodes/contributions/prepubEmail.ts | 10 ++++--- desci-server/src/services/Contributors.ts | 7 +++-- desci-server/src/services/PublishServices.ts | 27 ++++++++++++++++--- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/desci-server/src/controllers/nodes/contributions/prepubEmail.ts b/desci-server/src/controllers/nodes/contributions/prepubEmail.ts index a67e1e57..0afbaaf3 100644 --- a/desci-server/src/controllers/nodes/contributions/prepubEmail.ts +++ b/desci-server/src/controllers/nodes/contributions/prepubEmail.ts @@ -56,12 +56,16 @@ export const emailPublishPackage = async ( }); if (!distPdfEntry) return res.status(404).json({ ok: false, error: 'Distribution PDF not found' }); - // Fire off email to all contributors - await publishServices.sendVersionUpdateEmailToAllContributors({ node, manuscriptCid: prepubDistPdfCid }); + // Fire off email + await publishServices.sendVersionUpdateEmailToAllContributors({ + node, + manuscriptCid: prepubDistPdfCid, + ownerOnly: !emailAllContributors, + }); return res.status(200).json({ ok: true }); } catch (e) { logger.error({ error: e.message }); - return res.status(500).json({ ok: false, error: 'Failed sending distribution package' }); + return res.status(500).json({ ok: false, error: 'Failed sending distribution package email' }); } }; diff --git a/desci-server/src/services/Contributors.ts b/desci-server/src/services/Contributors.ts index 87867839..8c1adb03 100644 --- a/desci-server/src/services/Contributors.ts +++ b/desci-server/src/services/Contributors.ts @@ -191,9 +191,12 @@ class ContributorService { * To be used within the backend, if the data from this is returned to the frontend, it can potentially leak data, * opt for retrieveSelectedContributionsForNode instead if the data is to be returned to the frontend */ - async retrieveAllVerifiedContributionsForNode(node: Node): Promise<(NodeContribution & { user: User })[]> { + async retrieveAllContributionsForNode( + node: Node, + verifiedOnly?: boolean, + ): Promise<(NodeContribution & { user: User })[]> { return prisma.nodeContribution.findMany({ - where: { nodeId: node.id, verified: true }, + where: { nodeId: node.id, ...(verifiedOnly && { verified: true }) }, include: { user: true }, }); } diff --git a/desci-server/src/services/PublishServices.ts b/desci-server/src/services/PublishServices.ts index 15dfbe57..35343ccf 100644 --- a/desci-server/src/services/PublishServices.ts +++ b/desci-server/src/services/PublishServices.ts @@ -1,4 +1,4 @@ -import { Node } from '@prisma/client'; +import { Node, NodeContribution, User } from '@prisma/client'; import sgMail from '@sendgrid/mail'; import { prisma } from '../client.js'; @@ -17,8 +17,18 @@ const logger = parentLogger.child({ }); export class PublishServices { - async sendVersionUpdateEmailToAllContributors({ node, manuscriptCid }: { node: Node; manuscriptCid: string }) { - const contributors = await contributorService.retrieveAllVerifiedContributionsForNode(node); + async sendVersionUpdateEmailToAllContributors({ + node, + manuscriptCid, + ownerOnly, + verifiedOnly = false, + }: { + node: Node; + manuscriptCid: string; + ownerOnly?: boolean; + verifiedOnly?: boolean; + }) { + const contributors = ownerOnly ? [] : await contributorService.retrieveAllContributionsForNode(node, verifiedOnly); const nodeOwner = await prisma.user.findUnique({ where: { id: node.ownerId } }); const manifest = await getLatestManifestFromNode(node); const dpid = manifest.dpid?.id; @@ -31,6 +41,15 @@ export class PublishServices { ); } + const ownerEmailIncluded = contributors.find((c) => c.email === nodeOwner.email); + if (!ownerEmailIncluded) { + // Add the owner to the email list incase they forgot to add themselves as a contributor + const ownerContributor = { email: nodeOwner.email, name: nodeOwner.name } as unknown as NodeContribution & { + user: User; + }; + contributors.push(ownerContributor); + } + const emailPromises = contributors.map((contributor) => { const emailHtml = NodeUpdatedEmailHtml({ nodeOwner: nodeOwner.name, @@ -52,7 +71,7 @@ export class PublishServices { return emailMsg; }); - if (process.env.NODE_ENV === 'production') { + if (process.env.SHOULD_SEND_EMAIL && process.env.SENDGRID_API_KEY) { await Promise.allSettled(emailPromises.map((emailMsg) => sgMail.send(emailMsg))); } else { logger.info( From f351dc51ead1c2b3a480bc0c2bcede54a560a338 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Mon, 24 Jun 2024 11:28:43 +0000 Subject: [PATCH 187/278] add email route --- .../src/controllers/nodes/contributions/prepubEmail.ts | 6 +++++- desci-server/src/routes/v1/nodes.ts | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/desci-server/src/controllers/nodes/contributions/prepubEmail.ts b/desci-server/src/controllers/nodes/contributions/prepubEmail.ts index 0afbaaf3..373b8c4c 100644 --- a/desci-server/src/controllers/nodes/contributions/prepubEmail.ts +++ b/desci-server/src/controllers/nodes/contributions/prepubEmail.ts @@ -1,3 +1,4 @@ +import { User } from '@prisma/client'; import type { Request, Response } from 'express'; import { prisma } from '../../../client.js'; @@ -25,9 +26,10 @@ type EmailPublishPackageErrorResponse = { * Generates a prepublish package for a published node (at the moment just the distro PDF) */ export const emailPublishPackage = async ( - req: Request<{ emailAllContributors?: boolean }, any, EmailPublishPackageReqBodyParams>, + req: Request<{ emailAllContributors?: boolean }, any, EmailPublishPackageReqBodyParams> & { user: User }, res: Response, ) => { + const user = req.user; const { prepubDistPdfCid, nodeUuid } = req.body; const { emailAllContributors } = req.query; const logger = parentLogger.child({ @@ -35,6 +37,7 @@ export const emailPublishPackage = async ( prepubDistPdfCid, emailAllContributors, nodeUuid, + userId: user.id, }); // debugger; logger.trace({ fn: 'Distributing Publish Package' }); @@ -46,6 +49,7 @@ export const emailPublishPackage = async ( const node = await prisma.node.findFirst({ where: { uuid: ensureUuidEndsWithDot(nodeUuid), + ownerId: user.id, }, }); diff --git a/desci-server/src/routes/v1/nodes.ts b/desci-server/src/routes/v1/nodes.ts index 85d487eb..82bf8a42 100755 --- a/desci-server/src/routes/v1/nodes.ts +++ b/desci-server/src/routes/v1/nodes.ts @@ -5,8 +5,10 @@ import { deleteContributor } from '../../controllers/nodes/contributions/delete. import { getNodeContributions } from '../../controllers/nodes/contributions/getNodeContributions.js'; import { getUserContributions } from '../../controllers/nodes/contributions/getUserContributions.js'; import { getUserContributionsAuthed } from '../../controllers/nodes/contributions/getUserContributionsAuthed.js'; +import { emailPublishPackage } from '../../controllers/nodes/contributions/prepubEmail.js'; import { updateContributor } from '../../controllers/nodes/contributions/update.js'; import { verifyContribution } from '../../controllers/nodes/contributions/verify.js'; +import { createDpid } from '../../controllers/nodes/createDpid.js'; import { dispatchDocumentChange, getNodeDocument } from '../../controllers/nodes/documents.js'; import { feed } from '../../controllers/nodes/feed.js'; import { frontmatterPreview } from '../../controllers/nodes/frontmatterPreview.js'; @@ -41,7 +43,6 @@ import { versionDetails } from '../../controllers/nodes/versionDetails.js'; import { asyncHander, attachUser, validate } from '../../internal.js'; import { ensureNodeAccess, ensureWriteNodeAccess } from '../../middleware/authorisation.js'; import { ensureUser } from '../../middleware/permissions.js'; -import { createDpid } from '../../controllers/nodes/createDpid.js'; const router = Router(); @@ -83,6 +84,7 @@ router.get('/contributions/user/:userId', [], getUserContributions); router.get('/contributions/user', [ensureUser], getUserContributionsAuthed); router.post('/distribution', preparePublishPackage); router.post('/distribution/preview', [ensureUser], frontmatterPreview); +router.post('/distribution/email', [ensureUser], emailPublishPackage); router.delete('/:uuid', [ensureUser], deleteNode); From 0bfaaae069a07eaca7ddeee02f83f1a91f72e489 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Mon, 24 Jun 2024 17:59:25 +0200 Subject: [PATCH 188/278] doi automation using upload manuscript title --- desci-server/src/controllers/doi/schema.ts | 1 + desci-server/src/controllers/nodes/doi.ts | 73 +++++++++++++++---- desci-server/src/routes/v1/nodes.ts | 2 +- .../src/services/AutomatedMetadata.ts | 7 +- desci-server/src/services/crossRef/client.ts | 50 ++++++++++++- .../src/services/crossRef/definitions.ts | 3 +- 6 files changed, 114 insertions(+), 22 deletions(-) diff --git a/desci-server/src/controllers/doi/schema.ts b/desci-server/src/controllers/doi/schema.ts index 1220604c..35ec9cec 100644 --- a/desci-server/src/controllers/doi/schema.ts +++ b/desci-server/src/controllers/doi/schema.ts @@ -4,5 +4,6 @@ export const attachDoiSchema = z.object({ body: z.object({ uuid: z.string(), path: z.string().startsWith('root/', 'Invalid component path'), + publication: z.boolean().optional(), }), }); diff --git a/desci-server/src/controllers/nodes/doi.ts b/desci-server/src/controllers/nodes/doi.ts index 0e4671bd..5a02f3a8 100644 --- a/desci-server/src/controllers/nodes/doi.ts +++ b/desci-server/src/controllers/nodes/doi.ts @@ -1,9 +1,11 @@ import { DocumentId } from '@automerge/automerge-repo'; import { CommonComponentPayload, + ManifestActions, PdfComponent, PdfComponentPayload, ResearchObjectComponentType, + ResearchObjectV1AuthorRole, } from '@desci-labs/desci-models'; import { NextFunction, Response } from 'express'; import { z } from 'zod'; @@ -18,7 +20,8 @@ import { getLatestManifestFromNode, logger as parentLogger, } from '../../internal.js'; -import { WorkSelectOptions } from '../../services/crossRef/definitions.js'; +import { MetadataResponse } from '../../services/AutomatedMetadata.js'; +import { Work, WorkSelectOptions } from '../../services/crossRef/definitions.js'; import repoService from '../../services/repoService.js'; export const attachDoiSchema = z.object({ @@ -29,10 +32,11 @@ export const attachDoiSchema = z.object({ }); export const automateManuscriptDoi = async (req: RequestWithNode, res: Response, _next: NextFunction) => { - const { uuid, path } = req.body; + const { uuid, path, prepublication } = req.body; const logger = parentLogger.child({ module: 'DOI::AttachDOI', + body: req.body, }); const node = req.node; @@ -60,6 +64,8 @@ export const automateManuscriptDoi = async (req: RequestWithNode, res: Response, select: [WorkSelectOptions.DOI, WorkSelectOptions.TITLE, WorkSelectOptions.AUTHOR], }); + logger.info({ works }, 'Works Response'); + const doi = works?.data?.message?.items.find((item) => item.title.some((t) => t.toLowerCase() === queryTitle.toLowerCase()), ); @@ -71,22 +77,63 @@ export const automateManuscriptDoi = async (req: RequestWithNode, res: Response, throw new NotFoundError('DOI not found'); } + // todo: pull metadata from crossrefClient#getDoiMetadata + + const actions: ManifestActions[] = [ + { + type: 'Update Component', + component: { + ...component, + payload: { + ...component.payload, + doi: component.payload?.doi ? component.payload.doi.concat([doi.DOI]) : [doi.DOI], + } as PdfComponentPayload, + }, + componentIndex, + }, + ]; + + if (prepublication) { + const { title, authors } = transformWorkToMetadata(doi); + actions.push({ type: 'Update Title', title }); + if (authors.length > 0) { + actions.push({ + type: 'Add Contributors', + contributors: authors.map((author) => ({ + name: author.name, + role: ResearchObjectV1AuthorRole.AUTHOR, + ...(author.affiliations.length > 0 && { organizations: author.affiliations }), + ...(author.orcid && { orcid: author.orcid }), + })), + }); + } + } + + logger.info({ actions }, 'Automate DOI actions'); + const response = await repoService.dispatchAction({ uuid, documentId: node.manifestDocumentId as DocumentId, - actions: [ - { - type: 'Update Component', - component: { - ...component, - payload: { ...component.payload, doi: component.payload.doi.concat(doi.DOI) } as PdfComponentPayload, - }, - componentIndex, - }, - ], + actions, }); - logger.info(response.manifest.components[componentIndex], 'component updated'); + logger.info({ response: response.manifest.components[componentIndex] }, 'component updated'); new SuccessResponse(true).send(res); }; + +const formatOrcidUrl = (orcid: string) => { + const url = new URL(orcid); + return url.pathname.replace('/', ''); +}; + +const transformWorkToMetadata = (work: Work): MetadataResponse => { + const title = work.title[0]; + const authors = work.author.map((author) => ({ + orcid: author.ORCID ? formatOrcidUrl(author.ORCID) : null, + name: author.given ? `${author.given} ${author.family}`.trim() : author.name, + affiliations: author.affiliation.map((org) => ({ name: org.name, id: '' })), + })); + + return { title, authors, pdfUrl: '', keywords: [] }; +}; diff --git a/desci-server/src/routes/v1/nodes.ts b/desci-server/src/routes/v1/nodes.ts index 0737dd8b..1b281a1b 100755 --- a/desci-server/src/routes/v1/nodes.ts +++ b/desci-server/src/routes/v1/nodes.ts @@ -97,7 +97,7 @@ router.post('/generate-metadata', [ensureUser, validate(generateMetadataSchema)] // doi automation router.post( - '/attachManuscriptDoi', + '/:uuid/attachManuscriptDoi', [ensureUser, ensureNodeAccess, validate(attachDoiSchema)], asyncHander(automateManuscriptDoi), ); diff --git a/desci-server/src/services/AutomatedMetadata.ts b/desci-server/src/services/AutomatedMetadata.ts index 6e8f1d95..76621f8b 100644 --- a/desci-server/src/services/AutomatedMetadata.ts +++ b/desci-server/src/services/AutomatedMetadata.ts @@ -25,6 +25,7 @@ export type AutomatedMetadataResponse = { affiliation: string; name: string; role: string; + ror: string; }; }; datePublished: [number, number, number]; // [year, month, day] @@ -45,7 +46,7 @@ export type AutomatedMetadataResponse = { }; export type MetadataResponse = { - authors: Array<{ orcid: string; name: string; affiliation: string }>; + authors: Array<{ orcid: string; name: string; affiliations: { name: string; id: string }[] }>; title: string; pdfUrl: string | null; keywords: string[]; @@ -139,7 +140,7 @@ export class AutomatedMetadataClient { const authors = output?.creator ? Object.entries(output.creator).map(([name, creator]) => ({ - affiliation: creator.affiliation, + affiliations: [{ name: creator.affiliation, id: creator.ror }], name, ...(creator['@id'] && { orcid: creator['@id'] }), })) @@ -165,7 +166,7 @@ export class AutomatedMetadataClient { name: author.name, orcid: author.orcid, role: ResearchObjectV1AuthorRole.AUTHOR, - organisations: [{ id: author.affiliation, name: author.affiliation }], + organisations: author.affiliations, // [{ id: author.affiliation, name: author.affiliation }], }) as ResearchObjectV1Author, ), }); // diff --git a/desci-server/src/services/crossRef/client.ts b/desci-server/src/services/crossRef/client.ts index 3f993b5a..ad9c865b 100644 --- a/desci-server/src/services/crossRef/client.ts +++ b/desci-server/src/services/crossRef/client.ts @@ -59,11 +59,11 @@ class CrossRefClient { } } - logger.info(params, 'API INFO'); + logger.info({ params }, 'API INFO'); if (typeof params === 'object') { params = keysToDotsAndDashses(params); - logger.info(params, 'parsed params'); + logger.info({ params }, 'parsed params'); } for (const [key, value] of Object.entries(params)) { @@ -84,12 +84,12 @@ class CrossRefClient { url = url.slice(0, -1); url = encodeURI(url); - logger.info(url, 'url params'); + logger.info({ url }, 'url params'); const request = new Request(url, config); try { return await this.performFetch>(request); } catch (error) { - logger.error(error, 'LIST WORKS API ERROR'); + logger.error({ error }, 'LIST WORKS API ERROR'); // retry after 1 second await delay(1000); @@ -98,6 +98,48 @@ class CrossRefClient { } } + /** + * Returns a list of all works (journal articles, + * conference proceedings, books, components, etc), + */ + async getDoiMetadata(doi: string) { + const params: { [k: string]: any } = {}; + let url = `$https://www.crossref.org/openurl/?pid=myemail@crossref.org&format=unixref&id=${doi}`; + const config: RequestInit = { + method: 'GET', + mode: 'cors', + headers: {}, + }; + + // polite api + if (this._mailto) { + params['pid'] = this._mailto; + } + + params['format'] = 'unixref'; + params['id'] = doi; + + logger.info(params, 'API INFO'); + + for (const [key, value] of Object.entries(params)) { + url += `${key}=${value}&`; + } + + url = url.slice(0, -1); + url = encodeURI(url); + logger.info(url, 'url params'); + const request = new Request(url, config); + try { + const response = await fetch(request); + if (!response.ok) return null; + const body = await response.text(); + logger.info(body, 'XML RESPONSE'); + } catch (error) { + logger.error(error, 'OPEN URL SEARCH ERROR'); + return null; + } + } + async performFetch(request: Request) { const responseFromCache = await getFromCache(request.url); // logger.info(responseFromCache, 'DOI From Cache'); diff --git a/desci-server/src/services/crossRef/definitions.ts b/desci-server/src/services/crossRef/definitions.ts index 49a2f2f1..722cd840 100644 --- a/desci-server/src/services/crossRef/definitions.ts +++ b/desci-server/src/services/crossRef/definitions.ts @@ -32,8 +32,9 @@ export interface Work { export interface Author { given: string; family: string; + name?: string; sequence: string; - affiliation: unknown[]; + affiliation: { name: string }[]; ORCID?: string; authenticatedOrcid?: boolean; } From a0b77169722085b8c0037bcfbe4bcd85e2b8329a Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Mon, 24 Jun 2024 16:50:04 +0000 Subject: [PATCH 189/278] type fix --- .../controllers/nodes/contributions/prepubEmail.ts | 11 ++++++++++- desci-server/src/services/PublishServices.ts | 14 ++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/desci-server/src/controllers/nodes/contributions/prepubEmail.ts b/desci-server/src/controllers/nodes/contributions/prepubEmail.ts index 373b8c4c..a39524f5 100644 --- a/desci-server/src/controllers/nodes/contributions/prepubEmail.ts +++ b/desci-server/src/controllers/nodes/contributions/prepubEmail.ts @@ -12,6 +12,15 @@ export type EmailPublishPackageReqBodyParams = { nodeUuid: string; }; +export type EmailPublishPackageRequest = Request< + never, + never, + EmailPublishPackageReqBodyParams, + { emailAllContributors?: boolean } +> & { + user: User; // Added by the ensureUser middleware +}; + type EmailPublishPackageResponse = { ok: true; }; @@ -26,7 +35,7 @@ type EmailPublishPackageErrorResponse = { * Generates a prepublish package for a published node (at the moment just the distro PDF) */ export const emailPublishPackage = async ( - req: Request<{ emailAllContributors?: boolean }, any, EmailPublishPackageReqBodyParams> & { user: User }, + req: EmailPublishPackageRequest, res: Response, ) => { const user = req.user; diff --git a/desci-server/src/services/PublishServices.ts b/desci-server/src/services/PublishServices.ts index 35343ccf..2cf3e0f0 100644 --- a/desci-server/src/services/PublishServices.ts +++ b/desci-server/src/services/PublishServices.ts @@ -68,11 +68,21 @@ export class PublishServices { html: emailHtml, }; - return emailMsg; + return { contributor, emailMsg }; }); if (process.env.SHOULD_SEND_EMAIL && process.env.SENDGRID_API_KEY) { - await Promise.allSettled(emailPromises.map((emailMsg) => sgMail.send(emailMsg))); + await Promise.allSettled( + emailPromises.map((emailEntry) => { + // if (emailEntry.contributor.id !== undefined) { + // prisma.nodeContribution.update({ + // where: { id: emailEntry.contributor.id }, + // data: { inviteSent: true }, + // }); + // } + return sgMail.send(emailEntry.emailMsg); + }), + ); } else { logger.info( { nodeEnv: process.env.NODE_ENV }, From 82921b870470e37df26b737147b265a219b54dbb Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Mon, 24 Jun 2024 16:50:38 +0000 Subject: [PATCH 190/278] add contributor invite sent migration --- .../migrations/20240624161728_invites_sent_bool/migration.sql | 2 ++ desci-server/prisma/schema.prisma | 1 + 2 files changed, 3 insertions(+) create mode 100644 desci-server/prisma/migrations/20240624161728_invites_sent_bool/migration.sql diff --git a/desci-server/prisma/migrations/20240624161728_invites_sent_bool/migration.sql b/desci-server/prisma/migrations/20240624161728_invites_sent_bool/migration.sql new file mode 100644 index 00000000..30ace797 --- /dev/null +++ b/desci-server/prisma/migrations/20240624161728_invites_sent_bool/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "NodeContribution" ADD COLUMN "inviteSent" BOOLEAN NOT NULL DEFAULT false; diff --git a/desci-server/prisma/schema.prisma b/desci-server/prisma/schema.prisma index de96007a..753a86ef 100755 --- a/desci-server/prisma/schema.prisma +++ b/desci-server/prisma/schema.prisma @@ -519,6 +519,7 @@ model NodeContribution { orcid String? deleted Boolean @default(false) deletedAt DateTime? + inviteSent Boolean @default(false) node Node @relation(fields: [nodeId], references: [id]) user User? @relation(fields: [userId], references: [id]) From 477d2e208d7bb05e7b4b418a3c629b5fa5d3427a Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Mon, 24 Jun 2024 16:51:19 +0000 Subject: [PATCH 191/278] keep track of invites sent --- desci-server/src/controllers/nodes/contributions/create.ts | 4 ++++ desci-server/src/controllers/nodes/contributions/update.ts | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/desci-server/src/controllers/nodes/contributions/create.ts b/desci-server/src/controllers/nodes/contributions/create.ts index 7d3318a9..0d7a489e 100644 --- a/desci-server/src/controllers/nodes/contributions/create.ts +++ b/desci-server/src/controllers/nodes/contributions/create.ts @@ -100,6 +100,10 @@ export const addContributor = async (req: AddContributorRequest, res: Response Date: Mon, 24 Jun 2024 16:51:46 +0000 Subject: [PATCH 192/278] fix prepub email template --- desci-server/src/templates/emails/NodeUpdated.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desci-server/src/templates/emails/NodeUpdated.tsx b/desci-server/src/templates/emails/NodeUpdated.tsx index b65e8204..bf6d0d41 100644 --- a/desci-server/src/templates/emails/NodeUpdated.tsx +++ b/desci-server/src/templates/emails/NodeUpdated.tsx @@ -34,7 +34,7 @@ export const NodeUpdated = ({ - DPID {nodeDpid} has been updated to version ${versionUpdate} + DPID {nodeDpid} has been updated to version {versionUpdate} {nodeOwner} has published an updated version of their research object titled{' '} From 47664c6d5ae4a9347cd4414c01022080897218fa Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Mon, 24 Jun 2024 16:55:00 +0000 Subject: [PATCH 193/278] update node contributor authed map to return invite sent data --- desci-server/src/services/Contributors.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/desci-server/src/services/Contributors.ts b/desci-server/src/services/Contributors.ts index 8c1adb03..839694b3 100644 --- a/desci-server/src/services/Contributors.ts +++ b/desci-server/src/services/Contributors.ts @@ -181,6 +181,7 @@ class ContributorService { userId: contributor.user?.id, deleted: contributor.deleted, deletedAt: contributor.deletedAt, + ...(authedMode && { inviteSent: contributor.inviteSent }), ...(authedMode && { email: contributor.email, orcid: contributor.orcid }), }; return acc; From 1b10fff95629dca1ccb5a52b790dcad783cfc73a Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Mon, 24 Jun 2024 18:17:50 +0000 Subject: [PATCH 194/278] setup multer for uploads to isolated media server --- desci-media-isolated/package-lock.json | 168 +++++++++++++++--- desci-media-isolated/package.json | 2 + .../src/middleware/uploadHandler.ts | 30 ++++ .../src/routes/v1/thumbnails.ts | 3 +- 4 files changed, 181 insertions(+), 22 deletions(-) create mode 100644 desci-media-isolated/src/middleware/uploadHandler.ts diff --git a/desci-media-isolated/package-lock.json b/desci-media-isolated/package-lock.json index b31f36ba..1c31948d 100644 --- a/desci-media-isolated/package-lock.json +++ b/desci-media-isolated/package-lock.json @@ -9,10 +9,12 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "@types/multer": "^1.4.11", "axios": "^1.6.7", "express": "^4.18.2", "filepreview_ts": "^1.0.0", "helmet": "^7.1.0", + "multer": "^1.4.5-lts.1", "pdf-lib": "^1.17.1", "pdf2pic": "^3.1.1", "pdflib-fontkit": "^1.8.11", @@ -314,7 +316,6 @@ "version": "1.19.5", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", - "dev": true, "dependencies": { "@types/connect": "*", "@types/node": "*" @@ -324,7 +325,6 @@ "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dev": true, "dependencies": { "@types/node": "*" } @@ -333,7 +333,6 @@ "version": "4.17.21", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", - "dev": true, "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -345,7 +344,6 @@ "version": "4.17.43", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz", "integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==", - "dev": true, "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -356,8 +354,7 @@ "node_modules/@types/http-errors": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", - "dev": true + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" }, "node_modules/@types/json-schema": { "version": "7.0.15", @@ -368,14 +365,20 @@ "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "dev": true + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + }, + "node_modules/@types/multer": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.11.tgz", + "integrity": "sha512-svK240gr6LVWvv3YGyhLlA+6LRRWA4mnGIU7RcNmgjBYFl6665wcXrRfxGp5tEPVHUNm5FMcmq7too9bxCwX/w==", + "dependencies": { + "@types/express": "*" + } }, "node_modules/@types/node": { "version": "20.11.19", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz", "integrity": "sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==", - "dev": true, "dependencies": { "undici-types": "~5.26.4" } @@ -383,14 +386,12 @@ "node_modules/@types/qs": { "version": "6.9.11", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz", - "integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==", - "dev": true + "integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==" }, "node_modules/@types/range-parser": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "dev": true + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" }, "node_modules/@types/semver": { "version": "7.5.7", @@ -402,7 +403,6 @@ "version": "0.17.4", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "dev": true, "dependencies": { "@types/mime": "^1", "@types/node": "*" @@ -412,7 +412,6 @@ "version": "1.15.5", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", - "dev": true, "dependencies": { "@types/http-errors": "*", "@types/mime": "*", @@ -838,6 +837,11 @@ "node": ">= 8" } }, + "node_modules/append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==" + }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -952,8 +956,18 @@ "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } }, "node_modules/bytes": { "version": "3.1.2", @@ -1065,6 +1079,20 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -1097,6 +1125,11 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -2109,6 +2142,11 @@ "node": ">=8" } }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -2294,7 +2332,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -2316,6 +2353,34 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "node_modules/multer": { + "version": "1.4.5-lts.1", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz", + "integrity": "sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==", + "dependencies": { + "append-field": "^1.0.0", + "busboy": "^1.0.0", + "concat-stream": "^1.5.2", + "mkdirp": "^0.5.4", + "object-assign": "^4.1.1", + "type-is": "^1.6.4", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/multer/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -2339,6 +2404,14 @@ "node": ">=0.10.0" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -2541,6 +2614,11 @@ "node": ">= 0.8.0" } }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -2628,6 +2706,25 @@ "node": ">= 0.8" } }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -2895,6 +2992,27 @@ "node": ">= 0.8" } }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -3144,6 +3262,11 @@ "node": ">= 0.6" } }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, "node_modules/typescript": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", @@ -3160,8 +3283,7 @@ "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" }, "node_modules/unpipe": { "version": "1.0.0", @@ -3180,6 +3302,11 @@ "punycode": "^2.1.0" } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -3227,7 +3354,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, "engines": { "node": ">=0.4" } diff --git a/desci-media-isolated/package.json b/desci-media-isolated/package.json index 410743b2..a82ec4b8 100644 --- a/desci-media-isolated/package.json +++ b/desci-media-isolated/package.json @@ -13,10 +13,12 @@ "author": "", "license": "ISC", "dependencies": { + "@types/multer": "^1.4.11", "axios": "^1.6.7", "express": "^4.18.2", "filepreview_ts": "^1.0.0", "helmet": "^7.1.0", + "multer": "^1.4.5-lts.1", "pdf-lib": "^1.17.1", "pdf2pic": "^3.1.1", "pdflib-fontkit": "^1.8.11", diff --git a/desci-media-isolated/src/middleware/uploadHandler.ts b/desci-media-isolated/src/middleware/uploadHandler.ts new file mode 100644 index 00000000..f8d764fc --- /dev/null +++ b/desci-media-isolated/src/middleware/uploadHandler.ts @@ -0,0 +1,30 @@ +import type { NextFunction, Request, Response } from 'express'; +import multer from 'multer'; +import path from 'path'; +import { fileURLToPath } from 'url'; +import { TEMP_DIR, THUMBNAIL_FILES_DIR } from '../config/index.js'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const BASE_TEMP_DIR = path.resolve(__dirname, '../..', TEMP_DIR); + +const storage = multer.diskStorage({ + destination: function (req, file, cb) { + cb(null, path.join(BASE_TEMP_DIR, THUMBNAIL_FILES_DIR)); + }, + filename: function (req, file, cb) { + const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9); + cb(null, file.fieldname + '-' + uniqueSuffix + path.extname(file.originalname)); + }, +}); + +const upload = multer({ storage: storage }); + +// Middleware to determine if it's a file upload or JSON request +export const uploadHandler = (req: Request, res: Response, next: NextFunction) => { + if (req.is('multipart/form-data')) { + upload.single('file')(req, res, next); + } else { + next(); + } +}; diff --git a/desci-media-isolated/src/routes/v1/thumbnails.ts b/desci-media-isolated/src/routes/v1/thumbnails.ts index 0ca747e6..206f48da 100644 --- a/desci-media-isolated/src/routes/v1/thumbnails.ts +++ b/desci-media-isolated/src/routes/v1/thumbnails.ts @@ -1,8 +1,9 @@ import { Router } from 'express'; import { generateThumbnail } from '../../controllers/thumbnails/create.js'; +import { uploadHandler } from '../../middleware/uploadHandler.js'; const router = Router(); -router.post('/', generateThumbnail); +router.post('/', uploadHandler, generateThumbnail); export default router; From 32b089fd5bb54006b123b946d7f5cacc01f10d67 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Mon, 24 Jun 2024 18:22:08 +0000 Subject: [PATCH 195/278] update thumbnail controller to accept cid/file stream --- .../src/controllers/thumbnails/create.ts | 40 ++++++++++++------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/desci-media-isolated/src/controllers/thumbnails/create.ts b/desci-media-isolated/src/controllers/thumbnails/create.ts index 912bdd25..360883e4 100644 --- a/desci-media-isolated/src/controllers/thumbnails/create.ts +++ b/desci-media-isolated/src/controllers/thumbnails/create.ts @@ -7,36 +7,48 @@ import { TEMP_DIR, THUMBNAIL_OUTPUT_DIR } from '../../config/index.js'; import { BadRequestError, NotFoundError } from '../../utils/customErrors.js'; export type GenerateThumbnailRequestBody = { - cid: string; - fileName: string; + cid?: string; + fileName?: string; }; +interface GenerateThumbnailRequest extends Request { + body: GenerateThumbnailRequestBody; + query: { + height?: string; + }; + file?: Express.Multer.File; +} + const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const BASE_TEMP_DIR = path.resolve(__dirname, '../../..', TEMP_DIR); -export const generateThumbnail = async ( - req: Request, - res: Response, -) => { +export const generateThumbnail = async (req: GenerateThumbnailRequest, res: Response) => { const { cid, fileName } = req.body; - const { height = 300 } = req.query; - if (!cid) throw new BadRequestError('Missing cid in request body'); - if (!fileName) throw new BadRequestError('Missing fileName in request body'); + const height = parseInt(req.query.height || '300'); + + const finalFileName = fileName || (req.file && req.file.originalname); + if (!finalFileName) throw new BadRequestError('Missing fileName in request body or file upload'); try { - const thumbnailPath = await ThumbnailsService.generateThumbnail(cid, fileName, height); + let thumbnailPath: string; + + if (cid) { + thumbnailPath = await ThumbnailsService.generateThumbnailFromCid(cid, finalFileName, height); + } else if (req.file) { + thumbnailPath = await ThumbnailsService.generateThumbnailFromFile(req.file.path, finalFileName, height); + } else { + throw new BadRequestError('Either cid or file is required'); + } + const fullThumbnailPath = path.join(BASE_TEMP_DIR, THUMBNAIL_OUTPUT_DIR, thumbnailPath); - // Check if the file exists before attempting to stream it fs.access(fullThumbnailPath, fs.constants.F_OK, (err) => { if (err) { - throw new NotFoundError(`Thumbnail not found for file with cid: ${cid}`); + throw new NotFoundError(`Thumbnail not found for file: ${finalFileName}`); } - res.setHeader('Content-Type', 'image/png'); const readStream = fs.createReadStream(fullThumbnailPath); - readStream.pipe(res); }); From 3f7a897662f123481afd94cfc9ef0e5ffd553e69 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Mon, 24 Jun 2024 18:22:46 +0000 Subject: [PATCH 196/278] separate thumbnail gen logic for either cid based or file based for ephemeral generations --- .../src/services/thumbnails.ts | 47 +++++++++++-------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/desci-media-isolated/src/services/thumbnails.ts b/desci-media-isolated/src/services/thumbnails.ts index 2dae30b6..8303a979 100644 --- a/desci-media-isolated/src/services/thumbnails.ts +++ b/desci-media-isolated/src/services/thumbnails.ts @@ -7,7 +7,6 @@ import fs from 'fs'; import { fileURLToPath } from 'url'; const THUMBNAIL_DIMENSIONS = { - // width: 220, height: 300, keepAspect: true, quality: '100', @@ -19,39 +18,49 @@ const __dirname = path.dirname(__filename); const BASE_TEMP_DIR = path.resolve(__dirname, '../..', TEMP_DIR); export class ThumbnailsService { - static async generateThumbnail(cid: string, fileName: string, heightPx: number) { + static async generateThumbnailFromCid(cid: string, fileName: string, heightPx: number) { const extension = '.' + fileName.split('.').pop(); if (!extension) throw new BadRequestError('Invalid file name, requires extension'); + const tempFilePath = path.join(BASE_TEMP_DIR, THUMBNAIL_FILES_DIR, `${cid + extension}`); - const thumbnailPath = this.getThumbnailPath(cid); - const exportPath = path.join(BASE_TEMP_DIR, THUMBNAIL_OUTPUT_DIR, thumbnailPath); - // debugger; await IpfsService.saveFile(cid, tempFilePath); + + return this.generateThumbnail(tempFilePath, cid, heightPx); + } + + static async generateThumbnailFromFile(filePath: string, fileName: string, heightPx: number) { + const extension = '.' + fileName.split('.').pop(); + if (!extension) throw new BadRequestError('Invalid file name, requires extension'); + + const identifier = path.basename(filePath, extension); + return this.generateThumbnail(filePath, identifier, heightPx); + } + + private static async generateThumbnail(tempFilePath: string, identifier: string, heightPx: number) { + const thumbnailPath = this.getThumbnailPath(identifier); + const exportPath = path.join(BASE_TEMP_DIR, THUMBNAIL_OUTPUT_DIR, thumbnailPath); + try { await generateAsync(tempFilePath, exportPath, { ...THUMBNAIL_DIMENSIONS, height: heightPx }); console.log('Thumbnail generated successfully:', exportPath); return thumbnailPath; } catch (e) { console.error(e); - throw new UnhandledError(`Failed generating thumbnail for file with cid: ${cid}`); + throw new UnhandledError(`Failed generating thumbnail for file: ${identifier}`); } finally { - // The initially saved file is removed, however the thumbnail remains. Further cleanup can be done for the thumbnail. - try { - await fs.unlink(tempFilePath, (err) => { - if (err) { - console.error(err, `Failed to cleanup temporary file: ${tempFilePath}`); - return; - } + // Only delete the temp file if it's not the original uploaded file + if (!tempFilePath.includes(THUMBNAIL_FILES_DIR)) { + try { + await fs.promises.unlink(tempFilePath); console.log(`Temporary file ${tempFilePath} deleted successfully.`); - }); - } catch (cleanupError) { - console.error(`Failed to delete temporary file ${tempFilePath}:`, cleanupError); + } catch (cleanupError) { + console.error(`Failed to delete temporary file ${tempFilePath}:`, cleanupError); + } } } } - static getThumbnailPath(cid: string) { - return `h-${THUMBNAIL_DIMENSIONS.height}px_${cid}.jpg`; - // return `${THUMBNAIL_DIMENSIONS.width}x${THUMBNAIL_DIMENSIONS.height}_${cid}.jpg`; + static getThumbnailPath(identifier: string) { + return `h-${THUMBNAIL_DIMENSIONS.height}px_${identifier}.jpg`; } } From c8400239c86846dcebbab53f22243f0b9118c83c Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Mon, 24 Jun 2024 22:58:58 +0200 Subject: [PATCH 197/278] support pagination and access/publish checks for nodes --- ...DeSci Nodes Server.postman_collection.json | 309 +++++++++++++++ ...ul_API_Boilerplate.postman_collection.json | 365 ------------------ ...l_API_Boilerplate.postman_environment.json | 29 -- .../controllers/nodes/checkIfPublishedNode.ts | 99 +++++ .../src/controllers/nodes/checkNodeAccess.ts | 142 +++++++ .../controllers/nodes/getDraftNodeStats.ts | 38 ++ .../nodes/getPublishedNodeStats.ts | 113 ++++++ .../controllers/nodes/getPublishedNodes.ts | 85 ++++ desci-server/src/controllers/nodes/list.ts | 10 +- .../src/controllers/nodes/searchNodes.ts | 86 +++++ desci-server/src/routes/v1/nodes.ts | 13 + 11 files changed, 891 insertions(+), 398 deletions(-) create mode 100644 desci-server/postman/DeSci Nodes Server.postman_collection.json delete mode 100755 desci-server/postman/RESTful_API_Boilerplate.postman_collection.json delete mode 100755 desci-server/postman/RESTful_API_Boilerplate.postman_environment.json create mode 100644 desci-server/src/controllers/nodes/checkIfPublishedNode.ts create mode 100644 desci-server/src/controllers/nodes/checkNodeAccess.ts create mode 100644 desci-server/src/controllers/nodes/getDraftNodeStats.ts create mode 100644 desci-server/src/controllers/nodes/getPublishedNodeStats.ts create mode 100644 desci-server/src/controllers/nodes/getPublishedNodes.ts create mode 100644 desci-server/src/controllers/nodes/searchNodes.ts diff --git a/desci-server/postman/DeSci Nodes Server.postman_collection.json b/desci-server/postman/DeSci Nodes Server.postman_collection.json new file mode 100644 index 00000000..d05c1079 --- /dev/null +++ b/desci-server/postman/DeSci Nodes Server.postman_collection.json @@ -0,0 +1,309 @@ +{ + "info": { + "_postman_id": "f3499db3-0bee-418e-8229-3af4d9f4719f", + "name": "DeSci Nodes Server", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "10483110" + }, + "item": [ + { + "name": "Start Email Login (Magic Code)", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"email\": \"sina@desci.com\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{server_url}}/v1/auth/magic", + "host": [ + "{{server_url}}" + ], + "path": [ + "v1", + "auth", + "magic" + ] + } + }, + "response": [] + }, + { + "name": "Complete Email Login (Magic Code)", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"email\": \"sina@desci.com\",\r\n \"code\": \"353876\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{server_url}}/v1/auth/magic", + "host": [ + "{{server_url}}" + ], + "path": [ + "v1", + "auth", + "magic" + ] + } + }, + "response": [] + }, + { + "name": "Create Node Draft", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"title\": \"Test123\",\r\n \"links\": []\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{server_url}}/v1/nodes/createDraft", + "host": [ + "{{server_url}}" + ], + "path": [ + "v1", + "nodes", + "createDraft" + ] + } + }, + "response": [] + }, + { + "name": "Get Nodes", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{auth_jwt_token}}", + "type": "text" + } + ], + "url": { + "raw": "{{server_url}}/v1/nodes/access/", + "host": [ + "{{server_url}}" + ], + "path": [ + "v1", + "nodes", + "access", + "" + ] + } + }, + "response": [] + }, + { + "name": "Get Nodes Page 2", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{auth_jwt_token}}", + "type": "text" + } + ], + "url": { + "raw": "{{server_url}}/v1/nodes?g=http://localhost:5001&page=2", + "host": [ + "{{server_url}}" + ], + "path": [ + "v1", + "nodes" + ], + "query": [ + { + "key": "g", + "value": "http://localhost:5001" + }, + { + "key": "page", + "value": "2" + } + ] + } + }, + "response": [] + }, + { + "name": "Get Published Nodes", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{auth_jwt_token}}", + "type": "text" + } + ], + "url": { + "raw": "{{server_url}}/v1/nodes/published/list?g=http://localhost:5001", + "host": [ + "{{server_url}}" + ], + "path": [ + "v1", + "nodes", + "published", + "list" + ], + "query": [ + { + "key": "g", + "value": "http://localhost:5001" + } + ] + } + }, + "response": [] + }, + { + "name": "Search Node Titles", + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{server_url}}/v1/nodes/search/test", + "host": [ + "{{server_url}}" + ], + "path": [ + "v1", + "nodes", + "search", + "test" + ] + } + }, + "response": [] + }, + { + "name": "Get Node Stats", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{auth_jwt_token}}", + "type": "text" + } + ], + "url": { + "raw": "{{server_url}}/v1/nodes/stats", + "host": [ + "{{server_url}}" + ], + "path": [ + "v1", + "nodes", + "stats" + ] + } + }, + "response": [] + }, + { + "name": "Check Node Access", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{auth_jwt_token}}", + "type": "text" + } + ], + "url": { + "raw": "{{server_url}}/v1/nodes/access/GOcPwF6yNEyTemHzPmXXhINrx-dXMpfAMpUj-to-FMY", + "host": [ + "{{server_url}}" + ], + "path": [ + "v1", + "nodes", + "access", + "GOcPwF6yNEyTemHzPmXXhINrx-dXMpfAMpUj-to-FMY" + ] + } + }, + "response": [] + }, + { + "name": "Check if Published", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{auth_jwt_token}}", + "type": "text" + } + ], + "url": { + "raw": "{{server_url}}/v1/nodes/published/GOcPwF6yNEyTemHzPmXXhINrx-dXMpfAMpUj-to-FMY", + "host": [ + "{{server_url}}" + ], + "path": [ + "v1", + "nodes", + "published", + "GOcPwF6yNEyTemHzPmXXhINrx-dXMpfAMpUj-to-FMY" + ] + } + }, + "response": [] + }, + { + "name": "Get Published Node Stats", + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{auth_jwt_token}}", + "type": "text" + } + ], + "url": { + "raw": "{{server_url}}/v1/nodes/stats/published", + "host": [ + "{{server_url}}" + ], + "path": [ + "v1", + "nodes", + "stats", + "published" + ] + } + }, + "response": [] + } + ] +} \ No newline at end of file diff --git a/desci-server/postman/RESTful_API_Boilerplate.postman_collection.json b/desci-server/postman/RESTful_API_Boilerplate.postman_collection.json deleted file mode 100755 index 58c777c0..00000000 --- a/desci-server/postman/RESTful_API_Boilerplate.postman_collection.json +++ /dev/null @@ -1,365 +0,0 @@ -{ - "info": { - "_postman_id": "da0fe49f-e424-4b96-8f55-49f7db0583dc", - "name": "RESTful API Boilerplate", - "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" - }, - "item": [ - { - "name": "/auth", - "item": [ - { - "name": "/login", - "event": [ - { - "listen": "test", - "script": { - "id": "81ebd7f4-cc11-473a-a6b3-85b003f7222b", - "exec": [ - "var jsonData = JSON.parse(responseBody);", - "", - "postman.setEnvironmentVariable(\"token\", jsonData.data);" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "name": "Content-Type", - "type": "text", - "value": "application/x-www-form-urlencoded" - }, - { - "key": "Accept-Language", - "value": "{{language}}", - "type": "text" - } - ], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "email", - "value": "admin@admin.com", - "type": "text" - }, - { - "key": "password", - "value": "pass1", - "type": "text" - } - ] - }, - "url": { - "raw": "{{baseUrl}}/login", - "host": ["{{baseUrl}}"], - "path": ["login"] - } - }, - "response": [] - }, - { - "name": "/register", - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "name": "Content-Type", - "value": "application/x-www-form-urlencoded", - "type": "text" - }, - { - "key": "Accept-Language", - "value": "{{language}}", - "type": "text" - } - ], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "email", - "value": "admin1@admin.com", - "type": "text" - }, - { - "key": "password", - "value": "admin", - "type": "text" - }, - { - "key": "passwordConfirm", - "value": "admin", - "type": "text" - } - ] - }, - "url": { - "raw": "{{baseUrl}}/register", - "host": ["{{baseUrl}}"], - "path": ["register"] - } - }, - "response": [] - }, - { - "name": "/change-password", - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "name": "Content-Type", - "type": "text", - "value": "application/x-www-form-urlencoded" - }, - { - "key": "Authorization", - "value": "{{token}}", - "type": "text" - }, - { - "key": "Accept-Language", - "value": "{{language}}", - "type": "text" - } - ], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "password", - "value": "admin", - "type": "text" - }, - { - "key": "passwordNew", - "value": "admin", - "type": "text" - }, - { - "key": "passwordConfirm", - "value": "admin", - "type": "text" - } - ] - }, - "url": { - "raw": "{{baseUrl}}/change-password", - "host": ["{{baseUrl}}"], - "path": ["change-password"] - } - }, - "response": [] - } - ], - "protocolProfileBehavior": {} - }, - { - "name": "/misc", - "item": [ - { - "name": "/change-language", - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "name": "Content-Type", - "type": "text", - "value": "application/x-www-form-urlencoded" - }, - { - "key": "Accept-Language", - "type": "text", - "value": "sl-SI" - } - ], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "language", - "value": "sl-SI", - "type": "text" - } - ] - }, - "url": { - "raw": "{{baseUrl}}/misc/change-language", - "host": ["{{baseUrl}}"], - "path": ["misc", "change-language"] - } - }, - "response": [] - } - ], - "protocolProfileBehavior": {} - }, - { - "name": "/users", - "item": [ - { - "name": "/", - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [ - { - "key": "Content-Type", - "name": "Content-Type", - "type": "text", - "value": "application/x-www-form-urlencoded" - }, - { - "key": "Accept-Language", - "type": "text", - "value": "sl-SI" - }, - { - "key": "Authorization", - "value": "{{token}}", - "type": "text" - } - ], - "body": { - "mode": "urlencoded", - "urlencoded": [] - }, - "url": { - "raw": "{{baseUrl}}/users", - "host": ["{{baseUrl}}"], - "path": ["users"] - } - }, - "response": [] - }, - { - "name": "/:id", - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [ - { - "key": "Content-Type", - "name": "Content-Type", - "type": "text", - "value": "application/x-www-form-urlencoded" - }, - { - "key": "Accept-Language", - "type": "text", - "value": "sl-SI" - }, - { - "key": "Authorization", - "type": "text", - "value": "{{token}}" - } - ], - "body": { - "mode": "urlencoded", - "urlencoded": [] - }, - "url": { - "raw": "{{baseUrl}}/users/3", - "host": ["{{baseUrl}}"], - "path": ["users", "3"] - } - }, - "response": [] - }, - { - "name": "/:id", - "request": { - "method": "DELETE", - "header": [ - { - "key": "Content-Type", - "name": "Content-Type", - "type": "text", - "value": "application/x-www-form-urlencoded" - }, - { - "key": "Accept-Language", - "type": "text", - "value": "sl-SI" - }, - { - "key": "Authorization", - "type": "text", - "value": "{{token}}" - } - ], - "body": { - "mode": "urlencoded", - "urlencoded": [] - }, - "url": { - "raw": "{{baseUrl}}/users/9", - "host": ["{{baseUrl}}"], - "path": ["users", "9"] - } - }, - "response": [] - }, - { - "name": "/:id", - "request": { - "method": "PATCH", - "header": [ - { - "key": "Content-Type", - "name": "Content-Type", - "type": "text", - "value": "application/x-www-form-urlencoded" - }, - { - "key": "Accept-Language", - "type": "text", - "value": "sl-SI" - }, - { - "key": "Authorization", - "type": "text", - "value": "{{token}}" - } - ], - "body": { - "mode": "urlencoded", - "urlencoded": [ - { - "key": "username", - "value": "Tyrion1", - "type": "text" - }, - { - "key": "name", - "value": "test name", - "type": "text" - } - ] - }, - "url": { - "raw": "{{baseUrl}}/users/5", - "host": ["{{baseUrl}}"], - "path": ["users", "5"] - } - }, - "response": [] - } - ], - "protocolProfileBehavior": {} - } - ], - "protocolProfileBehavior": {} -} diff --git a/desci-server/postman/RESTful_API_Boilerplate.postman_environment.json b/desci-server/postman/RESTful_API_Boilerplate.postman_environment.json deleted file mode 100755 index 570ebdef..00000000 --- a/desci-server/postman/RESTful_API_Boilerplate.postman_environment.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "id": "a8df1c58-9c26-4452-a61e-0f0d2e865ee1", - "name": "RESTful API Boilerplate", - "values": [ - { - "key": "host", - "value": "http://localhost:5420", - "enabled": true - }, - { - "key": "baseUrl", - "value": "{{host}}", - "enabled": true - }, - { - "key": "language", - "value": "en", - "enabled": true - }, - { - "key": "token", - "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwibmFtZSI6IldhbHRlciBXaGl0ZSIsImVtYWlsIjoiYWRtaW5AYWRtaW4uY29tIiwicm9sZSI6IkFETUlOSVNUUkFUT1IiLCJjcmVhdGVkX2F0IjoiMjAyMC0wNi0xM1QwODoyNjoxNS41MjZaIiwiaWF0IjoxNTkyMTYxMjcwLCJleHAiOjE1OTIxNjIxNzB9.Fi-jszKGqt2plCqJj9jCM5x5l0KSQVkuQu9-qqElMug", - "enabled": true - } - ], - "_postman_variable_scope": "environment", - "_postman_exported_at": "2020-06-14T19:04:35.409Z", - "_postman_exported_using": "Postman/7.26.0" -} diff --git a/desci-server/src/controllers/nodes/checkIfPublishedNode.ts b/desci-server/src/controllers/nodes/checkIfPublishedNode.ts new file mode 100644 index 00000000..e090fa6c --- /dev/null +++ b/desci-server/src/controllers/nodes/checkIfPublishedNode.ts @@ -0,0 +1,99 @@ +import type { Request, Response, NextFunction } from 'express'; + +import { prisma } from '../../client.js'; +import { resolveNodeManifest } from '../../internal.js'; +import { logger as parentLogger } from '../../logger.js'; +import { decodeBase64UrlSafeToHex, ensureUuidEndsWithDot, randomUUID64 } from '../../utils.js'; +import { IndexedResearchObject, getIndexedResearchObjects } from '../../theGraph.js'; +import { ResearchObjectV1, ResearchObjectV1Dpid } from '@desci-labs/desci-models'; +import { NodeCover } from '@prisma/client'; + +const logger = parentLogger.child({ + module: 'NODE::checkIfPublishedNode', +}); + +type NodeWithDpid = { + uuid: string; + createdAt: Date; + updatedAt: Date; + ownerId: number; + title: string; + manifestUrl: string; + cid: string; + NodeCover: NodeCover[]; + isPublished: boolean; +} & { dpid?: ResearchObjectV1Dpid; isPublished: boolean; index?: IndexedResearchObject }; + +type GetPublishedNodeResponse = { + ok: true; + uuid?: string; + dpid?: string; + isPublished: boolean; + indexInfo?: IndexedResearchObject; +}; + +export const checkIfPublishedNode = async (req: Request, res: Response) => { + const owner = (req as any).user; + const ipfsQuery = req.query.g; + + logger.info({ + body: req.body, + user: (req as any).user, + ipfsQuery, + }); + + let node = await prisma.node.findFirst({ + select: { + uuid: true, + id: true, + createdAt: true, + updatedAt: true, + ownerId: true, + title: true, + manifestUrl: true, + cid: true, + NodeCover: true, + }, + where: { + ownerId: owner.id, + isDeleted: false, + uuid: ensureUuidEndsWithDot(req.params.uuid), + }, + }); + + // transition UUID + const indexMap = {}; + + try { + const uuids = node.uuid; + const indexed = await getIndexedResearchObjects([uuids]); + indexed.researchObjects.forEach((e) => { + indexMap[e.id] = e; + }); + } catch (err) { + logger.error({ err: err.message }, '[ERROR] graph index lookup fail'); + // todo: try on chain direct (current method doesnt support batch, so fix that and add here) + } + + const hex = `0x${decodeBase64UrlSafeToHex(node.uuid)}`; + const result = indexMap[hex]; + const manifest: ResearchObjectV1 = result?.recentCid ? await resolveNodeManifest(result?.recentCid) : null; + const o = { + ...node, + uuid: node.uuid.replaceAll('.', ''), + isPublished: !!indexMap[hex], + index: indexMap[hex], + dpid: manifest?.dpid, + }; + delete o.id; + + const enhancedNode: NodeWithDpid = o; + + res.send({ + ok: true, + uuid: enhancedNode.uuid, + dpid: enhancedNode.dpid?.id, + isPublished: enhancedNode.isPublished, + indexInfo: enhancedNode.index, + }); +}; diff --git a/desci-server/src/controllers/nodes/checkNodeAccess.ts b/desci-server/src/controllers/nodes/checkNodeAccess.ts new file mode 100644 index 00000000..29f0307f --- /dev/null +++ b/desci-server/src/controllers/nodes/checkNodeAccess.ts @@ -0,0 +1,142 @@ +import type { Request, Response } from 'express'; + +import { prisma } from '../../client.js'; +import { resolveNodeManifest } from '../../internal.js'; +import { logger as parentLogger } from '../../logger.js'; +import { decodeBase64UrlSafeToHex, ensureUuidEndsWithDot, randomUUID64 } from '../../utils.js'; +import { IndexedResearchObject, getIndexedResearchObjects } from '../../theGraph.js'; +import { ResearchObjectV1, ResearchObjectV1Dpid } from '@desci-labs/desci-models'; +import { NodeCover } from '@prisma/client'; +import { PRIV_SHARE_CONTRIBUTION_PREFIX } from '../../services/Contributors.js'; + +const logger = parentLogger.child({ + module: 'NODE::checkNodeAccess', +}); + +type NodeWithDpid = { + uuid: string; + createdAt: Date; + updatedAt: Date; + ownerId: number; + title: string; + manifestUrl: string; + cid: string; + NodeCover: NodeCover[]; + isPublished: boolean; +} & { dpid?: ResearchObjectV1Dpid; isPublished: boolean; index?: IndexedResearchObject }; + +type GetCheckNodeAccessResponse = { + ok: true; + uuid?: string; + isOwner: boolean; + isShared: boolean; + hasAccess: boolean; + sharedOn?: number; + isPublished: boolean; + recentCid?: string; + index?: IndexedResearchObject; + manifestUrl?: string; +}; + +type GetCheckNodeAccessErrorResponse = { + ok: false; + message: string; +}; + +export const checkNodeAccess = async ( + req: Request, + res: Response, +) => { + const owner = (req as any).user; + const ipfsQuery = req.query.g; + + logger.info({ + body: req.body, + user: (req as any).user, + ipfsQuery, + }); + + let node = await prisma.node.findFirst({ + select: { + uuid: true, + id: true, + createdAt: true, + updatedAt: true, + ownerId: true, + title: true, + manifestUrl: true, + cid: true, + NodeCover: true, + }, + where: { + isDeleted: false, + uuid: ensureUuidEndsWithDot(req.params.uuid), + }, + }); + + if (!node) { + res.status(404).send({ ok: false, message: 'Node not found' }); + return; + } + + const privSharedNode = await prisma.privateShare.findFirst({ + where: { + memo: `${PRIV_SHARE_CONTRIBUTION_PREFIX}${owner.email}`, + nodeUUID: node.uuid, + }, + }); + + // transition UUID + const indexMap = {}; + + try { + const uuids = node.uuid; + const indexed = await getIndexedResearchObjects([uuids]); + indexed.researchObjects.forEach((e) => { + indexMap[e.id] = e; + }); + } catch (err) { + logger.error({ err: err.message }, '[ERROR] graph index lookup fail'); + // todo: try on chain direct (current method doesnt support batch, so fix that and add here) + } + + const hex = `0x${decodeBase64UrlSafeToHex(node.uuid)}`; + const result = indexMap[hex]; + const manifest: ResearchObjectV1 = result?.recentCid + ? await resolveNodeManifest(result?.recentCid, ipfsQuery as string) + : null; + const o = { + ...node, + uuid: node.uuid.replaceAll('.', ''), + isPublished: !!indexMap[hex], + index: indexMap[hex], + dpid: manifest?.dpid, + }; + delete o.id; + + const enhancedNode: NodeWithDpid = o; + + const isOwner = owner.id === enhancedNode.ownerId; + const latestDraftVersion = await prisma.nodeVersion.findFirst({ + where: { + nodeId: node.id, + }, + orderBy: { + createdAt: 'desc', + }, + }); + + const hasAccess = privSharedNode?.nodeUUID === node.uuid || isOwner; + res.send({ + ok: true, + uuid: enhancedNode.uuid, + isOwner, + isShared: !isOwner && !!privSharedNode, + hasAccess, + isPublished: enhancedNode.isPublished, + sharedOn: privSharedNode?.createdAt.getTime(), + recentCid: enhancedNode.index?.recentCid, + index: enhancedNode.index, + manifestUrl: hasAccess ? latestDraftVersion?.manifestUrl : undefined, + }); +}; diff --git a/desci-server/src/controllers/nodes/getDraftNodeStats.ts b/desci-server/src/controllers/nodes/getDraftNodeStats.ts new file mode 100644 index 00000000..e16c3c08 --- /dev/null +++ b/desci-server/src/controllers/nodes/getDraftNodeStats.ts @@ -0,0 +1,38 @@ +import type { Request, Response } from 'express'; + +import { prisma } from '../../client.js'; +import { logger as parentLogger } from '../../logger.js'; + +const logger = parentLogger.child({ + module: 'NODE::getPublishedNodesController', +}); + +// type NodeWithDpid = Node & { dpid?: string; isPublished: boolean; index?: IndexedResearchObject }; + +type GetDraftNodeStatsResponse = { + ok: true; + totalDraftNodes: number; +}; + +export const getDraftNodeStats = async (req: Request, res: Response) => { + const user = (req as any).user; + const ipfsQuery = req.query.g; + + logger.info({ + body: req.body, + user: (req as any).user, + ipfsQuery, + }); + + let nodes = await prisma.node.count({ + where: { + ownerId: user.id, + isDeleted: false, + }, + }); + + return res.send({ + ok: true, + totalDraftNodes: nodes.valueOf(), + }); +}; diff --git a/desci-server/src/controllers/nodes/getPublishedNodeStats.ts b/desci-server/src/controllers/nodes/getPublishedNodeStats.ts new file mode 100644 index 00000000..61f00e07 --- /dev/null +++ b/desci-server/src/controllers/nodes/getPublishedNodeStats.ts @@ -0,0 +1,113 @@ +import type { Request, Response, NextFunction } from 'express'; + +import { prisma } from '../../client.js'; +import { NodeUuid, resolveNodeManifest } from '../../internal.js'; +import { logger as parentLogger } from '../../logger.js'; +import { type ThumbnailMap, thumbnailsService } from '../../services/Thumbnails.js'; +import { asyncMap, decodeBase64UrlSafeToHex, ensureUuidEndsWithDot, randomUUID64 } from '../../utils.js'; +import { IndexedResearchObject, getIndexedResearchObjects } from '../../theGraph.js'; +import { ResearchObjectV1, ResearchObjectV1Dpid } from '@desci-labs/desci-models'; +import { Node, NodeCover } from '@prisma/client'; + +const logger = parentLogger.child({ + module: 'NODE::getPublishedNodesController', +}); + +type NodeWithDpid = { + uuid: string; + createdAt: Date; + updatedAt: Date; + ownerId: number; + title: string; + manifestUrl: string; + cid: string; + NodeCover: NodeCover[]; + isPublished: boolean; +} & { dpid?: ResearchObjectV1Dpid; isPublished: boolean; index?: IndexedResearchObject }; + +type GetPublishedNodeStatsResponse = { + ok: true; + totalPublishedNodes: number; +}; + +export const getPublishedNodeStats = async ( + req: Request, + res: Response, +) => { + const owner = (req as any).user; + const ipfsQuery = req.query.g; + + logger.info({ + body: req.body, + user: (req as any).user, + ipfsQuery, + }); + + let nodes = await prisma.node.findMany({ + select: { + uuid: true, + id: true, + createdAt: true, + updatedAt: true, + ownerId: true, + title: true, + manifestUrl: true, + cid: true, + NodeCover: true, + }, + where: { + ownerId: owner.id, + isDeleted: false, + ceramicStream: { + not: null, + }, + }, + orderBy: { updatedAt: 'desc' }, + // take: limit, + // skip: (page - 1) * limit, + }); + + // transition UUID + const indexMap = {}; + + try { + const uuids = nodes.map((n) => n.uuid); + const indexed = await getIndexedResearchObjects(uuids); + indexed.researchObjects.forEach((e) => { + indexMap[e.id] = e; + }); + } catch (err) { + logger.error({ err: err.message }, '[ERROR] graph index lookup fail'); + // todo: try on chain direct (current method doesnt support batch, so fix that and add here) + } + + logger.info({ indexMap }, 'indexMap'); + logger.info({ nodes }, 'nodes'); + + const enhancedNodes = await asyncMap(nodes, async (n) => { + const hex = `0x${decodeBase64UrlSafeToHex(n.uuid)}`; + const result = indexMap[hex]; + const manifest: ResearchObjectV1 = result?.recentCid + ? await resolveNodeManifest(result?.recentCid, ipfsQuery as string) + : null; + const o = { + ...n, + uuid: n.uuid.replaceAll('.', ''), + isPublished: !!indexMap[hex], + index: indexMap[hex], + dpid: manifest?.dpid, + }; + delete o.id; + + return o; + }); + logger.info({ enhancedNodes }, 'enhancedNodes'); + + const totalPublishedNodes = enhancedNodes.filter((n) => n.isPublished).length; + logger.info({ totalPublishedNodes }, 'totalPublishedNodes'); + + res.send({ + ok: true, + totalPublishedNodes, + }); +}; diff --git a/desci-server/src/controllers/nodes/getPublishedNodes.ts b/desci-server/src/controllers/nodes/getPublishedNodes.ts new file mode 100644 index 00000000..4cf343a3 --- /dev/null +++ b/desci-server/src/controllers/nodes/getPublishedNodes.ts @@ -0,0 +1,85 @@ +// import { randomBytes } from 'crypto'; + +import { ResearchObjectV1, ResearchObjectV1Dpid } from '@desci-labs/desci-models'; +import axios from 'axios'; +import { Request, Response, NextFunction } from 'express'; + +import { prisma } from '../../client.js'; +import { resolveNodeManifest } from '../../internal.js'; +import { logger as parentLogger } from '../../logger.js'; +import { IndexedResearchObject, getIndexedResearchObjects } from '../../theGraph.js'; +import { asyncMap, decodeBase64UrlSafeToHex, randomUUID64 } from '../../utils.js'; +import { Node } from '@prisma/client'; + +const logger = parentLogger.child({ + module: 'NODE::getPublishedNodes', +}); +// type NodeWithDpid = { dpid?: ResearchObjectV1Dpid; isPublished: boolean; index?: IndexedResearchObject }; +export const getPublishedNodes = async (req: Request, res: Response, next: NextFunction) => { + const owner = (req as any).user; + const ipfsQuery = req.query.g; + + // implement paging + const page: number = req.query.page ? parseInt(req.query.page as string) : 1; + const limit: number = req.query.limit ? parseInt(req.query.limit as string) : 20; + + let nodes = await prisma.node.findMany({ + select: { + uuid: true, + id: true, + createdAt: true, + updatedAt: true, + ownerId: true, + title: true, + manifestUrl: true, + cid: true, + NodeCover: true, + }, + where: { + ownerId: owner.id, + isDeleted: false, + ceramicStream: { + not: null, + }, + }, + orderBy: { updatedAt: 'desc' }, + }); + logger.info({ nodes }, 'nodeess'); + const indexMap = {}; + + try { + const uuids = nodes.map((n) => n.uuid); + const indexed = await getIndexedResearchObjects(uuids); + indexed.researchObjects.forEach((e) => { + indexMap[e.id] = e; + }); + } catch (err) { + logger.error({ err: err.message }, '[ERROR] graph index lookup fail'); + // todo: try on chain direct (current method doesnt support batch, so fix that and add here) + } + + let foundNodes = await asyncMap(nodes, async (n) => { + const hex = `0x${decodeBase64UrlSafeToHex(n.uuid)}`; + const result = indexMap[hex]; + const manifest: ResearchObjectV1 = result?.recentCid + ? await resolveNodeManifest(result?.recentCid, ipfsQuery as string) + : null; + const o = { + ...n, + uuid: n.uuid.replaceAll('.', ''), + isPublished: !!indexMap[hex], + index: indexMap[hex], + dpid: manifest?.dpid, + }; + delete o.id; + + return o; + }); + + logger.info({ foundNodes }, 'foundNodes'); + + foundNodes = foundNodes.filter((n) => n.isPublished); + foundNodes = foundNodes.slice((page - 1) * limit, page * limit); + + res.send({ nodes: foundNodes }); +}; diff --git a/desci-server/src/controllers/nodes/list.ts b/desci-server/src/controllers/nodes/list.ts index f84cfc15..ac0fb99b 100755 --- a/desci-server/src/controllers/nodes/list.ts +++ b/desci-server/src/controllers/nodes/list.ts @@ -20,7 +20,7 @@ export const list = async (req: Request, res: Response, next: NextFunction) => { // implement paging const page: number = req.query.page ? parseInt(req.query.page as string) : 1; - const limit: number = req.query.limit ? parseInt(req.query.limit as string) : 20; + const limit: number = req.query.limit ? parseInt(req.query.limit as string) : 10; logger.info({ body: req.body, @@ -45,8 +45,8 @@ export const list = async (req: Request, res: Response, next: NextFunction) => { isDeleted: false, }, orderBy: { updatedAt: 'desc' }, - // take: limit, - // skip: (page - 1) * limit, + take: limit, + skip: (page - 1) * limit, }); // transition UUID @@ -100,7 +100,9 @@ export const list = async (req: Request, res: Response, next: NextFunction) => { nodes = await asyncMap(nodes, async (n) => { const hex = `0x${decodeBase64UrlSafeToHex(n.uuid)}`; const result = indexMap[hex]; - const manifest: ResearchObjectV1 = result?.recentCid ? await resolveNodeManifest(result?.recentCid) : null; + const manifest: ResearchObjectV1 = result?.recentCid + ? await resolveNodeManifest(result?.recentCid, ipfsQuery as string) + : null; const o = { ...n, uuid: n.uuid.replaceAll('.', ''), diff --git a/desci-server/src/controllers/nodes/searchNodes.ts b/desci-server/src/controllers/nodes/searchNodes.ts new file mode 100644 index 00000000..4f7ced30 --- /dev/null +++ b/desci-server/src/controllers/nodes/searchNodes.ts @@ -0,0 +1,86 @@ +// import { randomBytes } from 'crypto'; + +import { ResearchObjectV1 } from '@desci-labs/desci-models'; +import axios from 'axios'; +import { Request, Response, NextFunction } from 'express'; + +import { prisma } from '../../client.js'; +import { resolveNodeManifest } from '../../internal.js'; +import { logger as parentLogger } from '../../logger.js'; +import { getIndexedResearchObjects } from '../../theGraph.js'; +import { asyncMap, decodeBase64UrlSafeToHex, randomUUID64 } from '../../utils.js'; + +const logger = parentLogger.child({ + module: 'NODE::searchNodesController', +}); + +export const searchNodes = async (req: Request, res: Response, next: NextFunction) => { + const owner = (req as any).user; + const ipfsQuery = req.query.g; + + // implement paging + const page: number = req.query.page ? parseInt(req.query.page as string) : 1; + const limit: number = req.query.limit ? parseInt(req.query.limit as string) : 20; + + logger.info({ + body: req.body, + user: (req as any).user, + ipfsQuery, + }); + + let nodes = await prisma.node.findMany({ + select: { + uuid: true, + id: true, + createdAt: true, + updatedAt: true, + ownerId: true, + title: true, + manifestUrl: true, + cid: true, + NodeCover: true, + }, + where: { + ownerId: owner.id, + isDeleted: false, + title: { + contains: req.params.query, + mode: 'insensitive', + }, + }, + orderBy: { updatedAt: 'desc' }, + take: limit, + skip: (page - 1) * limit, + }); + + const indexMap = {}; + + try { + const uuids = nodes.map((n) => n.uuid); + const indexed = await getIndexedResearchObjects(uuids); + indexed.researchObjects.forEach((e) => { + indexMap[e.id] = e; + }); + } catch (err) { + logger.error({ err: err.message }, '[ERROR] graph index lookup fail'); + // todo: try on chain direct (current method doesnt support batch, so fix that and add here) + } + + nodes = await asyncMap(nodes, async (n) => { + const hex = `0x${decodeBase64UrlSafeToHex(n.uuid)}`; + const result = indexMap[hex]; + const manifest: ResearchObjectV1 = result?.recentCid ? await resolveNodeManifest(result?.recentCid) : null; + const o = { + ...n, + uuid: n.uuid.replaceAll('.', ''), + isPublished: !!indexMap[hex], + index: indexMap[hex], + dpid: manifest?.dpid, + }; + delete o.id; + + return o; + }); + + res.send({ nodes }); +}; diff --git a/desci-server/src/routes/v1/nodes.ts b/desci-server/src/routes/v1/nodes.ts index 85d487eb..bade460d 100755 --- a/desci-server/src/routes/v1/nodes.ts +++ b/desci-server/src/routes/v1/nodes.ts @@ -42,11 +42,24 @@ import { asyncHander, attachUser, validate } from '../../internal.js'; import { ensureNodeAccess, ensureWriteNodeAccess } from '../../middleware/authorisation.js'; import { ensureUser } from '../../middleware/permissions.js'; import { createDpid } from '../../controllers/nodes/createDpid.js'; +import { getDraftNodeStats } from '../../controllers/nodes/getDraftNodeStats.js'; +import { getPublishedNodeStats } from '../../controllers/nodes/getPublishedNodeStats.js'; +import { checkIfPublishedNode } from '../../controllers/nodes/checkIfPublishedNode.js'; +import { checkNodeAccess } from '../../controllers/nodes/checkNodeAccess.js'; +import { searchNodes } from '../../controllers/nodes/searchNodes.js'; +import { getPublishedNodes } from '../../controllers/nodes/getPublishedNodes.js'; const router = Router(); router.post('/prepublish', [ensureUser, ensureNodeAccess], prepublish); router.post('/publish', [ensureUser], publish); +router.get('/stats', [ensureUser], getDraftNodeStats); +router.get('/stats/published', [ensureUser], getPublishedNodeStats); +router.get('/published/list', [ensureUser], getPublishedNodes); +router.get('/published/:uuid', [ensureUser], checkIfPublishedNode); +router.get('/access/:uuid', [ensureUser], checkNodeAccess); +router.post('/search/:query', [ensureUser], searchNodes); + router.post('/createDpid', [ensureUser, ensureWriteNodeAccess], createDpid); router.post('/createDraft', [ensureUser], draftCreate); // is this api deprecated? From 5ec97fc9f3301646823521e56caf86e4191b1a46 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Mon, 24 Jun 2024 23:17:26 +0200 Subject: [PATCH 198/278] update metadata generation model, add abstract to result, fix bugs --- desci-server/src/controllers/nodes/doi.ts | 58 +++++++++++++------ .../src/services/AutomatedMetadata.ts | 39 +++++++++---- desci-server/src/services/crossRef/client.ts | 2 +- desci-server/src/services/crossRef/utils.ts | 5 ++ 4 files changed, 76 insertions(+), 28 deletions(-) diff --git a/desci-server/src/controllers/nodes/doi.ts b/desci-server/src/controllers/nodes/doi.ts index 5a02f3a8..62ec31ff 100644 --- a/desci-server/src/controllers/nodes/doi.ts +++ b/desci-server/src/controllers/nodes/doi.ts @@ -18,10 +18,12 @@ import { SuccessResponse, crossRefClient, getLatestManifestFromNode, + metadataClient, logger as parentLogger, } from '../../internal.js'; import { MetadataResponse } from '../../services/AutomatedMetadata.js'; import { Work, WorkSelectOptions } from '../../services/crossRef/definitions.js'; +import { getOrcidFromURL } from '../../services/crossRef/utils.js'; import repoService from '../../services/repoService.js'; export const attachDoiSchema = z.object({ @@ -66,36 +68,63 @@ export const automateManuscriptDoi = async (req: RequestWithNode, res: Response, logger.info({ works }, 'Works Response'); - const doi = works?.data?.message?.items.find((item) => + const matchFound = works?.data?.message?.items.find((item) => item.title.some((t) => t.toLowerCase() === queryTitle.toLowerCase()), ); - logger.info({ doi, queryTitle }, 'DOI Response'); + logger.info({ matchFound, queryTitle }, 'DOI Response'); - if (!(doi && works.ok)) { - logger.info({ data: works?.data?.message?.items }, 'DOI Not Found'); - throw new NotFoundError('DOI not found'); + let doi: string; + let metadata: MetadataResponse; + + if (works.ok && matchFound) { + doi = matchFound.DOI; + metadata = transformWorkToMetadata(matchFound); } + // if (!(works.ok && matchFound)) { + // logger.info({ data: works?.data?.message?.items }, 'DOI Not Found'); + // throw new NotFoundError('DOI not found'); + // } + + // pull metadata from AM service + metadata = await metadataClient.getResourceMetadata({ cid: component.payload.cid }); + // todo: pull metadata from crossrefClient#getDoiMetadata + // const doiMetadata = await crossRefClient.getDoiMetadata(''); - const actions: ManifestActions[] = [ - { + if (!metadata) throw new NotFoundError('DOI not found!'); + + const actions: ManifestActions[] = []; + + if (doi) { + actions.push({ type: 'Update Component', component: { ...component, payload: { ...component.payload, - doi: component.payload?.doi ? component.payload.doi.concat([doi.DOI]) : [doi.DOI], + doi: component.payload?.doi ? component.payload.doi.concat([doi]) : [doi], } as PdfComponentPayload, }, componentIndex, - }, - ]; + }); + } + + if (metadata?.abstract) { + actions.push({ + type: 'Update Description', + description: metadata.abstract, + }); + } if (prepublication) { - const { title, authors } = transformWorkToMetadata(doi); + const { title, authors } = metadata; + + // update title actions.push({ type: 'Update Title', title }); + + // update contributors if populated if (authors.length > 0) { actions.push({ type: 'Add Contributors', @@ -122,15 +151,10 @@ export const automateManuscriptDoi = async (req: RequestWithNode, res: Response, new SuccessResponse(true).send(res); }; -const formatOrcidUrl = (orcid: string) => { - const url = new URL(orcid); - return url.pathname.replace('/', ''); -}; - const transformWorkToMetadata = (work: Work): MetadataResponse => { const title = work.title[0]; const authors = work.author.map((author) => ({ - orcid: author.ORCID ? formatOrcidUrl(author.ORCID) : null, + orcid: author.ORCID ? getOrcidFromURL(author.ORCID) : null, name: author.given ? `${author.given} ${author.family}`.trim() : author.name, affiliations: author.affiliation.map((org) => ({ name: org.name, id: '' })), })); diff --git a/desci-server/src/services/AutomatedMetadata.ts b/desci-server/src/services/AutomatedMetadata.ts index 76621f8b..b924c0d0 100644 --- a/desci-server/src/services/AutomatedMetadata.ts +++ b/desci-server/src/services/AutomatedMetadata.ts @@ -19,7 +19,7 @@ export type MetadataParam = { export type AutomatedMetadataResponse = { output: Array<{ - creator: { + creator?: { [k in string]: { '@id': string; affiliation: string; @@ -28,9 +28,18 @@ export type AutomatedMetadataResponse = { ror: string; }; }; - datePublished: [number, number, number]; // [year, month, day] - keywords: Array<{ display_name: string; id: string; score: number }>; - license: Array<{ + authors?: { + [k in string]: { + '@id': string; + affiliation: string; + name: string; + role: string; + ror: string; + }; + }; + datePublished?: [number, number, number]; // [year, month, day] + keywords?: Array<{ display_name: string; id: string; score: number }>; + license?: Array<{ url: string; 'content-version': string; 'delay-in-days': number; @@ -40,12 +49,14 @@ export type AutomatedMetadataResponse = { timestamp: number; }; }>; - oa_url: string | null; + abstract?: string; + oa_url?: string | null; title: string; }>; }; export type MetadataResponse = { + abstract?: string; authors: Array<{ orcid: string; name: string; affiliations: { name: string; id: string }[] }>; title: string; pdfUrl: string | null; @@ -136,17 +147,25 @@ export class AutomatedMetadataClient { } transformResponse(data: AutomatedMetadataResponse): MetadataResponse { - const output = data.output?.[0]; + logger.info({ data }, 'TRANSFORM'); + const output = Array.isArray(data.output) ? data.output?.[0] : data.output; - const authors = output?.creator - ? Object.entries(output.creator).map(([name, creator]) => ({ + const contributors = output?.authors || output?.creator; + const authors = contributors + ? Object.entries(contributors).map(([name, creator]) => ({ affiliations: [{ name: creator.affiliation, id: creator.ror }], name, - ...(creator['@id'] && { orcid: creator['@id'] }), + ...(creator['@id'] && creator['@id'].toLowerCase() !== 'none' && { orcid: creator['@id'] }), })) : []; const keywords = output?.keywords ? output.keywords.map((keyword) => keyword.display_name) : []; - const metadata: MetadataResponse = { authors, keywords, title: output.title, pdfUrl: output.oa_url }; + const metadata: MetadataResponse = { + authors, + keywords, + title: output.title, + pdfUrl: output.oa_url, + abstract: output.abstract ?? '', + }; logger.info(metadata, 'METADATA'); return metadata; } diff --git a/desci-server/src/services/crossRef/client.ts b/desci-server/src/services/crossRef/client.ts index ad9c865b..d8821503 100644 --- a/desci-server/src/services/crossRef/client.ts +++ b/desci-server/src/services/crossRef/client.ts @@ -104,7 +104,7 @@ class CrossRefClient { */ async getDoiMetadata(doi: string) { const params: { [k: string]: any } = {}; - let url = `$https://www.crossref.org/openurl/?pid=myemail@crossref.org&format=unixref&id=${doi}`; + let url = `https://www.crossref.org/openurl/?pid=myemail@crossref.org&format=unixref&id=${doi}`; const config: RequestInit = { method: 'GET', mode: 'cors', diff --git a/desci-server/src/services/crossRef/utils.ts b/desci-server/src/services/crossRef/utils.ts index 97e12018..3ad31ff3 100644 --- a/desci-server/src/services/crossRef/utils.ts +++ b/desci-server/src/services/crossRef/utils.ts @@ -19,3 +19,8 @@ const toDotsAndDashes = (str: string) => { str = str.replace(/[A-Z]/g, (match) => match.toLowerCase()); return str; }; + +export const getOrcidFromURL = (orcid: string) => { + const url = new URL(orcid); + return url.pathname.replace('/', ''); +}; From f1862fcfc9f9056d4a7a56ecc3de625c381e77e3 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Tue, 25 Jun 2024 01:09:35 +0200 Subject: [PATCH 199/278] fix node access / pub issues, allow anon req --- .../controllers/nodes/checkIfPublishedNode.ts | 23 ++++++++++++++----- .../src/controllers/nodes/checkNodeAccess.ts | 16 +++++++------ desci-server/src/routes/v1/nodes.ts | 6 ++--- 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/desci-server/src/controllers/nodes/checkIfPublishedNode.ts b/desci-server/src/controllers/nodes/checkIfPublishedNode.ts index e090fa6c..a51b9190 100644 --- a/desci-server/src/controllers/nodes/checkIfPublishedNode.ts +++ b/desci-server/src/controllers/nodes/checkIfPublishedNode.ts @@ -32,8 +32,15 @@ type GetPublishedNodeResponse = { indexInfo?: IndexedResearchObject; }; -export const checkIfPublishedNode = async (req: Request, res: Response) => { - const owner = (req as any).user; +type GetPublishedNodeErrorResponse = { + ok: false; + message: string; +}; + +export const checkIfPublishedNode = async ( + req: Request, + res: Response, +) => { const ipfsQuery = req.query.g; logger.info({ @@ -55,7 +62,6 @@ export const checkIfPublishedNode = async (req: Request, res: Res NodeCover: true, }, where: { - ownerId: owner.id, isDeleted: false, uuid: ensureUuidEndsWithDot(req.params.uuid), }, @@ -64,6 +70,11 @@ export const checkIfPublishedNode = async (req: Request, res: Res // transition UUID const indexMap = {}; + if (!node) { + res.status(404).send({ ok: false, message: 'Node not found' }); + return; + } + try { const uuids = node.uuid; const indexed = await getIndexedResearchObjects([uuids]); @@ -71,16 +82,16 @@ export const checkIfPublishedNode = async (req: Request, res: Res indexMap[e.id] = e; }); } catch (err) { - logger.error({ err: err.message }, '[ERROR] graph index lookup fail'); + logger.error({ err }, '[ERROR] graph index lookup fail'); // todo: try on chain direct (current method doesnt support batch, so fix that and add here) } const hex = `0x${decodeBase64UrlSafeToHex(node.uuid)}`; const result = indexMap[hex]; - const manifest: ResearchObjectV1 = result?.recentCid ? await resolveNodeManifest(result?.recentCid) : null; + const manifest: ResearchObjectV1 = result?.recentCid ? await resolveNodeManifest(result?.recentCid, ipfsQuery) : null; const o = { ...node, - uuid: node.uuid.replaceAll('.', ''), + uuid: node?.uuid.replaceAll('.', ''), isPublished: !!indexMap[hex], index: indexMap[hex], dpid: manifest?.dpid, diff --git a/desci-server/src/controllers/nodes/checkNodeAccess.ts b/desci-server/src/controllers/nodes/checkNodeAccess.ts index 29f0307f..4a2ecf1f 100644 --- a/desci-server/src/controllers/nodes/checkNodeAccess.ts +++ b/desci-server/src/controllers/nodes/checkNodeAccess.ts @@ -79,12 +79,14 @@ export const checkNodeAccess = async ( return; } - const privSharedNode = await prisma.privateShare.findFirst({ - where: { - memo: `${PRIV_SHARE_CONTRIBUTION_PREFIX}${owner.email}`, - nodeUUID: node.uuid, - }, - }); + const privSharedNode = owner + ? await prisma.privateShare.findFirst({ + where: { + memo: `${PRIV_SHARE_CONTRIBUTION_PREFIX}${owner?.email}`, + nodeUUID: node.uuid, + }, + }) + : undefined; // transition UUID const indexMap = {}; @@ -116,7 +118,7 @@ export const checkNodeAccess = async ( const enhancedNode: NodeWithDpid = o; - const isOwner = owner.id === enhancedNode.ownerId; + const isOwner = owner?.id === enhancedNode.ownerId; const latestDraftVersion = await prisma.nodeVersion.findFirst({ where: { nodeId: node.id, diff --git a/desci-server/src/routes/v1/nodes.ts b/desci-server/src/routes/v1/nodes.ts index 670ce5d3..e177b317 100755 --- a/desci-server/src/routes/v1/nodes.ts +++ b/desci-server/src/routes/v1/nodes.ts @@ -40,7 +40,7 @@ import { prepublish } from '../../controllers/nodes/prepublish.js'; import { listSharedNodes } from '../../controllers/nodes/sharedNodes.js'; import { thumbnails } from '../../controllers/nodes/thumbnails.js'; import { versionDetails } from '../../controllers/nodes/versionDetails.js'; -import { asyncHander, attachDoiSchema, attachUser, validate } from '../../internal.js'; +import { asyncHander, attachDoiSchema, attachUser, ensureUserIfPresent, validate } from '../../internal.js'; import { ensureNodeAccess, ensureWriteNodeAccess } from '../../middleware/authorisation.js'; import { ensureUser } from '../../middleware/permissions.js'; import { getDraftNodeStats } from '../../controllers/nodes/getDraftNodeStats.js'; @@ -57,8 +57,8 @@ router.post('/publish', [ensureUser], publish); router.get('/stats', [ensureUser], getDraftNodeStats); router.get('/stats/published', [ensureUser], getPublishedNodeStats); router.get('/published/list', [ensureUser], getPublishedNodes); -router.get('/published/:uuid', [ensureUser], checkIfPublishedNode); -router.get('/access/:uuid', [ensureUser], checkNodeAccess); +router.get('/published/:uuid', [], checkIfPublishedNode); +router.get('/access/:uuid', [ensureUserIfPresent], checkNodeAccess); router.post('/search/:query', [ensureUser], searchNodes); router.post('/createDpid', [ensureUser, ensureWriteNodeAccess], createDpid); From dac8120ec27c2f0ecdcafe61b5cc99298d89f756 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Tue, 25 Jun 2024 01:14:44 +0200 Subject: [PATCH 200/278] fix build --- desci-server/src/controllers/nodes/checkIfPublishedNode.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/desci-server/src/controllers/nodes/checkIfPublishedNode.ts b/desci-server/src/controllers/nodes/checkIfPublishedNode.ts index a51b9190..ec9de288 100644 --- a/desci-server/src/controllers/nodes/checkIfPublishedNode.ts +++ b/desci-server/src/controllers/nodes/checkIfPublishedNode.ts @@ -88,7 +88,9 @@ export const checkIfPublishedNode = async ( const hex = `0x${decodeBase64UrlSafeToHex(node.uuid)}`; const result = indexMap[hex]; - const manifest: ResearchObjectV1 = result?.recentCid ? await resolveNodeManifest(result?.recentCid, ipfsQuery) : null; + const manifest: ResearchObjectV1 = result?.recentCid + ? await resolveNodeManifest(result?.recentCid, ipfsQuery as string) + : null; const o = { ...node, uuid: node?.uuid.replaceAll('.', ''), From f1f7ff918d50a93c52ea155948fac61a86e7ad7a Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Tue, 25 Jun 2024 01:58:42 +0200 Subject: [PATCH 201/278] share debug logs --- desci-server/src/controllers/nodes/sharedNodes.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/desci-server/src/controllers/nodes/sharedNodes.ts b/desci-server/src/controllers/nodes/sharedNodes.ts index 459fb8be..59407817 100644 --- a/desci-server/src/controllers/nodes/sharedNodes.ts +++ b/desci-server/src/controllers/nodes/sharedNodes.ts @@ -46,11 +46,12 @@ export const listSharedNodes = async (req: ListSharedNodesRequest, res: Response }); if (!user.email) { - logger.warn('User does not have an email, no nodes can be shared with the user.'); + logger.warn({}, 'User does not have an email, no nodes can be shared with the user.'); return res.status(500).json({ error: 'User does not have an email' }); } try { + logger.trace({}, 'Retrieving shared nodes for user'); const privSharedNodes = await prisma.privateShare.findMany({ where: { memo: `${PRIV_SHARE_CONTRIBUTION_PREFIX}${user.email}`, @@ -60,12 +61,17 @@ export const listSharedNodes = async (req: ListSharedNodesRequest, res: Response }, }); + logger.trace({ privSharedNodesLength: privSharedNodes.length }, 'Shared nodes retrieved successfully'); + if (privSharedNodes?.length === 0) { return res.status(200).json({ ok: true, sharedNodes: [] }); } const nodeUuids = privSharedNodes.map((priv) => priv.node.uuid); const { researchObjects } = await getIndexedResearchObjects(nodeUuids); + + logger.trace({ researchObjectsLength: researchObjects.length }, 'Research objects retrieved successfully'); + const publishedNodesMap = researchObjects.reduce((acc, ro) => { // convert hex string to integer const nodeUuidInt = Buffer.from(ro.id.substring(2), 'hex'); @@ -74,6 +80,11 @@ export const listSharedNodes = async (req: ListSharedNodesRequest, res: Response acc[nodeUuid] = ro; }, {}); + logger.trace( + { publishedNodesMapKeyLength: Object.keys(publishedNodesMap).length }, + 'Published nodes map created successfully', + ); + const filledSharedNodes = await Promise.all( privSharedNodes.map(async (priv) => { const { node } = priv; @@ -93,6 +104,7 @@ export const listSharedNodes = async (req: ListSharedNodesRequest, res: Response }; }), ); + logger.trace({ filledSharedNodesLength: filledSharedNodes.length }, 'Shared nodes filled successfully'); if (filledSharedNodes) { logger.info({ totalSharedNodesFound: filledSharedNodes.length }, 'Shared nodes retrieved successfully'); From f2d08184fc5f8808845a98292532170d54850f7a Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Tue, 25 Jun 2024 02:27:27 +0200 Subject: [PATCH 202/278] faster builds --- .github/workflows/build-server.yaml | 79 +++++++++++++++++++++++++---- desci-server/src/server.ts | 4 ++ 2 files changed, 72 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build-server.yaml b/.github/workflows/build-server.yaml index b20942c0..5d108b6f 100644 --- a/.github/workflows/build-server.yaml +++ b/.github/workflows/build-server.yaml @@ -71,9 +71,9 @@ jobs: exit 1 fi - build-and-push: - needs: build-and-test - name: Build and deploy + build-and-push-images: + # we build and push for every commit, even if tests pass, that way when tests pass deployment is short (run test + build in parallel) + name: Build and push images runs-on: ubuntu-latest steps: - uses: hashicorp/setup-terraform@v1 @@ -125,7 +125,7 @@ jobs: run: | # Build and tag the image docker build \ - -t $CONTAINER_IMAGE-dev:latest \ + -t $CONTAINER_IMAGE-dev:${{ github.sha }} \ -t $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-dev \ . @@ -134,7 +134,7 @@ jobs: run: | # Build and tag the image docker build \ - -t $CONTAINER_IMAGE-demo:latest \ + -t $CONTAINER_IMAGE-demo:${{ github.sha }} \ -t $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-demo \ . @@ -143,7 +143,7 @@ jobs: run: | # Build and tag the image docker build \ - -t $CONTAINER_IMAGE:latest \ + -t $CONTAINER_IMAGE:${{ github.sha }} \ -t $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE \ . @@ -156,9 +156,7 @@ jobs: # Push image to AWS ECR aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com docker tag $CONTAINER_IMAGE-dev:latest $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-dev:${{ github.sha }} - docker tag $CONTAINER_IMAGE-dev:latest $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-dev:latest docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-dev:${{ github.sha }} - docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-dev:latest - name: Push (DEMO) if: github.ref == 'refs/heads/demo' @@ -166,9 +164,7 @@ jobs: # Push image to AWS ECR aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com docker tag $CONTAINER_IMAGE-demo:latest $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-demo:${{ github.sha }} - docker tag $CONTAINER_IMAGE-demo:latest $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-demo:latest docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-demo:${{ github.sha }} - docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-demo:latest - name: Push (PROD) if: github.ref == 'refs/heads/main' @@ -176,8 +172,69 @@ jobs: # Push image to AWS ECR aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com docker tag $CONTAINER_IMAGE:latest $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE:${{ github.sha }} - docker tag $CONTAINER_IMAGE:latest $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE:latest docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE:${{ github.sha }} + + deploy: + name: Deploy desci-server + needs: + - build-and-test + - build-and-push-images + runs-on: ubuntu-latest + steps: + - uses: hashicorp/setup-terraform@v1 + - name: Checkout + uses: actions/checkout@v4 + + # Add steps here like linting, testing, minification, etc. + - id: install-aws-cli + uses: unfor19/install-aws-cli-action@v1 + with: + version: 1 + + - uses: prepor/action-aws-iam-authenticator@master + - run: aws-iam-authenticator version + + - name: Install Kubectl + run: | + #$(curl -Ls https://dl.k8s.io/release/stable.txt) + version=v1.23.6 + echo "using kubectl@$version" + curl -sLO "https://dl.k8s.io/release/$version/bin/linux/amd64/kubectl" -o kubectl + chmod +x kubectl + mv kubectl /usr/local/bin + mkdir $HOME/.kube + sudo apt-get update + sudo apt-get install less + echo ${{ secrets.KUBE_CONFIG_DATA }} | base64 --decode > $HOME/.kube/config + aws sts get-caller-identity + kubectl describe deployments + + # Only push to registry on dev + - name: Push (DEV) + if: github.ref == 'refs/heads/develop' + run: | + # Push image to AWS ECR + aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com + docker pull $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-dev:${{ github.sha }} + docker tag $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-dev:${{ github.sha }} $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-dev:latest + docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-dev:latest + + - name: Push (DEMO) + if: github.ref == 'refs/heads/demo' + run: | + # Push image to AWS ECR + aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com + docker pull $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-demo:${{ github.sha }} + docker tag $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-demo:${{ github.sha }} $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-demo:latest + docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-demo:latest + + - name: Push (PROD) + if: github.ref == 'refs/heads/main' + run: | + # Push image to AWS ECR + aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com + docker pull $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE:${{ github.sha }} + docker tag $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE:${{ github.sha }} $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE:latest docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE:latest - name: Deploy to EKS (DEV) diff --git a/desci-server/src/server.ts b/desci-server/src/server.ts index 392fecc1..d9d7fba6 100644 --- a/desci-server/src/server.ts +++ b/desci-server/src/server.ts @@ -122,6 +122,10 @@ class AppServer { this.app.use(cookieParser()); this.app.set('trust proxy', 2); // detect AWS ELB IP + cloudflare + this.app.get('/test-update', (_req, res) => { + res.status(200).json({ status: 'ok', updated: true }); + }); + this.#attachRouteHandlers(); // catch 404 errors and forward to error handler From ba674f81ac1179b52876c6918df731e2716993a6 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Tue, 25 Jun 2024 03:01:13 +0200 Subject: [PATCH 203/278] Fix port issue, add typescript check to tests, add failing test to check if build will deploy with failing test --- .env.test | 2 +- desci-repo/.env.test | 2 +- desci-repo/src/config.ts | 2 +- desci-server/package.json | 3 +- desci-server/src/config/index.ts | 2 +- desci-server/test/integration/temp.test.ts | 23 +++++++++++++ desci-server/tsconfig-test.json | 39 ++++++++++++++++++++++ docker-compose.test.yml | 4 +-- nodes-media/src/config/index.ts | 2 +- 9 files changed, 71 insertions(+), 8 deletions(-) create mode 100644 desci-server/test/integration/temp.test.ts create mode 100755 desci-server/tsconfig-test.json diff --git a/.env.test b/.env.test index 8e78ffe8..94e1315e 100644 --- a/.env.test +++ b/.env.test @@ -2,7 +2,7 @@ NODE_ENV=test PORT=5421 -IPFS_NODE_URL=http://host.docker.internal:5002 +IPFS_NODE_URL=http://host.docker.internal:5003 PUBLIC_IPFS_RESOLVER=https://ipfs.io ### Database - Postgres diff --git a/desci-repo/.env.test b/desci-repo/.env.test index aed267ca..832a3f69 100755 --- a/desci-repo/.env.test +++ b/desci-repo/.env.test @@ -4,7 +4,7 @@ NODE_ENV=test PORT=5484 # mapped to 5486 WS_PORT=5445 # mapped to 5446 -IPFS_NODE_URL=http://host.docker.internal:5002 +IPFS_NODE_URL=http://host.docker.internal:5003 PUBLIC_IPFS_RESOLVER=https://ipfs.io ### Database - Postgres PG_HOST=host.docker.internal diff --git a/desci-repo/src/config.ts b/desci-repo/src/config.ts index 77fcdf4c..20a668d3 100644 --- a/desci-repo/src/config.ts +++ b/desci-repo/src/config.ts @@ -2,5 +2,5 @@ export const PUBLIC_IPFS_PATH = process.env.NODE_ENV === 'dev' ? `http://host.docker.internal:8089/ipfs` : process.env.NODE_ENV === 'test' - ? 'http://host.docker.internal:8090/ipfs' + ? 'http://host.docker.internal:8091/ipfs' : 'https://ipfs.desci.com/ipfs'; \ No newline at end of file diff --git a/desci-server/package.json b/desci-server/package.json index 5bcb6d41..ba987795 100755 --- a/desci-server/package.json +++ b/desci-server/package.json @@ -38,7 +38,8 @@ "prettier": "prettier --config .prettierrc --write './**/*.{ts,js,css,scss,json,md}'", "test:destructive": "NODE_OPTIONS=\"--experimental-specifier-resolution=node --loader=ts-node/esm\" mocha --colors --require ts-node/register 'test/integration/**/*.test.ts' --timeout 20000 --exit", "test:destructive:debug": "yarn test:destructive --inspect=0.0.0.0:9227", - "test": "yarn docker:test; export EXIT=$(echo $?); docker-compose --file ../docker-compose.test.yml --compatibility down; exit $EXIT", + "test:check": "npx tsc --project ./tsconfig-test.json", + "test": "yarn test:check && yarn docker:test; export EXIT=$(echo $?); docker-compose --file ../docker-compose.test.yml --compatibility down; exit $EXIT", "coverage:destructive": "nyc --all --parser-plugins='[\"importAssertions\"]' -r lcov -e .ts -x \"*.test.ts\" npm run test:destructive", "coverage:destructive:debug": "nyc --all --parser-plugins='[\"importAssertions\"]' -r lcov -e .ts -x \"*.test.ts\" npm run test:destructive:debug", "commit": "git-cz", diff --git a/desci-server/src/config/index.ts b/desci-server/src/config/index.ts index ba9134dd..048ad753 100644 --- a/desci-server/src/config/index.ts +++ b/desci-server/src/config/index.ts @@ -4,7 +4,7 @@ export const PUBLIC_IPFS_PATH = process.env.NODE_ENV === 'dev' ? `http://host.docker.internal:8089/ipfs` : process.env.NODE_ENV === 'test' - ? 'http://host.docker.internal:8090/ipfs' + ? 'http://host.docker.internal:8091/ipfs' : 'https://ipfs.desci.com/ipfs'; export const MEDIA_SERVER_API_URL = process.env.NODES_MEDIA_SERVER_URL; diff --git a/desci-server/test/integration/temp.test.ts b/desci-server/test/integration/temp.test.ts new file mode 100644 index 00000000..8f9f9265 --- /dev/null +++ b/desci-server/test/integration/temp.test.ts @@ -0,0 +1,23 @@ +import 'mocha'; +import { User } from '@prisma/client'; +import { expect } from 'chai'; +import supertest from 'supertest'; + +import { prisma } from '../../src/client.js'; +import { generateAccessToken } from '../../src/controllers/auth/magic.js'; +import { app } from '../../src/index.js'; +import { testingGenerateMagicCode } from '../util.js'; + +describe('failing test', () => { + let request: supertest.SuperTest; + + before(async () => { + request = supertest(app); + }); + + describe('should fail', () => { + it('should fail', async () => { + expect(1).to.equal(2); + }); + }); +}); diff --git a/desci-server/tsconfig-test.json b/desci-server/tsconfig-test.json new file mode 100755 index 00000000..5683e053 --- /dev/null +++ b/desci-server/tsconfig-test.json @@ -0,0 +1,39 @@ +{ + "compilerOptions": { + "module": "nodenext", + /** + * Implied by "module: nodenext": + * "moduleResolution": "nodenext", + * "esModuleInterop": true, + */ + "target": "esnext", + // Recommended by docs, but a lot of errors + // "verbatimModuleSyntax": true, + "lib": [ + "esnext", + "dom" + ], + "noEmit": true, + "removeComments": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "resolveJsonModule": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "skipLibCheck": true, + // dagConcat.cjs requires this + "allowJs": true, + "inlineSourceMap": true, + "paths": { + // Overrides a built-in Response type + "express": [ + "./src/types/express" + ] + }, + "jsx": "react" + }, + "include": [ + "test/**/*.ts" + ], + "compileOnSave": true +} \ No newline at end of file diff --git a/docker-compose.test.yml b/docker-compose.test.yml index e8d9f2e5..3247cf25 100755 --- a/docker-compose.test.yml +++ b/docker-compose.test.yml @@ -41,8 +41,8 @@ services: environment: IPFS_SWARM_KEY: "/key/swarm/psk/1.0.0/\n/base16/\n9d002c50635a479d29dcc0ccb49d862952a0dcc52baddd253167adcd496c8d04" ports: - - "5002:5001" - - "8090:8080" + - "5003:5001" + - "8091:8080" volumes: - ./local-data/test/ipfs:/data/ipfs diff --git a/nodes-media/src/config/index.ts b/nodes-media/src/config/index.ts index 4afeef42..a96e403d 100644 --- a/nodes-media/src/config/index.ts +++ b/nodes-media/src/config/index.ts @@ -2,5 +2,5 @@ export const PUBLIC_IPFS_PATH = process.env.NODE_ENV === 'dev' ? `http://host.docker.internal:8089/ipfs` : process.env.NODE_ENV === 'test' - ? 'http://host.docker.internal:8090/ipfs' + ? 'http://host.docker.internal:8091/ipfs' : 'https://ipfs.desci.com/ipfs'; From 1a504c1d9ca11d464016e0145d7c42aa4d4daf19 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Tue, 25 Jun 2024 03:16:25 +0200 Subject: [PATCH 204/278] fix build --- .github/workflows/build-server.yaml | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/.github/workflows/build-server.yaml b/.github/workflows/build-server.yaml index 5d108b6f..e88e27a3 100644 --- a/.github/workflows/build-server.yaml +++ b/.github/workflows/build-server.yaml @@ -209,34 +209,6 @@ jobs: aws sts get-caller-identity kubectl describe deployments - # Only push to registry on dev - - name: Push (DEV) - if: github.ref == 'refs/heads/develop' - run: | - # Push image to AWS ECR - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com - docker pull $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-dev:${{ github.sha }} - docker tag $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-dev:${{ github.sha }} $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-dev:latest - docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-dev:latest - - - name: Push (DEMO) - if: github.ref == 'refs/heads/demo' - run: | - # Push image to AWS ECR - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com - docker pull $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-demo:${{ github.sha }} - docker tag $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-demo:${{ github.sha }} $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-demo:latest - docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-demo:latest - - - name: Push (PROD) - if: github.ref == 'refs/heads/main' - run: | - # Push image to AWS ECR - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com - docker pull $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE:${{ github.sha }} - docker tag $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE:${{ github.sha }} $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE:latest - docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE:latest - - name: Deploy to EKS (DEV) # uses: steebchen/kubectl@v2.0.0 if: github.ref == 'refs/heads/develop' From 17081a7c523dcec18e00d908307b6f75dbd1569e Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Tue, 25 Jun 2024 03:35:40 +0200 Subject: [PATCH 205/278] image tagging build fix --- .github/workflows/build-server.yaml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-server.yaml b/.github/workflows/build-server.yaml index e88e27a3..bbd50da1 100644 --- a/.github/workflows/build-server.yaml +++ b/.github/workflows/build-server.yaml @@ -147,15 +147,12 @@ jobs: -t $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE \ . - # Add additional steps here like scanning of image - - # Only push to registry on dev - name: Push (DEV) if: github.ref == 'refs/heads/develop' run: | # Push image to AWS ECR aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com - docker tag $CONTAINER_IMAGE-dev:latest $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-dev:${{ github.sha }} + docker tag $CONTAINER_IMAGE-dev:${{ github.sha }} $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-dev:${{ github.sha }} docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-dev:${{ github.sha }} - name: Push (DEMO) @@ -163,7 +160,7 @@ jobs: run: | # Push image to AWS ECR aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com - docker tag $CONTAINER_IMAGE-demo:latest $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-demo:${{ github.sha }} + docker tag $CONTAINER_IMAGE-demo:${{ github.sha }} $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-demo:${{ github.sha }} docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-demo:${{ github.sha }} - name: Push (PROD) @@ -171,7 +168,7 @@ jobs: run: | # Push image to AWS ECR aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com - docker tag $CONTAINER_IMAGE:latest $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE:${{ github.sha }} + docker tag $CONTAINER_IMAGE:${{ github.sha }} $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE:${{ github.sha }} docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE:${{ github.sha }} deploy: @@ -215,6 +212,9 @@ jobs: run: | # defaults to latest kubectl binary version kubectl apply -f desci-server/kubernetes/deployment_dev.yaml kubectl set image deployment/desci-server-dev desci-server-dev=$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-dev:${{ github.sha }} --record + docker pull $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-dev:${{ github.sha }} + docker tag $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-dev:${{ github.sha }} $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-dev:latest + docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-dev:latest - name: Deploy to EKS (DEMO) # uses: steebchen/kubectl@v2.0.0 @@ -227,6 +227,9 @@ jobs: run: | # defaults to latest kubectl binary version kubectl apply -f desci-server/kubernetes/deployment_prod.yaml kubectl set image deployment/desci-server desci-server=$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE:${{ github.sha }} --record + docker pull $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE:${{ github.sha }} + docker tag $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE:${{ github.sha }} $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE:latest + docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE:latest - name: Verify EKS Deployment (DEV) if: github.ref == 'refs/heads/develop' From c323cca86d39f42c6e10883c1b67038290aff81a Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Tue, 25 Jun 2024 03:43:32 +0200 Subject: [PATCH 206/278] remove temp failing test --- desci-server/test/integration/temp.test.ts | 23 ---------------------- 1 file changed, 23 deletions(-) delete mode 100644 desci-server/test/integration/temp.test.ts diff --git a/desci-server/test/integration/temp.test.ts b/desci-server/test/integration/temp.test.ts deleted file mode 100644 index 8f9f9265..00000000 --- a/desci-server/test/integration/temp.test.ts +++ /dev/null @@ -1,23 +0,0 @@ -import 'mocha'; -import { User } from '@prisma/client'; -import { expect } from 'chai'; -import supertest from 'supertest'; - -import { prisma } from '../../src/client.js'; -import { generateAccessToken } from '../../src/controllers/auth/magic.js'; -import { app } from '../../src/index.js'; -import { testingGenerateMagicCode } from '../util.js'; - -describe('failing test', () => { - let request: supertest.SuperTest; - - before(async () => { - request = supertest(app); - }); - - describe('should fail', () => { - it('should fail', async () => { - expect(1).to.equal(2); - }); - }); -}); From a5da277e242dfa5a275f5b7abef90791948e8a4f Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Tue, 25 Jun 2024 03:56:37 +0200 Subject: [PATCH 207/278] fix tag update latest --- .github/workflows/build-server.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/build-server.yaml b/.github/workflows/build-server.yaml index bbd50da1..1a6c4c9f 100644 --- a/.github/workflows/build-server.yaml +++ b/.github/workflows/build-server.yaml @@ -212,6 +212,7 @@ jobs: run: | # defaults to latest kubectl binary version kubectl apply -f desci-server/kubernetes/deployment_dev.yaml kubectl set image deployment/desci-server-dev desci-server-dev=$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-dev:${{ github.sha }} --record + aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com docker pull $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-dev:${{ github.sha }} docker tag $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-dev:${{ github.sha }} $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-dev:latest docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-dev:latest @@ -221,12 +222,17 @@ jobs: if: github.ref == 'refs/heads/demo' run: | # defaults to latest kubectl binary version kubectl set image deployment/desci-server-demo desci-server-demo=$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-demo:${{ github.sha }} --record + aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com + docker pull $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-demo:${{ github.sha }} + docker tag $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-demo:${{ github.sha }} $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-demo:latest + docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE-demo:latest - name: Deploy to EKS (PROD) if: github.ref == 'refs/heads/main' run: | # defaults to latest kubectl binary version kubectl apply -f desci-server/kubernetes/deployment_prod.yaml kubectl set image deployment/desci-server desci-server=$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE:${{ github.sha }} --record + aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com docker pull $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE:${{ github.sha }} docker tag $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE:${{ github.sha }} $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE:latest docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE:latest From dbc2d7275297aa9cfca4033bff93871e99c2f6b0 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Tue, 25 Jun 2024 04:08:35 +0200 Subject: [PATCH 208/278] remove dummy route --- desci-server/src/server.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/desci-server/src/server.ts b/desci-server/src/server.ts index d9d7fba6..392fecc1 100644 --- a/desci-server/src/server.ts +++ b/desci-server/src/server.ts @@ -122,10 +122,6 @@ class AppServer { this.app.use(cookieParser()); this.app.set('trust proxy', 2); // detect AWS ELB IP + cloudflare - this.app.get('/test-update', (_req, res) => { - res.status(200).json({ status: 'ok', updated: true }); - }); - this.#attachRouteHandlers(); // catch 404 errors and forward to error handler From 5e9f891e14f37503dcf712b336b563f725813ff8 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Tue, 25 Jun 2024 04:15:04 +0200 Subject: [PATCH 209/278] Additional logging shared node --- .../src/controllers/nodes/sharedNodes.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/desci-server/src/controllers/nodes/sharedNodes.ts b/desci-server/src/controllers/nodes/sharedNodes.ts index 59407817..d5deff0b 100644 --- a/desci-server/src/controllers/nodes/sharedNodes.ts +++ b/desci-server/src/controllers/nodes/sharedNodes.ts @@ -73,11 +73,15 @@ export const listSharedNodes = async (req: ListSharedNodesRequest, res: Response logger.trace({ researchObjectsLength: researchObjects.length }, 'Research objects retrieved successfully'); const publishedNodesMap = researchObjects.reduce((acc, ro) => { - // convert hex string to integer - const nodeUuidInt = Buffer.from(ro.id.substring(2), 'hex'); - // convert integer to hex - const nodeUuid = nodeUuidInt.toString('base64url'); - acc[nodeUuid] = ro; + try { + // convert hex string to integer + const nodeUuidInt = Buffer.from(ro.id.substring(2), 'hex'); + // convert integer to hex + const nodeUuid = nodeUuidInt.toString('base64url'); + acc[nodeUuid] = ro; + } catch (e) { + logger.error({ e, message: e?.message }, 'Failed to convert hex string to integer'); + } }, {}); logger.trace( @@ -111,7 +115,7 @@ export const listSharedNodes = async (req: ListSharedNodesRequest, res: Response return res.status(200).json({ ok: true, sharedNodes: filledSharedNodes }); } } catch (e) { - logger.error({ e }, 'Failed to retrieve shared nodes for user'); + logger.error({ e, message: e?.message }, 'Failed to retrieve shared nodes for user'); return res.status(500).json({ error: 'Failed to retrieve shared nodes' }); } From 53eaa6ed5acf284b095704bdf85f473c1c44141f Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Tue, 25 Jun 2024 04:17:39 +0200 Subject: [PATCH 210/278] remove debugging statement in build --- .github/workflows/build-isolated-media-server.yaml | 1 - .github/workflows/build-nodes-media.yaml | 1 - .github/workflows/build-repo-server.yaml | 1 - .github/workflows/build-reverse-proxy.yaml | 1 - .github/workflows/build-server.yaml | 2 -- .github/workflows/deploy-staging-services.yaml | 7 +------ .github/workflows/run-migrations-dev.yaml | 1 - 7 files changed, 1 insertion(+), 13 deletions(-) diff --git a/.github/workflows/build-isolated-media-server.yaml b/.github/workflows/build-isolated-media-server.yaml index cb8ca9e8..e963f5cf 100644 --- a/.github/workflows/build-isolated-media-server.yaml +++ b/.github/workflows/build-isolated-media-server.yaml @@ -55,7 +55,6 @@ jobs: sudo apt-get install less echo ${{ secrets.KUBE_CONFIG_DATA }} | base64 --decode > $HOME/.kube/config aws sts get-caller-identity - kubectl describe deployments - name: Build and tag the image (DEV) if: github.ref == 'refs/heads/develop' diff --git a/.github/workflows/build-nodes-media.yaml b/.github/workflows/build-nodes-media.yaml index b42f5a6e..87906af1 100644 --- a/.github/workflows/build-nodes-media.yaml +++ b/.github/workflows/build-nodes-media.yaml @@ -54,7 +54,6 @@ jobs: sudo apt-get install less echo ${{ secrets.KUBE_CONFIG_DATA }} | base64 --decode > $HOME/.kube/config aws sts get-caller-identity - kubectl describe deployments - name: Build and tag the image (DEV) if: github.ref == 'refs/heads/develop' diff --git a/.github/workflows/build-repo-server.yaml b/.github/workflows/build-repo-server.yaml index bab5513c..ff50b44e 100644 --- a/.github/workflows/build-repo-server.yaml +++ b/.github/workflows/build-repo-server.yaml @@ -90,7 +90,6 @@ jobs: sudo apt-get install less echo ${{ secrets.KUBE_CONFIG_DATA }} | base64 --decode > $HOME/.kube/config aws sts get-caller-identity - kubectl describe deployments - name: Build and tag the image (DEV) if: github.ref == 'refs/heads/develop' diff --git a/.github/workflows/build-reverse-proxy.yaml b/.github/workflows/build-reverse-proxy.yaml index 9cfcb68b..c2512f9a 100644 --- a/.github/workflows/build-reverse-proxy.yaml +++ b/.github/workflows/build-reverse-proxy.yaml @@ -49,7 +49,6 @@ jobs: sudo apt-get install less echo ${{ secrets.KUBE_CONFIG_DATA }} | base64 --decode > $HOME/.kube/config aws sts get-caller-identity - kubectl describe deployments - name: Build and tag the image (DEV) if: github.ref == 'refs/heads/develop' diff --git a/.github/workflows/build-server.yaml b/.github/workflows/build-server.yaml index 1a6c4c9f..ebef63f2 100644 --- a/.github/workflows/build-server.yaml +++ b/.github/workflows/build-server.yaml @@ -102,7 +102,6 @@ jobs: sudo apt-get install less echo ${{ secrets.KUBE_CONFIG_DATA }} | base64 --decode > $HOME/.kube/config aws sts get-caller-identity - kubectl describe deployments # - name: Check Docker Version # run: docker --version @@ -204,7 +203,6 @@ jobs: sudo apt-get install less echo ${{ secrets.KUBE_CONFIG_DATA }} | base64 --decode > $HOME/.kube/config aws sts get-caller-identity - kubectl describe deployments - name: Deploy to EKS (DEV) # uses: steebchen/kubectl@v2.0.0 diff --git a/.github/workflows/deploy-staging-services.yaml b/.github/workflows/deploy-staging-services.yaml index c1bf2437..a810c2da 100644 --- a/.github/workflows/deploy-staging-services.yaml +++ b/.github/workflows/deploy-staging-services.yaml @@ -46,7 +46,6 @@ jobs: sudo apt-get install less echo ${{ secrets.KUBE_CONFIG_DATA }} | base64 --decode > $HOME/.kube/config aws sts get-caller-identity - kubectl describe deployments - name: Build and tag desci-media-isolated image (STAGING) run: | @@ -103,7 +102,6 @@ jobs: sudo apt-get install less echo ${{ secrets.KUBE_CONFIG_DATA }} | base64 --decode > $HOME/.kube/config aws sts get-caller-identity - kubectl describe deployments - name: Build and tag nodes-media-server image (STAGING) run: | @@ -160,7 +158,6 @@ jobs: sudo apt-get install less echo ${{ secrets.KUBE_CONFIG_DATA }} | base64 --decode > $HOME/.kube/config aws sts get-caller-identity - kubectl describe deployments - name: Stub contract run: | @@ -222,7 +219,6 @@ jobs: sudo apt-get install less echo ${{ secrets.KUBE_CONFIG_DATA }} | base64 --decode > $HOME/.kube/config aws sts get-caller-identity - kubectl describe deployments - name: Stub contract run: | @@ -289,7 +285,6 @@ jobs: sudo apt-get install less echo ${{ secrets.KUBE_CONFIG_DATA }} | base64 --decode > $HOME/.kube/config aws sts get-caller-identity - kubectl describe deployments - name: Build and tag the image (STAGING) run: | @@ -307,7 +302,7 @@ jobs: docker tag $CONTAINER_IMAGE_PROXY-staging:latest $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE_PROXY-staging:latest docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE_PROXY-staging:${{ github.sha }} docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$CONTAINER_IMAGE_PROXY-staging:latest - + - name: Deploy to EKS (STAGING) run: | # defaults to latest kubectl binary version kubectl apply -f $CONTAINER_IMAGE_PROXY/deployment.yaml diff --git a/.github/workflows/run-migrations-dev.yaml b/.github/workflows/run-migrations-dev.yaml index 21db0989..01ec1aea 100644 --- a/.github/workflows/run-migrations-dev.yaml +++ b/.github/workflows/run-migrations-dev.yaml @@ -39,7 +39,6 @@ jobs: sudo apt-get install less echo ${{ secrets.KUBE_CONFIG_DATA }} | base64 --decode > $HOME/.kube/config aws sts get-caller-identity - kubectl describe deployments - name: Migrate DB (DEV) if: github.ref == 'refs/heads/develop' From 60ff71b6f8baaf880d68dd34f6f59d65ba10ff66 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Tue, 25 Jun 2024 06:29:06 +0200 Subject: [PATCH 211/278] more logging --- desci-server/src/controllers/nodes/sharedNodes.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/desci-server/src/controllers/nodes/sharedNodes.ts b/desci-server/src/controllers/nodes/sharedNodes.ts index d5deff0b..8c2d6d8a 100644 --- a/desci-server/src/controllers/nodes/sharedNodes.ts +++ b/desci-server/src/controllers/nodes/sharedNodes.ts @@ -80,8 +80,9 @@ export const listSharedNodes = async (req: ListSharedNodesRequest, res: Response const nodeUuid = nodeUuidInt.toString('base64url'); acc[nodeUuid] = ro; } catch (e) { - logger.error({ e, message: e?.message }, 'Failed to convert hex string to integer'); + logger.error({ acc, ro, e, message: e?.message }, 'Failed to convert hex string to integer'); } + return acc; }, {}); logger.trace( From 28633cc4d70dc3e8e695eb04b6fd198200b8ba8f Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Tue, 25 Jun 2024 00:42:18 +0200 Subject: [PATCH 212/278] add support for DOI meta in external url uploads --- desci-server/src/controllers/nodes/doi.ts | 7 +++-- .../src/services/AutomatedMetadata.ts | 5 ++-- .../services/data/externalUrlProcessing.ts | 30 ++++++++++++++++++- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/desci-server/src/controllers/nodes/doi.ts b/desci-server/src/controllers/nodes/doi.ts index 62ec31ff..9b4b1195 100644 --- a/desci-server/src/controllers/nodes/doi.ts +++ b/desci-server/src/controllers/nodes/doi.ts @@ -53,7 +53,7 @@ export const automateManuscriptDoi = async (req: RequestWithNode, res: Response, const component = latestManifest.components[componentIndex] as PdfComponent; - if (component.payload.doi) throw new ForbiddenError(`${component.subtype || component.type} already has a DOI`); + // if (component.payload.doi) throw new ForbiddenError(`${component.subtype || component.type} already has a DOI`); const queryTitle = component.payload.path.split('/').pop().replace(/\.pdf/g, '') || @@ -88,7 +88,10 @@ export const automateManuscriptDoi = async (req: RequestWithNode, res: Response, // } // pull metadata from AM service - metadata = await metadataClient.getResourceMetadata({ cid: component.payload.cid }); + metadata = await metadataClient.getResourceMetadata({ + cid: component.payload.cid, + doi: doi || component.payload.doi[0], + }); // todo: pull metadata from crossrefClient#getDoiMetadata // const doiMetadata = await crossRefClient.getDoiMetadata(''); diff --git a/desci-server/src/services/AutomatedMetadata.ts b/desci-server/src/services/AutomatedMetadata.ts index b924c0d0..dcb6917f 100644 --- a/desci-server/src/services/AutomatedMetadata.ts +++ b/desci-server/src/services/AutomatedMetadata.ts @@ -158,7 +158,8 @@ export class AutomatedMetadataClient { ...(creator['@id'] && creator['@id'].toLowerCase() !== 'none' && { orcid: creator['@id'] }), })) : []; - const keywords = output?.keywords ? output.keywords.map((keyword) => keyword.display_name) : []; + const keywords = + output?.keywords && Array.isArray(output.keywords) ? output.keywords.map((keyword) => keyword.display_name) : []; const metadata: MetadataResponse = { authors, keywords, @@ -166,7 +167,7 @@ export class AutomatedMetadataClient { pdfUrl: output.oa_url, abstract: output.abstract ?? '', }; - logger.info(metadata, 'METADATA'); + return metadata; } diff --git a/desci-server/src/services/data/externalUrlProcessing.ts b/desci-server/src/services/data/externalUrlProcessing.ts index c3e81337..a02b4c09 100644 --- a/desci-server/src/services/data/externalUrlProcessing.ts +++ b/desci-server/src/services/data/externalUrlProcessing.ts @@ -60,7 +60,7 @@ const logger = parentLogger.child({ interface ProcessExternalUrlDataToIpfsParams { // files: any[]; - externalUrl: any; + externalUrl: { path: string; url: string; doi?: string }; user: User; node: Node; /** @@ -244,6 +244,34 @@ export async function processExternalUrlDataToIpfs({ if (firstNestingComponents?.length > 0) { updatedManifest = await addComponentsToDraftManifest(node, firstNestingComponents); } + + logger.info({ EXTERNAL_DOI: externalUrl }, 'External URL DOI'); + if (componentType === ResearchObjectComponentType.PDF && externalUrl.doi) { + const componentIndex = updatedManifest.components.findIndex( + (comp) => comp.type === ResearchObjectComponentType.PDF, + ); + const comp = updatedManifest.components[componentIndex]; + const res = await repoService.dispatchAction({ + uuid: node.uuid, + documentId: node.manifestDocumentId as DocumentId, + actions: [ + { + type: 'Update Component', + component: { + ...comp, + payload: { + ...comp.payload, + ...(externalUrl.doi && { + doi: [externalUrl.doi], + }), + }, + }, + componentIndex, + }, + ], + }); + updatedManifest = res.manifest; + } } updatedManifest = updatedManifest ?? (await repoService.getDraftManifest(ltsNode.uuid as NodeUuid)); From febd58ed22216f24bf19209b65ca540ac73c1a50 Mon Sep 17 00:00:00 2001 From: m0ar Date: Sun, 23 Jun 2024 11:39:37 +0200 Subject: [PATCH 213/278] contracts: add registry activation script --- .../scripts/alias-registry/README.md | 41 +++++++++++++++++ .../alias-registry/activateAliasRegistry.mjs | 46 +++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 desci-contracts/scripts/alias-registry/README.md create mode 100644 desci-contracts/scripts/alias-registry/activateAliasRegistry.mjs diff --git a/desci-contracts/scripts/alias-registry/README.md b/desci-contracts/scripts/alias-registry/README.md new file mode 100644 index 00000000..4b123c93 --- /dev/null +++ b/desci-contracts/scripts/alias-registry/README.md @@ -0,0 +1,41 @@ +# dPID alias registry scripts +These scripts are used to interact with the dPID alias registry contracts. There are two deployments, `dev` and `prod`, which correspond to the environment for the previous dPID token contract and registry. Both of these envionments currently live on Optimism Sepolia. + +The contract is `pausable`, and deployed in a paused state. For dPID minting not to revert, the contracts need to be unpaused before they are fully operational. Meanwhile, the owner can perform imports/updates of legacy dPID entries. + +The contract is `ownable`, and the owner is initially the `PRIVATE_KEY` used to configure the deployment script. Note this `PRIVATE_KEY` variable isn't directly referred to in the scripts, but is known to hardhat from `hardhat.config.ts`. + +Run the scripts using this pattern, where `--network` pulls the required information from the hardhat config: + +```shell +ARG1=ble ARG2=blu npx hardhat run --network optimismSepolia scripts/alias-registry/xyz.mjs +``` + +## Scripts +These scripts are used to interact with the alias registry contracts. More detailed documentation is available in the script files. + +### `migrateToAliasRegistry.mjs` +Deploys a new dPID alias registry, populating the legacy entries mapping with data from the dPID API. After import, it validates the information in the contract against the data from the dPID API. It saves a log file in `migration-data`, showing the deployed address and each imported dPID. + +Arguments: +- `ENV`, selects which dPID API it should use for migration data. Either `dev` or `prod`. +- `PRIVATE_KEY`, makes the deployments, is set as contract owner, and makes import transactions. + +### `syncAliasRegistryMigration.mjs` +For a given alias registry address, pulls the dPID API data and validates the existence and history of each dPID, importing / updating the legacy entires as needed. This can be run multiple times, as it only concerns itself with deltas and is idempotent if nothing has changed. + +Arguments: +- `ENV`, selects which dPID API it should use for migration data. Either `dev` or `prod`. If this is set to anything else than the env used to populate the contract initially, it'll likely permanently break the contract. +- `PRIVATE_KEY`, makes import transactions (needs to be owner). +- `REGISTRY_ADDRESS`, select which contract to sync (see artifacts in `.openzeppelin` or consult the migration data). + +### `activateAliasRegistry.mjs` +Sets the first dPID (i.e., next available integer) and unpauses the contract, leaving it open for external callers to mint identifiers. + +Arguments: +- `PRIVATE_KEY`, makes the transactions (needs to be owner). +- `NEXT_DPID`, set the next available dPID. This should correspond to the last legacy dPID, plus one. +- `REGISTRY_ADDRESS`, select which contract to activate (see artifacts in `.openzeppelin` or consult the migration data). + +### `deployDpidAliasRegistry.js` +This script is only used for deploying to the local testchain, as part of the monorepo `dockerDev.sh` script. diff --git a/desci-contracts/scripts/alias-registry/activateAliasRegistry.mjs b/desci-contracts/scripts/alias-registry/activateAliasRegistry.mjs new file mode 100644 index 00000000..89ead36e --- /dev/null +++ b/desci-contracts/scripts/alias-registry/activateAliasRegistry.mjs @@ -0,0 +1,46 @@ +/** + * ALIAS REGISTRY MIGRATION + * + * Deploys a new dPID alias registry, through proxy. Imports existing dPID's as + * legacy entries, and validates the correctness of these imports afterward. + * If the imports are interrupted, it can be continued using the syncAliasRegistryMigration.mjs + * script. The registry is initialized in a paused state, meaning minting new dPID's + * is disabled, but imports and other administration like configuring the dPID + * counter can still be done. + * + * The script performs the following actions: + * - Deploys new instance of the registry + * - Imports legacy dPID's, validating correctness + * - Immediately pauses minting of new dPID's + * + * Steps required to fully activate: + * - Admin calls `setNextDpid` to whatever is the next when legacy contract is disabled + * - Admin calls `unpause` to allow minting new dPID's + * + * Required arguments (env variables): + * 1. PRIVATE_KEY - Owner/admin identity (see hardhat.config.ts) + * 2. ENV - Environment to sync legacy entires from ("dev" or "prod") + */ +import hardhat from "hardhat"; +const { ethers, hardhatArguments } = hardhat; + +const REGISTRY_ADDRESS = process.env.REGISTRY_ADDRESS; +if (REGISTRY_ADDRESS === undefined) { + throw new Error("REGISTRY_ADDRESS unset"); +}; + +const NEXT_DPID = process.env.NEXT_DPID; +if (NEXT_DPID === undefined) { + throw new Error("NEXT_DPID unset"); +}; + +const DpidAliasRegistryFactory = await ethers.getContractFactory("DpidAliasRegistry"); +const registry = DpidAliasRegistryFactory.attach(REGISTRY_ADDRESS); + +const setNextDpid = await registry.setNextDpid(NEXT_DPID) +await setNextDpid.wait(); + +const unpause = await registry.unpause(); +await unpause.wait(); + +console.log(`🐎 let dPID minting commence from ${NEXT_DPID} at ${REGISTRY_ADDRESS}`); From 2d36efbf04e4da447e564bca6cbb22eaefbe83c5 Mon Sep 17 00:00:00 2001 From: m0ar Date: Tue, 25 Jun 2024 11:40:23 +0200 Subject: [PATCH 214/278] contracts: deploy and migrate prod contracts, updating package --- .../opSepoliaProd-dpid-alias-registry.json | 201 + desci-contracts/index.ts | 4 +- ...ync_dev_Mon,_24_Jun_2024_15:21:59_GMT.json | 4979 +++++++++++++++++ ...ry_prod_Tue,_25_Jun_2024_08:36:06_GMT.json | 3200 +++++++++++ desci-contracts/package.json | 2 +- 5 files changed, 8383 insertions(+), 3 deletions(-) create mode 100644 desci-contracts/.openzeppelin/opSepoliaProd-dpid-alias-registry.json create mode 100644 desci-contracts/migration-data/aliasRegistrySync_dev_Mon,_24_Jun_2024_15:21:59_GMT.json create mode 100644 desci-contracts/migration-data/aliasRegistry_prod_Tue,_25_Jun_2024_08:36:06_GMT.json diff --git a/desci-contracts/.openzeppelin/opSepoliaProd-dpid-alias-registry.json b/desci-contracts/.openzeppelin/opSepoliaProd-dpid-alias-registry.json new file mode 100644 index 00000000..a09e8be7 --- /dev/null +++ b/desci-contracts/.openzeppelin/opSepoliaProd-dpid-alias-registry.json @@ -0,0 +1,201 @@ +{ + "manifestVersion": "3.2", + "admin": { + "address": "0x1cb519A0f2C7F0695BfDd4a71473885a070D2144", + "txHash": "0xf3cb35faa31f949a534a766f9beff65f35323c151dbcca5f844084900e07372e" + }, + "proxies": [ + { + "address": "0x935e08ce8AFdefa17CD1579f5a3CD31224e47456", + "txHash": "0x5132459b8b0e828aad6e54de40b58de3b7e55e1c40b0a15f99cda3373629f344", + "kind": "transparent" + } + ], + "impls": { + "a230b5b705959d3e3e4fc01d0b0da971f2e249681ed6a78165280ba33db100b5": { + "address": "0x40EcC698B074604a85Bb877Eb7362ab6Cf14BaDE", + "txHash": "0xb81b2d4547119d842d88e7aaeb582cec2eca72e891c17dc20df64425a00f9e5f", + "layout": { + "solcVersion": "0.8.4", + "storage": [ + { + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62", + "retypedFrom": "bool" + }, + { + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool", + "contract": "Initializable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67" + }, + { + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage", + "contract": "ContextUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" + }, + { + "label": "_owner", + "offset": 0, + "slot": "51", + "type": "t_address", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:22" + }, + { + "label": "__gap", + "offset": 0, + "slot": "52", + "type": "t_array(t_uint256)49_storage", + "contract": "OwnableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:94" + }, + { + "label": "_paused", + "offset": 0, + "slot": "101", + "type": "t_bool", + "contract": "PausableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" + }, + { + "label": "__gap", + "offset": 0, + "slot": "102", + "type": "t_array(t_uint256)49_storage", + "contract": "PausableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116" + }, + { + "label": "nextDpid", + "offset": 0, + "slot": "151", + "type": "t_uint256", + "contract": "DpidAliasRegistry", + "src": "contracts/DpidAliasRegistry.sol:10" + }, + { + "label": "registry", + "offset": 0, + "slot": "152", + "type": "t_mapping(t_uint256,t_string_storage)", + "contract": "DpidAliasRegistry", + "src": "contracts/DpidAliasRegistry.sol:13" + }, + { + "label": "reverseRegistry", + "offset": 0, + "slot": "153", + "type": "t_mapping(t_string_memory_ptr,t_uint256)", + "contract": "DpidAliasRegistry", + "src": "contracts/DpidAliasRegistry.sol:16" + }, + { + "label": "legacy", + "offset": 0, + "slot": "154", + "type": "t_mapping(t_uint256,t_struct(LegacyDpidEntry)4712_storage)", + "contract": "DpidAliasRegistry", + "src": "contracts/DpidAliasRegistry.sol:125" + } + ], + "types": { + "t_address": { + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_struct(LegacyVersion)4705_storage)dyn_storage": { + "label": "struct DpidAliasRegistry.LegacyVersion[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)49_storage": { + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "label": "bool", + "numberOfBytes": "1" + }, + "t_mapping(t_string_memory_ptr,t_uint256)": { + "label": "mapping(string => uint256)", + "numberOfBytes": "32" + }, + "t_mapping(t_uint256,t_string_storage)": { + "label": "mapping(uint256 => string)", + "numberOfBytes": "32" + }, + "t_mapping(t_uint256,t_struct(LegacyDpidEntry)4712_storage)": { + "label": "mapping(uint256 => struct DpidAliasRegistry.LegacyDpidEntry)", + "numberOfBytes": "32" + }, + "t_string_memory_ptr": { + "label": "string", + "numberOfBytes": "32" + }, + "t_string_storage": { + "label": "string", + "numberOfBytes": "32" + }, + "t_struct(LegacyDpidEntry)4712_storage": { + "label": "struct DpidAliasRegistry.LegacyDpidEntry", + "members": [ + { + "label": "owner", + "type": "t_address", + "offset": 0, + "slot": "0" + }, + { + "label": "versions", + "type": "t_array(t_struct(LegacyVersion)4705_storage)dyn_storage", + "offset": 0, + "slot": "1" + } + ], + "numberOfBytes": "64" + }, + "t_struct(LegacyVersion)4705_storage": { + "label": "struct DpidAliasRegistry.LegacyVersion", + "members": [ + { + "label": "cid", + "type": "t_string_storage", + "offset": 0, + "slot": "0" + }, + { + "label": "time", + "type": "t_uint256", + "offset": 0, + "slot": "1" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" + } + }, + "namespaces": {} + } + } + } +} diff --git a/desci-contracts/index.ts b/desci-contracts/index.ts index 4f5d0fb8..7f3b7d8c 100644 --- a/desci-contracts/index.ts +++ b/desci-contracts/index.ts @@ -7,6 +7,7 @@ import prodRoInfo from "./.openzeppelin/sepoliaProd-research-object.json"; import prodDpidInfo from "./.openzeppelin/sepoliaProd-dpid.json"; import localDpidAliasInfo from "./.openzeppelin/unknown-dpid-alias-registry.json"; import devDpidAliasInfo from "./.openzeppelin/opSepoliaDev-dpid-alias-registry.json"; +import prodDpidAliasInfo from "./.openzeppelin/opSepoliaProd-dpid-alias-registry.json"; export const contracts = { localRoInfo, @@ -17,6 +18,5 @@ export const contracts = { prodDpidInfo, localDpidAliasInfo, devDpidAliasInfo, - // TODO update when opt mainnet contracts are deployed - prodDpidAliasInfo: { proxies: [ { address: "NOT_DEPLOYED" }]}, + prodDpidAliasInfo, }; diff --git a/desci-contracts/migration-data/aliasRegistrySync_dev_Mon,_24_Jun_2024_15:21:59_GMT.json b/desci-contracts/migration-data/aliasRegistrySync_dev_Mon,_24_Jun_2024_15:21:59_GMT.json new file mode 100644 index 00000000..fce792b1 --- /dev/null +++ b/desci-contracts/migration-data/aliasRegistrySync_dev_Mon,_24_Jun_2024_15:21:59_GMT.json @@ -0,0 +1,4979 @@ +[ + { + "dpid": "0", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreie2idd2yuwibppujafgtfc6cczopht4q47y563q4paml2me2dsh6y", + "time": 1675737468 + }, + { + "cid": "bafkreie2idd2yuwibppujafgtfc6cczopht4q47y563q4paml2me2dsh6y", + "time": 1675737468 + } + ], + "validationError": false + }, + { + "dpid": "1", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigbp7bahnrxujbz5uu3j6hzmyimq7wijkucwyi4bc5tbvka5xw3wq", + "time": 1675781796 + }, + { + "cid": "bafkreigbp7bahnrxujbz5uu3j6hzmyimq7wijkucwyi4bc5tbvka5xw3wq", + "time": 1675781796 + }, + { + "cid": "bafkreigwzsizb76b62ln5xnhhqeypxhyqwwyp56zcprl52siut2q7h2lky", + "time": 1682818404 + }, + { + "cid": "bafkreigwzsizb76b62ln5xnhhqeypxhyqwwyp56zcprl52siut2q7h2lky", + "time": 1682818404 + }, + { + "cid": "bafkreigwzsizb76b62ln5xnhhqeypxhyqwwyp56zcprl52siut2q7h2lky", + "time": 1682818608 + }, + { + "cid": "bafkreigwzsizb76b62ln5xnhhqeypxhyqwwyp56zcprl52siut2q7h2lky", + "time": 1682818608 + } + ], + "validationError": false + }, + { + "dpid": "2", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihlsxjw3gzrikm2att6sd2yty4qx37z3fgmzokrm6fd3oony2qqby", + "time": 1676095440 + }, + { + "cid": "bafkreihlsxjw3gzrikm2att6sd2yty4qx37z3fgmzokrm6fd3oony2qqby", + "time": 1676095440 + }, + { + "cid": "bafkreigvalv7basyqxn57b5ittssieecsccy7qaypmy6s7egr2o5tcqnda", + "time": 1676096820 + }, + { + "cid": "bafkreigvalv7basyqxn57b5ittssieecsccy7qaypmy6s7egr2o5tcqnda", + "time": 1676096820 + } + ], + "validationError": false + }, + { + "dpid": "3", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiancsq3yywjzkoyevwhn4hxyzgcfbdb72jspegmwy6uacd2cztpra", + "time": 1676725008 + }, + { + "cid": "bafkreiancsq3yywjzkoyevwhn4hxyzgcfbdb72jspegmwy6uacd2cztpra", + "time": 1676725008 + } + ], + "validationError": false + }, + { + "dpid": "4", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreick32zk4ennjwwy7vqva7wpjo2w5d4fkwhg7hkrdjk63xq5r6gup4", + "time": 1676988612 + }, + { + "cid": "bafkreick32zk4ennjwwy7vqva7wpjo2w5d4fkwhg7hkrdjk63xq5r6gup4", + "time": 1676988612 + } + ], + "validationError": false + }, + { + "dpid": "5", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihra4e2ejsm7yqra4wmo2ww43j4ndvylfsrv5obobkl2k666baram", + "time": 1676996292 + }, + { + "cid": "bafkreihra4e2ejsm7yqra4wmo2ww43j4ndvylfsrv5obobkl2k666baram", + "time": 1676996292 + } + ], + "validationError": false + }, + { + "dpid": "6", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiee7atuqdvq7dtxf2msslelz2ubst2g64oigetxunn352ryqvuoti", + "time": 1677066240 + }, + { + "cid": "bafkreiee7atuqdvq7dtxf2msslelz2ubst2g64oigetxunn352ryqvuoti", + "time": 1677066240 + } + ], + "validationError": false + }, + { + "dpid": "7", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidi2idvbbbg5y6iuf3bnbdo7gkyzgoz3hik2hghr3rl3gd7nplnwe", + "time": 1677080820 + }, + { + "cid": "bafkreidi2idvbbbg5y6iuf3bnbdo7gkyzgoz3hik2hghr3rl3gd7nplnwe", + "time": 1677080820 + }, + { + "cid": "bafkreicyvzgk632l2zn55dkbscjrwrlrxlckrxjhpxn6kiv4roegwzprpi", + "time": 1677081012 + }, + { + "cid": "bafkreicyvzgk632l2zn55dkbscjrwrlrxlckrxjhpxn6kiv4roegwzprpi", + "time": 1677081012 + } + ], + "validationError": false + }, + { + "dpid": "8", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibnhuq4tliestyutqxrfco4wwr3gxyrp7dlydxvgkddo6euet5yyu", + "time": 1677144720 + }, + { + "cid": "bafkreibnhuq4tliestyutqxrfco4wwr3gxyrp7dlydxvgkddo6euet5yyu", + "time": 1677144720 + } + ], + "validationError": false + }, + { + "dpid": "9", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigjjlyedw3l7yfunjhaooe226hemiqz7pkeqb3arfmwvujknaa7pe", + "time": 1677230328 + }, + { + "cid": "bafkreigjjlyedw3l7yfunjhaooe226hemiqz7pkeqb3arfmwvujknaa7pe", + "time": 1677230328 + } + ], + "validationError": false + }, + { + "dpid": "10", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihbcdgctujsajvlhbbcghfkg766pprlgatvujzkw6utteryn737wi", + "time": 1677510672 + }, + { + "cid": "bafkreihbcdgctujsajvlhbbcghfkg766pprlgatvujzkw6utteryn737wi", + "time": 1677510672 + }, + { + "cid": "bafkreif6omh6d2nosj7exr4gybupz3i6owb7ig7mfha23bebzbbzgtj3ty", + "time": 1677511224 + }, + { + "cid": "bafkreif6omh6d2nosj7exr4gybupz3i6owb7ig7mfha23bebzbbzgtj3ty", + "time": 1677511224 + } + ], + "validationError": false + }, + { + "dpid": "11", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreig75cxpsu2zhnkej7nwqszduw6l32luo3opikzsqa5wpfchnl7sua", + "time": 1678309056 + }, + { + "cid": "bafkreig75cxpsu2zhnkej7nwqszduw6l32luo3opikzsqa5wpfchnl7sua", + "time": 1678309056 + } + ], + "validationError": false + }, + { + "dpid": "12", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigvec6jtxth3eessemov7x62wjhtfpfihdleanekwx5l47rkxclcu", + "time": 1678771692 + }, + { + "cid": "bafkreigvec6jtxth3eessemov7x62wjhtfpfihdleanekwx5l47rkxclcu", + "time": 1678771692 + } + ], + "validationError": false + }, + { + "dpid": "13", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreienztazc23yp5ejvwymgekqf2kmx6foasxul7yzt6w5crjwceqsea", + "time": 1678814328 + }, + { + "cid": "bafkreienztazc23yp5ejvwymgekqf2kmx6foasxul7yzt6w5crjwceqsea", + "time": 1678814328 + }, + { + "cid": "bafkreid4yx77dkhlbmx2gqwwki6y2rjmuybnqkxqmxnoyjtx7uhgdkdeu4", + "time": 1680117252 + }, + { + "cid": "bafkreid4yx77dkhlbmx2gqwwki6y2rjmuybnqkxqmxnoyjtx7uhgdkdeu4", + "time": 1680117252 + } + ], + "validationError": false + }, + { + "dpid": "14", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiasx7tcckutok7a7yk7ej2pv6bolo5naihlk2gny6tpykcfvzxqm4", + "time": 1679014104 + }, + { + "cid": "bafkreiasx7tcckutok7a7yk7ej2pv6bolo5naihlk2gny6tpykcfvzxqm4", + "time": 1679014104 + } + ], + "validationError": false + }, + { + "dpid": "15", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifjuqlmsnnr2vlhwxrjsgu5zczwgodqjuzmo4kzgpzzu5zn42ivby", + "time": 1679219244 + }, + { + "cid": "bafkreifjuqlmsnnr2vlhwxrjsgu5zczwgodqjuzmo4kzgpzzu5zn42ivby", + "time": 1679219244 + }, + { + "cid": "bafkreiar3d6vkcyvfnk7kfhu4yrvul6hsn4fnjrwgq7wbl27t4e3ehfhwq", + "time": 1679219328 + }, + { + "cid": "bafkreiar3d6vkcyvfnk7kfhu4yrvul6hsn4fnjrwgq7wbl27t4e3ehfhwq", + "time": 1679219328 + }, + { + "cid": "bafkreiar3d6vkcyvfnk7kfhu4yrvul6hsn4fnjrwgq7wbl27t4e3ehfhwq", + "time": 1679219484 + }, + { + "cid": "bafkreiar3d6vkcyvfnk7kfhu4yrvul6hsn4fnjrwgq7wbl27t4e3ehfhwq", + "time": 1679219484 + } + ], + "validationError": false + }, + { + "dpid": "16", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreig27rnst73rqnqgtesyo32xhrhaqtdxbvtdohwnjdzua7cyapghbu", + "time": 1679343324 + }, + { + "cid": "bafkreig27rnst73rqnqgtesyo32xhrhaqtdxbvtdohwnjdzua7cyapghbu", + "time": 1679343324 + } + ], + "validationError": false + }, + { + "dpid": "17", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigggibyev5x4w3tcydslfl3j5g2fl2sabfcxvdzqeajzfg3tqignq", + "time": 1679409324 + }, + { + "cid": "bafkreigggibyev5x4w3tcydslfl3j5g2fl2sabfcxvdzqeajzfg3tqignq", + "time": 1679409324 + } + ], + "validationError": false + }, + { + "dpid": "18", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigghoctitgbpsjl6elgjkdlpu26t6zon7gqfx7cuhprsyykcjgvee", + "time": 1679409744 + }, + { + "cid": "bafkreigghoctitgbpsjl6elgjkdlpu26t6zon7gqfx7cuhprsyykcjgvee", + "time": 1679409744 + } + ], + "validationError": false + }, + { + "dpid": "19", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicvdmmzw7tyaa7dkaikb7dcowjjbu3cv76rhvxqdbzm7gcg4inrfq", + "time": 1679539764 + }, + { + "cid": "bafkreicvdmmzw7tyaa7dkaikb7dcowjjbu3cv76rhvxqdbzm7gcg4inrfq", + "time": 1679539764 + } + ], + "validationError": false + }, + { + "dpid": "20", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreie6bxf7u3z45sn2amk7ocsjihloiecfncmwsgvqoamqjnczfwnexy", + "time": 1679540424 + }, + { + "cid": "bafkreie6bxf7u3z45sn2amk7ocsjihloiecfncmwsgvqoamqjnczfwnexy", + "time": 1679540424 + }, + { + "cid": "bafkreibnxznsx2xwdasyhjr2epkypjohuvz5qy35iu2elyoygjnfbk7im4", + "time": 1680554796 + }, + { + "cid": "bafkreibnxznsx2xwdasyhjr2epkypjohuvz5qy35iu2elyoygjnfbk7im4", + "time": 1680554796 + } + ], + "validationError": false + }, + { + "dpid": "21", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiecholb67ldemsvyr7js2x6dewjnsylvpk47ejyhrokkbnqbl4i4y", + "time": 1679637204 + }, + { + "cid": "bafkreiecholb67ldemsvyr7js2x6dewjnsylvpk47ejyhrokkbnqbl4i4y", + "time": 1679637204 + }, + { + "cid": "bafkreih6jpxxvs5ruwhfms7t4kg3qv27x6cf4qn7rzoffcjhgctjjcn7my", + "time": 1679637252 + }, + { + "cid": "bafkreih6jpxxvs5ruwhfms7t4kg3qv27x6cf4qn7rzoffcjhgctjjcn7my", + "time": 1679637252 + }, + { + "cid": "bafkreih6jpxxvs5ruwhfms7t4kg3qv27x6cf4qn7rzoffcjhgctjjcn7my", + "time": 1679637288 + }, + { + "cid": "bafkreih6jpxxvs5ruwhfms7t4kg3qv27x6cf4qn7rzoffcjhgctjjcn7my", + "time": 1679637288 + } + ], + "validationError": false + }, + { + "dpid": "22", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreid4d4543faobctzfxh53tfa7u2q7jwqll7g3o52b6ko2vxbq6gya4", + "time": 1679658768 + }, + { + "cid": "bafkreid4d4543faobctzfxh53tfa7u2q7jwqll7g3o52b6ko2vxbq6gya4", + "time": 1679658768 + } + ], + "validationError": false + }, + { + "dpid": "23", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifzp4vuudwvek33rcft2rd2szjrimey7yezcsbm2awkx2tjsunwwi", + "time": 1680567024 + }, + { + "cid": "bafkreifzp4vuudwvek33rcft2rd2szjrimey7yezcsbm2awkx2tjsunwwi", + "time": 1680567024 + } + ], + "validationError": false + }, + { + "dpid": "24", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicqcgfswelv7jvt3o5mirsrwbegst354jzl5znfhsysfi5kwa5oem", + "time": 1681191960 + }, + { + "cid": "bafkreicqcgfswelv7jvt3o5mirsrwbegst354jzl5znfhsysfi5kwa5oem", + "time": 1681191960 + } + ], + "validationError": false + }, + { + "dpid": "25", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiai7ekqchod7c7na6bsc5aeicugtqr2ai4jhdyjal4ukzzjdoxdoi", + "time": 1681495752 + }, + { + "cid": "bafkreiai7ekqchod7c7na6bsc5aeicugtqr2ai4jhdyjal4ukzzjdoxdoi", + "time": 1681495752 + } + ], + "validationError": false + }, + { + "dpid": "26", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiasg744hrz2h6tkkw4a2z55orh33v5rs2j62mx3arsuqxa5dppyzq", + "time": 1681497684 + }, + { + "cid": "bafkreiasg744hrz2h6tkkw4a2z55orh33v5rs2j62mx3arsuqxa5dppyzq", + "time": 1681497684 + }, + { + "cid": "bafkreicbh5ytfk7ohfa7tw44q5nmjkzmqseiesoskwcjntwc6apx7ifyyi", + "time": 1681497900 + }, + { + "cid": "bafkreicbh5ytfk7ohfa7tw44q5nmjkzmqseiesoskwcjntwc6apx7ifyyi", + "time": 1681497900 + } + ], + "validationError": false + }, + { + "dpid": "27", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiehj4xqrpk5m6sdemt5nv6ktb5uxp6ihmg3apdwiu6xhkjzlcmuka", + "time": 1681505184 + }, + { + "cid": "bafkreiehj4xqrpk5m6sdemt5nv6ktb5uxp6ihmg3apdwiu6xhkjzlcmuka", + "time": 1681505184 + } + ], + "validationError": false + }, + { + "dpid": "28", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihmuuks36pyt5quuvjbxkhyu6lhdf3sfbqvfii6j2gemwpu2uc67q", + "time": 1681506588 + }, + { + "cid": "bafkreihmuuks36pyt5quuvjbxkhyu6lhdf3sfbqvfii6j2gemwpu2uc67q", + "time": 1681506588 + } + ], + "validationError": false + }, + { + "dpid": "29", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigifwmh35byvn2yzg2vojm6r6qpjyoce6dfdsacmch336adgqmyee", + "time": 1681736556 + }, + { + "cid": "bafkreigifwmh35byvn2yzg2vojm6r6qpjyoce6dfdsacmch336adgqmyee", + "time": 1681736556 + }, + { + "cid": "bafkreicxifdkouaya7pzrj2upqft2c637t6awklqjsbd76dfog42hxvlqu", + "time": 1681736628 + }, + { + "cid": "bafkreicxifdkouaya7pzrj2upqft2c637t6awklqjsbd76dfog42hxvlqu", + "time": 1681736628 + } + ], + "validationError": false + }, + { + "dpid": "30", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidtjqvqyoq7ehafmy7vvhjlewgtxkxaqr7anwtwtgkzvlogmfwaey", + "time": 1681761420 + }, + { + "cid": "bafkreidtjqvqyoq7ehafmy7vvhjlewgtxkxaqr7anwtwtgkzvlogmfwaey", + "time": 1681761420 + }, + { + "cid": "bafkreif6imae7ikphst6f2opahy2bn4qnm3srzj4rmnpdhrqtykwr6c4yu", + "time": 1681762272 + }, + { + "cid": "bafkreif6imae7ikphst6f2opahy2bn4qnm3srzj4rmnpdhrqtykwr6c4yu", + "time": 1681762272 + } + ], + "validationError": false + }, + { + "dpid": "31", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiahcqh7zzoz27gzh2chwto2u5kabmf2vmca3xbmzrlmgoqucrmfky", + "time": 1681805808 + }, + { + "cid": "bafkreiahcqh7zzoz27gzh2chwto2u5kabmf2vmca3xbmzrlmgoqucrmfky", + "time": 1681805808 + } + ], + "validationError": false + }, + { + "dpid": "32", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiaakpmpc5jr4bp3puzzpdjv5nh3maunzbaug2p335ngmdfsfekkxe", + "time": 1681830960 + }, + { + "cid": "bafkreiaakpmpc5jr4bp3puzzpdjv5nh3maunzbaug2p335ngmdfsfekkxe", + "time": 1681830960 + } + ], + "validationError": false + }, + { + "dpid": "33", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreic2zkjdknqf5kfelzzstfovdwuc2dolbaej7eduedn6md7rpfo27y", + "time": 1682014560 + }, + { + "cid": "bafkreic2zkjdknqf5kfelzzstfovdwuc2dolbaej7eduedn6md7rpfo27y", + "time": 1682014560 + } + ], + "validationError": false + }, + { + "dpid": "34", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibkbhhedb3yazc6rze6772ouoymv3yy5vqmilmwi6eq7yuw3n6tue", + "time": 1682144088 + }, + { + "cid": "bafkreibkbhhedb3yazc6rze6772ouoymv3yy5vqmilmwi6eq7yuw3n6tue", + "time": 1682144088 + } + ], + "validationError": false + }, + { + "dpid": "35", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreih4kylr5z5oppj6wprw2luiyngsn3xq324kfbiku4ehi42dess4oi", + "time": 1682534976 + }, + { + "cid": "bafkreih4kylr5z5oppj6wprw2luiyngsn3xq324kfbiku4ehi42dess4oi", + "time": 1682534976 + }, + { + "cid": "bafkreidasu577tdw76nprafzy7oa42nlr6gcyk45agx3tawrw3zyxu7mva", + "time": 1682746284 + }, + { + "cid": "bafkreidasu577tdw76nprafzy7oa42nlr6gcyk45agx3tawrw3zyxu7mva", + "time": 1682746284 + }, + { + "cid": "bafkreieaozkgywz6vonai3kmhr6cct5jjpeau3lhy2zrb2ft3dsnudaxym", + "time": 1682813004 + }, + { + "cid": "bafkreieaozkgywz6vonai3kmhr6cct5jjpeau3lhy2zrb2ft3dsnudaxym", + "time": 1682813004 + } + ], + "validationError": false + }, + { + "dpid": "36", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifc4so5xny7vpkj62oejlxlnh2zp6w76idbvx3mi2t5nkhxpbenbe", + "time": 1682670864 + }, + { + "cid": "bafkreifc4so5xny7vpkj62oejlxlnh2zp6w76idbvx3mi2t5nkhxpbenbe", + "time": 1682670864 + } + ], + "validationError": false + }, + { + "dpid": "37", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiadoa3b3hvlzpfliappjvhzoacqst2tnu5x7cjvhwcdjhplqakmmy", + "time": 1682793228 + }, + { + "cid": "bafkreiadoa3b3hvlzpfliappjvhzoacqst2tnu5x7cjvhwcdjhplqakmmy", + "time": 1682793228 + }, + { + "cid": "bafkreiad7vwyvhxpgy5i6azrynsnu5g2x5ef7iwjafbnnvukkbc7dvygru", + "time": 1682793408 + }, + { + "cid": "bafkreiad7vwyvhxpgy5i6azrynsnu5g2x5ef7iwjafbnnvukkbc7dvygru", + "time": 1682793408 + } + ], + "validationError": false + }, + { + "dpid": "38", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiagyoholq6ypx4pdby56vfzq7a44q3sn6esvho7wcf6m4eghpcjoa", + "time": 1682813880 + }, + { + "cid": "bafkreiagyoholq6ypx4pdby56vfzq7a44q3sn6esvho7wcf6m4eghpcjoa", + "time": 1682813880 + }, + { + "cid": "bafkreiapfszw7l5sysx2hgophrztwyeonpppem2xxwbujhhwa5kipypyky", + "time": 1682814000 + }, + { + "cid": "bafkreiapfszw7l5sysx2hgophrztwyeonpppem2xxwbujhhwa5kipypyky", + "time": 1682814000 + }, + { + "cid": "bafkreiapfszw7l5sysx2hgophrztwyeonpppem2xxwbujhhwa5kipypyky", + "time": 1682822136 + }, + { + "cid": "bafkreiapfszw7l5sysx2hgophrztwyeonpppem2xxwbujhhwa5kipypyky", + "time": 1682822136 + } + ], + "validationError": false + }, + { + "dpid": "39", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibtewpmyizn2rvgbd7yqzirfcunu264zqwjc6qmf32wwtocp57eta", + "time": 1682820372 + }, + { + "cid": "bafkreibtewpmyizn2rvgbd7yqzirfcunu264zqwjc6qmf32wwtocp57eta", + "time": 1682820372 + }, + { + "cid": "bafkreiayluo2hglsq2qfahpzwqopgwaad7bqxma5we6l2bqzs2zfvk6eka", + "time": 1682820648 + }, + { + "cid": "bafkreiayluo2hglsq2qfahpzwqopgwaad7bqxma5we6l2bqzs2zfvk6eka", + "time": 1682820648 + }, + { + "cid": "bafkreiayluo2hglsq2qfahpzwqopgwaad7bqxma5we6l2bqzs2zfvk6eka", + "time": 1682821080 + }, + { + "cid": "bafkreiayluo2hglsq2qfahpzwqopgwaad7bqxma5we6l2bqzs2zfvk6eka", + "time": 1682821080 + }, + { + "cid": "bafkreiero2ggetbv2g5voe4yg7lr53cl7aocrcdbn5ndz754ani2c4xwye", + "time": 1682849124 + }, + { + "cid": "bafkreiero2ggetbv2g5voe4yg7lr53cl7aocrcdbn5ndz754ani2c4xwye", + "time": 1682849124 + } + ], + "validationError": false + }, + { + "dpid": "40", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreih3uvxd3entelbnsrhijwkperswmy4d27cjvx2fnurjqqjzvp7v54", + "time": 1682821224 + }, + { + "cid": "bafkreih3uvxd3entelbnsrhijwkperswmy4d27cjvx2fnurjqqjzvp7v54", + "time": 1682821224 + }, + { + "cid": "bafkreih3uvxd3entelbnsrhijwkperswmy4d27cjvx2fnurjqqjzvp7v54", + "time": 1682821884 + }, + { + "cid": "bafkreih3uvxd3entelbnsrhijwkperswmy4d27cjvx2fnurjqqjzvp7v54", + "time": 1682821884 + } + ], + "validationError": false + }, + { + "dpid": "41", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihesv24wbwkhgjeplqi7lu2rm5d75o6es3krxbj4rfmhk3bcxavhe", + "time": 1682854224 + }, + { + "cid": "bafkreihesv24wbwkhgjeplqi7lu2rm5d75o6es3krxbj4rfmhk3bcxavhe", + "time": 1682854224 + }, + { + "cid": "bafkreifmd5ucm3ypfkph7klhghsgyvfinkrwxw6uuiwpdjoarmxotflwaa", + "time": 1682854344 + }, + { + "cid": "bafkreifmd5ucm3ypfkph7klhghsgyvfinkrwxw6uuiwpdjoarmxotflwaa", + "time": 1682854344 + } + ], + "validationError": false + }, + { + "dpid": "42", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreie46ed23xpsfgxasdbhzq4zrni5v4dv3lbohasnqkgmohq4g6bjam", + "time": 1682856480 + }, + { + "cid": "bafkreie46ed23xpsfgxasdbhzq4zrni5v4dv3lbohasnqkgmohq4g6bjam", + "time": 1682856480 + } + ], + "validationError": false + }, + { + "dpid": "43", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigumcdo4dafutywplrgg7xgo6swf2qygljyzwktsafuhvednvpmhy", + "time": 1682951112 + }, + { + "cid": "bafkreigumcdo4dafutywplrgg7xgo6swf2qygljyzwktsafuhvednvpmhy", + "time": 1682951112 + } + ], + "validationError": false + }, + { + "dpid": "44", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihqpbdqrgnp6mebwfcqqt3izgreiw4zgiw42zmkezipmktv777itu", + "time": 1682962248 + }, + { + "cid": "bafkreihqpbdqrgnp6mebwfcqqt3izgreiw4zgiw42zmkezipmktv777itu", + "time": 1682962248 + } + ], + "validationError": false + }, + { + "dpid": "45", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihfrfianmcigzvnnetxkzwlcgza75dsah7ab5anx43phu3mke3uky", + "time": 1682993892 + }, + { + "cid": "bafkreihfrfianmcigzvnnetxkzwlcgza75dsah7ab5anx43phu3mke3uky", + "time": 1682993892 + } + ], + "validationError": false + }, + { + "dpid": "46", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreia2nvcwknooiu6t6ywob4dhd6exb3aamogse4n7kkydybjaugdr6u", + "time": 1683053508 + }, + { + "cid": "bafkreia2nvcwknooiu6t6ywob4dhd6exb3aamogse4n7kkydybjaugdr6u", + "time": 1683053508 + }, + { + "cid": "bafkreih5koqw5nvxucidlihwfslknj674oeuroclit74rkaqpe4mq6xuka", + "time": 1683222132 + }, + { + "cid": "bafkreih5koqw5nvxucidlihwfslknj674oeuroclit74rkaqpe4mq6xuka", + "time": 1683222132 + }, + { + "cid": "bafkreif3d644utirvwvkmukcrhg64palp3r4xociwsn6b6o2hxmkdxalby", + "time": 1683227616 + }, + { + "cid": "bafkreif3d644utirvwvkmukcrhg64palp3r4xociwsn6b6o2hxmkdxalby", + "time": 1683227616 + }, + { + "cid": "bafkreibn3jhdlsdsonv25t7i2bwtrbkl3jzwjbnnwylpeih3jmmzdhsfmi", + "time": 1683298680 + }, + { + "cid": "bafkreibn3jhdlsdsonv25t7i2bwtrbkl3jzwjbnnwylpeih3jmmzdhsfmi", + "time": 1683298680 + }, + { + "cid": "bafkreiepot62powegf7tt73gyiz24facsdloywggattt2asz5y4eaqhkyi", + "time": 1683299940 + }, + { + "cid": "bafkreiepot62powegf7tt73gyiz24facsdloywggattt2asz5y4eaqhkyi", + "time": 1683299940 + }, + { + "cid": "bafkreihge5qw7sc3mqc4wkf4cgpv6udtvrgipfxwyph7dhlyu6bkkt7tfq", + "time": 1705420740 + }, + { + "cid": "bafkreihge5qw7sc3mqc4wkf4cgpv6udtvrgipfxwyph7dhlyu6bkkt7tfq", + "time": 1705420740 + } + ], + "validationError": false + }, + { + "dpid": "47", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreia7orsrr4pwxe5m2gnklknpc25kjs7gnzemofki3aeh6ydh4hkfju", + "time": 1683222948 + }, + { + "cid": "bafkreia7orsrr4pwxe5m2gnklknpc25kjs7gnzemofki3aeh6ydh4hkfju", + "time": 1683222948 + } + ], + "validationError": false + }, + { + "dpid": "48", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreieahbi5tzb2od7nb2j5up4ooiglvh2lty2bgcrwjc3km7fnsplaxu", + "time": 1683232692 + }, + { + "cid": "bafkreieahbi5tzb2od7nb2j5up4ooiglvh2lty2bgcrwjc3km7fnsplaxu", + "time": 1683232692 + } + ], + "validationError": false + }, + { + "dpid": "49", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiet6onaozwmqyflpbjsa7f6f5jkhou5n3vxxkxmkgalhnr54bzftu", + "time": 1683236460 + }, + { + "cid": "bafkreiet6onaozwmqyflpbjsa7f6f5jkhou5n3vxxkxmkgalhnr54bzftu", + "time": 1683236460 + }, + { + "cid": "bafkreibp3hplo3b2hfetbrargv2gv2dkx3kfqfsqbxhkuved2k2nebxcpa", + "time": 1683236760 + }, + { + "cid": "bafkreibp3hplo3b2hfetbrargv2gv2dkx3kfqfsqbxhkuved2k2nebxcpa", + "time": 1683236760 + }, + { + "cid": "bafkreigym3lzf2ruzd3r23mflxjzafqfxoi5bncru3t4ky35vfaubbke34", + "time": 1683236760 + }, + { + "cid": "bafkreigym3lzf2ruzd3r23mflxjzafqfxoi5bncru3t4ky35vfaubbke34", + "time": 1683236760 + }, + { + "cid": "bafkreife4uk2mkecur54sq774ybtrka5l4gd5777j5cjjscfmx4vcqnfbm", + "time": 1683237288 + }, + { + "cid": "bafkreife4uk2mkecur54sq774ybtrka5l4gd5777j5cjjscfmx4vcqnfbm", + "time": 1683237288 + } + ], + "validationError": false + }, + { + "dpid": "50", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibroag6m5tps4srrtdxbfq74sskvpfu4sbhadhkh3vfonjrlmsvda", + "time": 1683886968 + }, + { + "cid": "bafkreibroag6m5tps4srrtdxbfq74sskvpfu4sbhadhkh3vfonjrlmsvda", + "time": 1683886968 + } + ], + "validationError": false + }, + { + "dpid": "51", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiheezwrynuxo6gnjd2pmahkcw3wstooxs6fvaflpjouewmh4qi3aa", + "time": 1683930000 + }, + { + "cid": "bafkreiheezwrynuxo6gnjd2pmahkcw3wstooxs6fvaflpjouewmh4qi3aa", + "time": 1683930000 + }, + { + "cid": "bafkreiasjo5wzkkk2s56tvdkmbe56vj4j7gyq345vnqpwvnvwozzhtkxfq", + "time": 1683931428 + }, + { + "cid": "bafkreiasjo5wzkkk2s56tvdkmbe56vj4j7gyq345vnqpwvnvwozzhtkxfq", + "time": 1683931428 + } + ], + "validationError": false + }, + { + "dpid": "52", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicxw5tzwajvwa757ihut3hvlgnfbpu7fa4oxfvvlssu4rikfrtmv4", + "time": 1684412244 + }, + { + "cid": "bafkreicxw5tzwajvwa757ihut3hvlgnfbpu7fa4oxfvvlssu4rikfrtmv4", + "time": 1684412244 + } + ], + "validationError": false + }, + { + "dpid": "53", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreia7yjdhq6tdxjtwyr4ajfhxypq3jxbo5augryzzeos7cqrbyy6jmi", + "time": 1684862784 + }, + { + "cid": "bafkreia7yjdhq6tdxjtwyr4ajfhxypq3jxbo5augryzzeos7cqrbyy6jmi", + "time": 1684862784 + }, + { + "cid": "bafkreifutouvscu3pbsaabgxdxqfd6zaphkcuei6i3fibdeefmrh4oujby", + "time": 1686612108 + }, + { + "cid": "bafkreifutouvscu3pbsaabgxdxqfd6zaphkcuei6i3fibdeefmrh4oujby", + "time": 1686612108 + } + ], + "validationError": false + }, + { + "dpid": "54", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigtfrsogce5ixgj4dvjgvj2qgjsujs5g4sa64svziiyz6j2bajise", + "time": 1685098464 + }, + { + "cid": "bafkreigtfrsogce5ixgj4dvjgvj2qgjsujs5g4sa64svziiyz6j2bajise", + "time": 1685098464 + }, + { + "cid": "bafkreihocw2lexz7nz4sfwmy576guhbecxnzq4wfltnx5twqn2clng3ewu", + "time": 1685098776 + }, + { + "cid": "bafkreihocw2lexz7nz4sfwmy576guhbecxnzq4wfltnx5twqn2clng3ewu", + "time": 1685098776 + } + ], + "validationError": false + }, + { + "dpid": "55", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicup2qewrwovkkgk5bun4vpws7cbq3qnv2rbt7truyw54owvtwovm", + "time": 1685442360 + }, + { + "cid": "bafkreicup2qewrwovkkgk5bun4vpws7cbq3qnv2rbt7truyw54owvtwovm", + "time": 1685442360 + } + ], + "validationError": false + }, + { + "dpid": "56", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreieis5ac2evezkciy26fvswybmyyarfnrlvyh7p5acvbhcsceayorq", + "time": 1685444172 + }, + { + "cid": "bafkreieis5ac2evezkciy26fvswybmyyarfnrlvyh7p5acvbhcsceayorq", + "time": 1685444172 + }, + { + "cid": "bafkreid6ibvbiblu6vviuc3l6ivmpmpdbj2rzt625capmi4igns2r7k4ue", + "time": 1685448060 + }, + { + "cid": "bafkreid6ibvbiblu6vviuc3l6ivmpmpdbj2rzt625capmi4igns2r7k4ue", + "time": 1685448060 + } + ], + "validationError": false + }, + { + "dpid": "57", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiaulqrzufg3qnw55rwzqtn5h2cvsawdunrfwt4j32ywt6oswi5bfm", + "time": 1685525952 + }, + { + "cid": "bafkreiaulqrzufg3qnw55rwzqtn5h2cvsawdunrfwt4j32ywt6oswi5bfm", + "time": 1685525952 + } + ], + "validationError": false + }, + { + "dpid": "58", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidlxqbem5m3kgtntq6243vujhuyvt2s72ry2k5uy4f6hmjwbezdje", + "time": 1685526132 + }, + { + "cid": "bafkreidlxqbem5m3kgtntq6243vujhuyvt2s72ry2k5uy4f6hmjwbezdje", + "time": 1685526132 + }, + { + "cid": "bafkreib2gln7ztcpt6z7q7yo6isznl6lam4zv74hwslwhplh6g55re26lm", + "time": 1685536224 + }, + { + "cid": "bafkreib2gln7ztcpt6z7q7yo6isznl6lam4zv74hwslwhplh6g55re26lm", + "time": 1685536224 + } + ], + "validationError": false + }, + { + "dpid": "59", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigj2svt7njv2nxznzm42pisbjgpfjzhoorlcsryjlx5coa2klssku", + "time": 1685613060 + }, + { + "cid": "bafkreigvuao6ogwtnr2oknvxl3a5mtulhats7dqsiuturbxnnablevorai", + "time": 1685613240 + }, + { + "cid": "bafkreigvuao6ogwtnr2oknvxl3a5mtulhats7dqsiuturbxnnablevorai", + "time": 1685613240 + } + ], + "validationError": false + }, + { + "dpid": "60", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiefsjhlwr6bcq4nscdoz2q2tkca5i7ocxgtn5nxggkf2lr5a2z2lq", + "time": 1685613216 + }, + { + "cid": "bafkreifmohd57nd6xbcjrc3b6dxgpycgijleopks7hrmza4t23dvqxd2au", + "time": 1685613708 + } + ], + "validationError": false + }, + { + "dpid": "61", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreid5vwbe6ri74rgtdevbjznreexoedsocftjqgpopx3bih656jwzni", + "time": 1685614104 + }, + { + "cid": "bafkreid5vwbe6ri74rgtdevbjznreexoedsocftjqgpopx3bih656jwzni", + "time": 1685614104 + } + ], + "validationError": false + }, + { + "dpid": "62", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiapjbbsrowag6txt3wuilla2vp6dhhijkylklmvdzc4es3qb27buq", + "time": 1685615388 + }, + { + "cid": "bafkreiapjbbsrowag6txt3wuilla2vp6dhhijkylklmvdzc4es3qb27buq", + "time": 1685615388 + } + ], + "validationError": false + }, + { + "dpid": "63", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicjmhgi5sbjvo2i3nzwfkwfmahgipbyq6iasekibgqpl75cdiqdsi", + "time": 1685615724 + } + ], + "validationError": false + }, + { + "dpid": "64", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreib2rkswbatx7qqcnymxcajqrgrywfzlsiischsrfowhbd5vjfskfi", + "time": 1685719428 + } + ], + "validationError": false + }, + { + "dpid": "65", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifdylfaiep4lc4544mow5aiq4vg37buebiybfx5wyznfi4pov6qri", + "time": 1686220584 + } + ], + "validationError": false + }, + { + "dpid": "66", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibelil5fgqul2o3chxv7g7xmdqkv2krqkv6r6mdbiw72vcqp4wxky", + "time": 1687805292 + }, + { + "cid": "bafkreiefvtk6gcvlxq3hw3lkxcjjy5aqkaxyu4swucs2wd3imjhi2yfdpm", + "time": 1687805484 + } + ], + "validationError": false + }, + { + "dpid": "67", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiazlufpwemnsbzscuycou7gi5m7t2p4yxbxvozkvxex47uczuokba", + "time": 1687807524 + }, + { + "cid": "bafkreiazlufpwemnsbzscuycou7gi5m7t2p4yxbxvozkvxex47uczuokba", + "time": 1687807524 + }, + { + "cid": "bafkreidupix2c3fizisuv2z6tluypvssf6solprgnmev6ul6vp6dprwop4", + "time": 1687808232 + }, + { + "cid": "bafkreidupix2c3fizisuv2z6tluypvssf6solprgnmev6ul6vp6dprwop4", + "time": 1687808232 + } + ], + "validationError": false + }, + { + "dpid": "68", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihakt3w53hwvneg2o3e4xysgegwk5j5rs6mug6ywlwb2bmprm4wzy", + "time": 1687812132 + }, + { + "cid": "bafkreihakt3w53hwvneg2o3e4xysgegwk5j5rs6mug6ywlwb2bmprm4wzy", + "time": 1687812132 + } + ], + "validationError": false + }, + { + "dpid": "69", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigfelcudmytsq2s2j4wcy3j7tsyatpnffpcthf6zz7q5wa4snafdm", + "time": 1687812804 + }, + { + "cid": "bafkreigfelcudmytsq2s2j4wcy3j7tsyatpnffpcthf6zz7q5wa4snafdm", + "time": 1687812804 + } + ], + "validationError": false + }, + { + "dpid": "70", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicandi5eh3gwuxwlq6k6fpeuurnbpbx33q3ijndg44go2p5ekni3y", + "time": 1687817568 + }, + { + "cid": "bafkreicandi5eh3gwuxwlq6k6fpeuurnbpbx33q3ijndg44go2p5ekni3y", + "time": 1687817568 + } + ], + "validationError": false + }, + { + "dpid": "71", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibb5g5ujmxeve56ktnuolb7rrncmbgedtrjemeshn6rxbrhn4uepe", + "time": 1688024628 + }, + { + "cid": "bafkreibb5g5ujmxeve56ktnuolb7rrncmbgedtrjemeshn6rxbrhn4uepe", + "time": 1688024628 + }, + { + "cid": "bafkreiddtartrk6isrs3j5ltx6nkcv437jsu62vc6ew3cwvxk3msebzg5e", + "time": 1688024676 + }, + { + "cid": "bafkreiddtartrk6isrs3j5ltx6nkcv437jsu62vc6ew3cwvxk3msebzg5e", + "time": 1688024676 + } + ], + "validationError": false + }, + { + "dpid": "72", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicj4c44gghcoy2ztvwe32fmbv7cuvty2hv2y4ndrnd6ghrl3ciaea", + "time": 1688552688 + }, + { + "cid": "bafkreicj4c44gghcoy2ztvwe32fmbv7cuvty2hv2y4ndrnd6ghrl3ciaea", + "time": 1688552688 + } + ], + "validationError": false + }, + { + "dpid": "73", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifdgjfu3g4qddc7g5kvnk3lshkuyfau7o2qle5ut5msptulbxsqme", + "time": 1688720808 + }, + { + "cid": "bafkreifdgjfu3g4qddc7g5kvnk3lshkuyfau7o2qle5ut5msptulbxsqme", + "time": 1688720808 + }, + { + "cid": "bafkreifdgjfu3g4qddc7g5kvnk3lshkuyfau7o2qle5ut5msptulbxsqme", + "time": 1689009768 + }, + { + "cid": "bafkreifdgjfu3g4qddc7g5kvnk3lshkuyfau7o2qle5ut5msptulbxsqme", + "time": 1689009768 + } + ], + "validationError": false + }, + { + "dpid": "74", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifqxkjzypbtz7snjp3ghjrv56bd5umihchpwfppnoz67tcmhuq7wi", + "time": 1689041640 + }, + { + "cid": "bafkreifqxkjzypbtz7snjp3ghjrv56bd5umihchpwfppnoz67tcmhuq7wi", + "time": 1689041640 + } + ], + "validationError": false + }, + { + "dpid": "75", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibtsll3aq2bynvlxnqh6nxafzdm4cpiovr3bcncbkzjcy32xalp7i", + "time": 1689294216 + }, + { + "cid": "bafkreibtsll3aq2bynvlxnqh6nxafzdm4cpiovr3bcncbkzjcy32xalp7i", + "time": 1689294216 + } + ], + "validationError": false + }, + { + "dpid": "76", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiatjdpouudloenzdzb7d3e5pogruvwbhurcnm2g5h64jmkpk2uebe", + "time": 1689518988 + }, + { + "cid": "bafkreiatjdpouudloenzdzb7d3e5pogruvwbhurcnm2g5h64jmkpk2uebe", + "time": 1689518988 + }, + { + "cid": "bafkreigg3xk6ojueylnninvwsrw62nqpt7pyjnz6thaipbydb5ltclctly", + "time": 1692182952 + }, + { + "cid": "bafkreigg3xk6ojueylnninvwsrw62nqpt7pyjnz6thaipbydb5ltclctly", + "time": 1692182952 + }, + { + "cid": "bafkreicrggm7jpxgaj2vgydvefuravrs2bh4emlt6eadx3zsbubtpulmcq", + "time": 1692330000 + }, + { + "cid": "bafkreicrggm7jpxgaj2vgydvefuravrs2bh4emlt6eadx3zsbubtpulmcq", + "time": 1692330000 + }, + { + "cid": "bafkreifgfzjltrvcz3qixyjkiubgms2r3figm37euwxzbi6pvej2me6tje", + "time": 1701997248 + }, + { + "cid": "bafkreifgfzjltrvcz3qixyjkiubgms2r3figm37euwxzbi6pvej2me6tje", + "time": 1701997248 + }, + { + "cid": "bafkreic4wiuatha4wclfbwft4vaeeqifrbb2f3tqm4eoajommogudbvswu", + "time": 1702000140 + }, + { + "cid": "bafkreic4wiuatha4wclfbwft4vaeeqifrbb2f3tqm4eoajommogudbvswu", + "time": 1702000140 + }, + { + "cid": "bafkreicraffpobz3k5rzdmigl5tzklihwuim4kwe7xl5uulmfrkr4uvm2u", + "time": 1702045680 + }, + { + "cid": "bafkreicraffpobz3k5rzdmigl5tzklihwuim4kwe7xl5uulmfrkr4uvm2u", + "time": 1702045680 + }, + { + "cid": "bafkreidtkraxowlx26oz5g6qyfuawhx5nroil4a4mo6ywa7knfel7ft2dq", + "time": 1702045944 + }, + { + "cid": "bafkreidtkraxowlx26oz5g6qyfuawhx5nroil4a4mo6ywa7knfel7ft2dq", + "time": 1702045944 + } + ], + "validationError": false + }, + { + "dpid": "77", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiaqxrcrai2j2lpk2moare5abq4vtyhxk6m5jxo5fbqkrsy24kdm7q", + "time": 1691492520 + }, + { + "cid": "bafkreiaqxrcrai2j2lpk2moare5abq4vtyhxk6m5jxo5fbqkrsy24kdm7q", + "time": 1691492520 + }, + { + "cid": "bafkreihjozked2lgpgtdcuvzejanhnm65sccwglgblxfdg3cwi72vlrtvq", + "time": 1691493636 + }, + { + "cid": "bafkreihjozked2lgpgtdcuvzejanhnm65sccwglgblxfdg3cwi72vlrtvq", + "time": 1691493636 + }, + { + "cid": "bafkreieodz3e4kzbnlg4nka5pwrgafwuuemfuejxqa5dpdaqlgt6bjs7fm", + "time": 1691496348 + }, + { + "cid": "bafkreieodz3e4kzbnlg4nka5pwrgafwuuemfuejxqa5dpdaqlgt6bjs7fm", + "time": 1691496348 + } + ], + "validationError": false + }, + { + "dpid": "78", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifixmk6tierh6qompfouk63r6clg5jbeuvwherrxacq4uoedk4o5q", + "time": 1691501736 + }, + { + "cid": "bafkreifixmk6tierh6qompfouk63r6clg5jbeuvwherrxacq4uoedk4o5q", + "time": 1691501736 + } + ], + "validationError": false + }, + { + "dpid": "79", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibtuuiejhyxu4zr2od34biucedhlmqdmqem6v2ruqu6ov2kgsfnfa", + "time": 1692472464 + }, + { + "cid": "bafkreibtuuiejhyxu4zr2od34biucedhlmqdmqem6v2ruqu6ov2kgsfnfa", + "time": 1692472464 + } + ], + "validationError": false + }, + { + "dpid": "80", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiawwe6os5lxye3hojdmwgcdt4nrs7xwfqy3p3vuv7xolhbnc2nqaq", + "time": 1693245804 + }, + { + "cid": "bafkreiawwe6os5lxye3hojdmwgcdt4nrs7xwfqy3p3vuv7xolhbnc2nqaq", + "time": 1693245804 + }, + { + "cid": "bafkreichlzplxpphzyoo3mnjg6tm2e4uplpm4d2q667a6dbz6xhctvktai", + "time": 1693246872 + }, + { + "cid": "bafkreichlzplxpphzyoo3mnjg6tm2e4uplpm4d2q667a6dbz6xhctvktai", + "time": 1693246872 + } + ], + "validationError": false + }, + { + "dpid": "81", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreieefydw5dajtfgz5xqecgyyqxt7kzzyibihy4dvnrtwakaahkn34y", + "time": 1693246440 + }, + { + "cid": "bafkreieefydw5dajtfgz5xqecgyyqxt7kzzyibihy4dvnrtwakaahkn34y", + "time": 1693246440 + }, + { + "cid": "bafkreicpdjfhoxg3gyc2xn63ppbxf7a7wvehkl4h34dapqeqekfetwunme", + "time": 1700147784 + }, + { + "cid": "bafkreicpdjfhoxg3gyc2xn63ppbxf7a7wvehkl4h34dapqeqekfetwunme", + "time": 1700147784 + } + ], + "validationError": false + }, + { + "dpid": "82", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicmvrritjqe4eatfkix3k6kgxz7oxlxengyfhg7rkubpagmxymiqa", + "time": 1693247148 + }, + { + "cid": "bafkreicmvrritjqe4eatfkix3k6kgxz7oxlxengyfhg7rkubpagmxymiqa", + "time": 1693247148 + } + ], + "validationError": false + }, + { + "dpid": "83", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreia6ccnzt76b23xkq7slvzxgebltmlkmvcbvr77nzfyca7wpq6qkru", + "time": 1693247616 + }, + { + "cid": "bafkreia6ccnzt76b23xkq7slvzxgebltmlkmvcbvr77nzfyca7wpq6qkru", + "time": 1693247616 + }, + { + "cid": "bafkreidrb3cry4mh6fcik54rotatfnz2mapg3olcsxqpodgdbecrh5iu54", + "time": 1700147268 + }, + { + "cid": "bafkreidrb3cry4mh6fcik54rotatfnz2mapg3olcsxqpodgdbecrh5iu54", + "time": 1700147268 + } + ], + "validationError": false + }, + { + "dpid": "84", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibgfpmyizfiu6mpmdcn6aqvqrli72za72ccrxsim24nhtfv3cqb7m", + "time": 1693248192 + }, + { + "cid": "bafkreibgfpmyizfiu6mpmdcn6aqvqrli72za72ccrxsim24nhtfv3cqb7m", + "time": 1693248192 + }, + { + "cid": "bafkreidfksyvtp5vjzoczjupn6h6h72dcr2p2rm63l7l5qwn6sq6d2nyjy", + "time": 1700146980 + }, + { + "cid": "bafkreidfksyvtp5vjzoczjupn6h6h72dcr2p2rm63l7l5qwn6sq6d2nyjy", + "time": 1700146980 + } + ], + "validationError": false + }, + { + "dpid": "85", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreichgcyenem343rn3cgpyymyicdgoe7vgkev7z7bccskncaux7rxt4", + "time": 1693248672 + }, + { + "cid": "bafkreichgcyenem343rn3cgpyymyicdgoe7vgkev7z7bccskncaux7rxt4", + "time": 1693248672 + }, + { + "cid": "bafkreiejwrzg3vtvrvxm75dzgmk3736v4wrhl6uin64hzq76oekbkqi2ci", + "time": 1700146392 + }, + { + "cid": "bafkreiejwrzg3vtvrvxm75dzgmk3736v4wrhl6uin64hzq76oekbkqi2ci", + "time": 1700146392 + } + ], + "validationError": false + }, + { + "dpid": "86", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihxqrtbvhxg3w2nu3ahpcu2it6qvnmca4xb72vq4w27er3v4rsjgi", + "time": 1693249560 + }, + { + "cid": "bafkreihxqrtbvhxg3w2nu3ahpcu2it6qvnmca4xb72vq4w27er3v4rsjgi", + "time": 1693249560 + }, + { + "cid": "bafkreidlqc6jfns3ftpxoopx7etmfqp75xwoptd6es36xir2fl4nkvmx6i", + "time": 1700145552 + }, + { + "cid": "bafkreidlqc6jfns3ftpxoopx7etmfqp75xwoptd6es36xir2fl4nkvmx6i", + "time": 1700145552 + } + ], + "validationError": false + }, + { + "dpid": "87", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidlb227q7gvv622itmewvsdli726msbjgtsoufaepsaajrc66d27u", + "time": 1693249908 + }, + { + "cid": "bafkreidlb227q7gvv622itmewvsdli726msbjgtsoufaepsaajrc66d27u", + "time": 1693249908 + }, + { + "cid": "bafkreibaiviks6ed4yuwaidz4zzerlhmlkbdcxucky74ah4nu37cm443lm", + "time": 1700146176 + }, + { + "cid": "bafkreibaiviks6ed4yuwaidz4zzerlhmlkbdcxucky74ah4nu37cm443lm", + "time": 1700146176 + } + ], + "validationError": false + }, + { + "dpid": "88", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibdpyr6vlsifgi3cebv7ip26ynplllfzpekxz4zfj7xna7uolpjgy", + "time": 1693250244 + }, + { + "cid": "bafkreibdpyr6vlsifgi3cebv7ip26ynplllfzpekxz4zfj7xna7uolpjgy", + "time": 1693250244 + }, + { + "cid": "bafkreif7e3nkqyrpa6pkhlnv7sdrwkgyct7fhgzqsteo457kpa46wuflhe", + "time": 1700146776 + }, + { + "cid": "bafkreif7e3nkqyrpa6pkhlnv7sdrwkgyct7fhgzqsteo457kpa46wuflhe", + "time": 1700146776 + } + ], + "validationError": false + }, + { + "dpid": "89", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidp3ed42l6cizgero5c7zfmxpmwp5hkc4tx6uz7mgioxsep4wb6rm", + "time": 1693251900 + }, + { + "cid": "bafkreidp3ed42l6cizgero5c7zfmxpmwp5hkc4tx6uz7mgioxsep4wb6rm", + "time": 1693251900 + } + ], + "validationError": false + }, + { + "dpid": "90", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiaw34rnu36p2ccawj3gopyxgl64qj3dc3ip3pzvfh5anzrvmu4z5u", + "time": 1694114940 + }, + { + "cid": "bafkreiaw34rnu36p2ccawj3gopyxgl64qj3dc3ip3pzvfh5anzrvmu4z5u", + "time": 1694114940 + }, + { + "cid": "bafkreidk7ihar3swjjf46wtttjl52govxa256725urm5upcefu4wfvnxpm", + "time": 1694187648 + }, + { + "cid": "bafkreidk7ihar3swjjf46wtttjl52govxa256725urm5upcefu4wfvnxpm", + "time": 1694187648 + }, + { + "cid": "bafkreic6n2x6jlvss4iepnkkb4o4wre4nezbbff7kw46mz2egtzxast5xe", + "time": 1695653376 + }, + { + "cid": "bafkreic6n2x6jlvss4iepnkkb4o4wre4nezbbff7kw46mz2egtzxast5xe", + "time": 1695653376 + } + ], + "validationError": false + }, + { + "dpid": "91", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigpcnierfxljhffgj4d6oyuwec4pcbkbjys6goaggw75rcobd6vnu", + "time": 1694197140 + }, + { + "cid": "bafkreigpcnierfxljhffgj4d6oyuwec4pcbkbjys6goaggw75rcobd6vnu", + "time": 1694197140 + }, + { + "cid": "bafkreidtiuwpwyewgjp3r5a7shvzgir7pvbeguxlv6zebpdbxrraialhxu", + "time": 1695653220 + }, + { + "cid": "bafkreidtiuwpwyewgjp3r5a7shvzgir7pvbeguxlv6zebpdbxrraialhxu", + "time": 1695653220 + } + ], + "validationError": false + }, + { + "dpid": "92", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicqezpklsjtuszjnsekc2dcyadgtbcfouhlc57vclrwco45gzbul4", + "time": 1695218412 + }, + { + "cid": "bafkreicqezpklsjtuszjnsekc2dcyadgtbcfouhlc57vclrwco45gzbul4", + "time": 1695218412 + } + ], + "validationError": false + }, + { + "dpid": "93", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreie2p56t2d3i762v3bow3jweile6fmryt2qlcjq3cmkz7kpqtaic2a", + "time": 1695246144 + }, + { + "cid": "bafkreie2p56t2d3i762v3bow3jweile6fmryt2qlcjq3cmkz7kpqtaic2a", + "time": 1695246144 + } + ], + "validationError": false + }, + { + "dpid": "94", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiaqnt5raa6b4ujpkgd4veg73rtp5csn6fwxrckbhq4mkrl7ws63dy", + "time": 1695246324 + }, + { + "cid": "bafkreiaqnt5raa6b4ujpkgd4veg73rtp5csn6fwxrckbhq4mkrl7ws63dy", + "time": 1695246324 + } + ], + "validationError": false + }, + { + "dpid": "95", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreied6xbi65zwpzqiiaqnhq3cdq42c7yqrx6sd32ncv6avkovcb6f6y", + "time": 1695324696 + }, + { + "cid": "bafkreied6xbi65zwpzqiiaqnhq3cdq42c7yqrx6sd32ncv6avkovcb6f6y", + "time": 1695324696 + } + ], + "validationError": false + }, + { + "dpid": "96", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigurq54verb4sihjuonnx2pbo77lbjlviol2jfjxxgyzzko7o42ka", + "time": 1695816576 + }, + { + "cid": "bafkreigurq54verb4sihjuonnx2pbo77lbjlviol2jfjxxgyzzko7o42ka", + "time": 1695816576 + } + ], + "validationError": false + }, + { + "dpid": "97", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreig76u6of7za2h5pdphz2ztsl5xdsgg2vrsh2dximjx3q2aszfjq6m", + "time": 1696295376 + }, + { + "cid": "bafkreig76u6of7za2h5pdphz2ztsl5xdsgg2vrsh2dximjx3q2aszfjq6m", + "time": 1696295376 + }, + { + "cid": "bafkreig76u6of7za2h5pdphz2ztsl5xdsgg2vrsh2dximjx3q2aszfjq6m", + "time": 1696296012 + }, + { + "cid": "bafkreig76u6of7za2h5pdphz2ztsl5xdsgg2vrsh2dximjx3q2aszfjq6m", + "time": 1696296012 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696299000 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696299000 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696299600 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696299600 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696299876 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696299876 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696299912 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696299912 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696299996 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696299996 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696440036 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696440036 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696440996 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696440996 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696459560 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696459560 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696459584 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696459584 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696466724 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696466724 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696466820 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696466820 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696466964 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696466964 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696468416 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696468416 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696479552 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696479552 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696480608 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696480608 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696480764 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696480764 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696480884 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696480884 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696481172 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696481172 + }, + { + "cid": "bafkreiciddswj3e6ho5of7x7a7liaqehnwqeg35w3cp3l5knv6k2tdlswa", + "time": 1696594740 + }, + { + "cid": "bafkreiciddswj3e6ho5of7x7a7liaqehnwqeg35w3cp3l5knv6k2tdlswa", + "time": 1696594740 + } + ], + "validationError": false + }, + { + "dpid": "98", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicsn4qia64pf7eim7sjggvmnggqadmfmrrcm5gecbpfdzxwzlk7i4", + "time": 1696303560 + }, + { + "cid": "bafkreicsn4qia64pf7eim7sjggvmnggqadmfmrrcm5gecbpfdzxwzlk7i4", + "time": 1696303944 + }, + { + "cid": "bafkreicsn4qia64pf7eim7sjggvmnggqadmfmrrcm5gecbpfdzxwzlk7i4", + "time": 1696303944 + } + ], + "validationError": false + }, + { + "dpid": "99", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696336296 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696336296 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696469268 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696469268 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536756 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536756 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536804 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536828 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536888 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536912 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536912 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536936 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536936 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536972 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536972 + } + ], + "validationError": false + }, + { + "dpid": "100", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreib2fs7g7yawpqeyjzatsv3bip5p6xr27pnblzjase3zyr4ixtbu6a", + "time": 1696506528 + }, + { + "cid": "bafkreib2fs7g7yawpqeyjzatsv3bip5p6xr27pnblzjase3zyr4ixtbu6a", + "time": 1696506528 + }, + { + "cid": "bafkreihirj6fsasmvqmzngnyqitl6fpt3ljapgwx7dpfelgvruqsu7smw4", + "time": 1696507296 + }, + { + "cid": "bafkreihirj6fsasmvqmzngnyqitl6fpt3ljapgwx7dpfelgvruqsu7smw4", + "time": 1696507296 + }, + { + "cid": "bafkreid5osij2amlc67sm7uzqp22j7y3dn6lseyuy72oh64z5rqoh5qity", + "time": 1696840824 + }, + { + "cid": "bafkreid5osij2amlc67sm7uzqp22j7y3dn6lseyuy72oh64z5rqoh5qity", + "time": 1696840824 + } + ], + "validationError": false + }, + { + "dpid": "101", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiaoby2dmz4sljyhxsizjj2yd2jvbzz2vsywii3vp6xqi4rjefxl4q", + "time": 1696589760 + }, + { + "cid": "bafkreiaoby2dmz4sljyhxsizjj2yd2jvbzz2vsywii3vp6xqi4rjefxl4q", + "time": 1696589760 + } + ], + "validationError": false + }, + { + "dpid": "102", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiceiefmvnwozgtpvvwv5exwsdxm36yl5ovunmcnjx5kjtcqvm6lwe", + "time": 1696605300 + }, + { + "cid": "bafkreiceiefmvnwozgtpvvwv5exwsdxm36yl5ovunmcnjx5kjtcqvm6lwe", + "time": 1696605300 + } + ], + "validationError": false + }, + { + "dpid": "103", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreif6p22atw6ekbaxkrnfmetfdqtnhldaqw6qtqiqc7lqbus6aizru4", + "time": 1696841976 + }, + { + "cid": "bafkreif6p22atw6ekbaxkrnfmetfdqtnhldaqw6qtqiqc7lqbus6aizru4", + "time": 1696841976 + } + ], + "validationError": false + }, + { + "dpid": "104", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiautwruptenrd4xbq5actpbmirrxprmnnxyxf37ixblmcynebjaqq", + "time": 1696842144 + }, + { + "cid": "bafkreiautwruptenrd4xbq5actpbmirrxprmnnxyxf37ixblmcynebjaqq", + "time": 1696842144 + }, + { + "cid": "bafkreie37zoipwpgqrupcmxfnhqfqpztumhcurzb27rfasa5ipao32w3ia", + "time": 1697792352 + }, + { + "cid": "bafkreie37zoipwpgqrupcmxfnhqfqpztumhcurzb27rfasa5ipao32w3ia", + "time": 1697792352 + }, + { + "cid": "bafkreiebcm7batu7zyp4aw6pzisbkldtlqsghh5jhczhkh63lxgjxp5wte", + "time": 1698779592 + }, + { + "cid": "bafkreiebcm7batu7zyp4aw6pzisbkldtlqsghh5jhczhkh63lxgjxp5wte", + "time": 1698779592 + } + ], + "validationError": false + }, + { + "dpid": "105", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreig33qp67gaov32ibvtb5gqtcnfrntrsrbzst2lcgrgnkbu4hbtcj4", + "time": 1696842444 + }, + { + "cid": "bafkreig33qp67gaov32ibvtb5gqtcnfrntrsrbzst2lcgrgnkbu4hbtcj4", + "time": 1696842444 + }, + { + "cid": "bafkreig33qp67gaov32ibvtb5gqtcnfrntrsrbzst2lcgrgnkbu4hbtcj4", + "time": 1698911760 + }, + { + "cid": "bafkreig33qp67gaov32ibvtb5gqtcnfrntrsrbzst2lcgrgnkbu4hbtcj4", + "time": 1698911760 + } + ], + "validationError": false + }, + { + "dpid": "106", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibbbm7623bsdoftewbedqd3peny6zhqpt6tjgx67ouf6hhvbv2idi", + "time": 1696941732 + }, + { + "cid": "bafkreibbbm7623bsdoftewbedqd3peny6zhqpt6tjgx67ouf6hhvbv2idi", + "time": 1696941732 + }, + { + "cid": "bafkreihemsbpld4yuzrn4ckrlriyq5ortlkycxx74ayfugnoce7oetsmam", + "time": 1696942104 + }, + { + "cid": "bafkreihemsbpld4yuzrn4ckrlriyq5ortlkycxx74ayfugnoce7oetsmam", + "time": 1696942104 + }, + { + "cid": "bafkreic4gpc3k5mrttk57w6k5fvtgvubvh6xfwgmubecx53b55xsxoavxe", + "time": 1696944228 + }, + { + "cid": "bafkreic4gpc3k5mrttk57w6k5fvtgvubvh6xfwgmubecx53b55xsxoavxe", + "time": 1696944228 + }, + { + "cid": "bafkreickteh2tt3oy43o42ikwei6tppghmtbkockk22a3niovi57ugor7q", + "time": 1696961232 + }, + { + "cid": "bafkreickteh2tt3oy43o42ikwei6tppghmtbkockk22a3niovi57ugor7q", + "time": 1696961232 + } + ], + "validationError": false + }, + { + "dpid": "107", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicgst5gqckb4bzduzxqhn2v5an2xjnmhv6qwscwtn3gjhuplpv3jm", + "time": 1697040396 + }, + { + "cid": "bafkreicgst5gqckb4bzduzxqhn2v5an2xjnmhv6qwscwtn3gjhuplpv3jm", + "time": 1697040396 + } + ], + "validationError": false + }, + { + "dpid": "108", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifzh36eve7dsmbebnvxhpalxdgcjcur7anxllzyfwnmetlsvq2f54", + "time": 1697792640 + }, + { + "cid": "bafkreifzh36eve7dsmbebnvxhpalxdgcjcur7anxllzyfwnmetlsvq2f54", + "time": 1697792640 + } + ], + "validationError": false + }, + { + "dpid": "109", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibiziudxe62de7g443yl453tpnky25ujrcdhuaudtwq7hxrrr6q3m", + "time": 1698054684 + }, + { + "cid": "bafkreibiziudxe62de7g443yl453tpnky25ujrcdhuaudtwq7hxrrr6q3m", + "time": 1698054684 + } + ], + "validationError": false + }, + { + "dpid": "110", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreic65maz27f7atu7a4euzl6jv4c2kz66ddvcxuhdajl4i4l27uwwii", + "time": 1698079308 + }, + { + "cid": "bafkreic65maz27f7atu7a4euzl6jv4c2kz66ddvcxuhdajl4i4l27uwwii", + "time": 1698079308 + }, + { + "cid": "bafkreic65maz27f7atu7a4euzl6jv4c2kz66ddvcxuhdajl4i4l27uwwii", + "time": 1698323460 + }, + { + "cid": "bafkreic65maz27f7atu7a4euzl6jv4c2kz66ddvcxuhdajl4i4l27uwwii", + "time": 1698323460 + } + ], + "validationError": false + }, + { + "dpid": "111", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiejskdyqkcsnvcl6njkivjvptts656x3qvr64nsjdnx6pcn6bdht4", + "time": 1698177444 + }, + { + "cid": "bafkreiejskdyqkcsnvcl6njkivjvptts656x3qvr64nsjdnx6pcn6bdht4", + "time": 1698177444 + }, + { + "cid": "bafkreialaclllbtsaxzdhbbut4mk57xh4r7bsj56cb44fockdxokcznbk4", + "time": 1698178344 + }, + { + "cid": "bafkreialaclllbtsaxzdhbbut4mk57xh4r7bsj56cb44fockdxokcznbk4", + "time": 1698178344 + } + ], + "validationError": false + }, + { + "dpid": "112", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreictzmcsbe3bkmb7vyludvy7q37brvsw6q7xayblyn45r23n7ru224", + "time": 1698747720 + }, + { + "cid": "bafkreictzmcsbe3bkmb7vyludvy7q37brvsw6q7xayblyn45r23n7ru224", + "time": 1698747720 + }, + { + "cid": "bafkreifpbperacf57typaumiauqsf3kcmljgm7ehu2vjmlflwepddpeth4", + "time": 1698747864 + }, + { + "cid": "bafkreifpbperacf57typaumiauqsf3kcmljgm7ehu2vjmlflwepddpeth4", + "time": 1698747864 + } + ], + "validationError": false + }, + { + "dpid": "113", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreig2nlksggv4ghb24xw7ng23klrttx3kiu3tdlnsa2gcn2zacpmxa4", + "time": 1698782484 + }, + { + "cid": "bafkreig2nlksggv4ghb24xw7ng23klrttx3kiu3tdlnsa2gcn2zacpmxa4", + "time": 1698782484 + } + ], + "validationError": false + }, + { + "dpid": "114", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibsaosbasq6er4o2mkovemlp6tgppyeudue6lsx6dbznba56omd6e", + "time": 1698782652 + }, + { + "cid": "bafkreibsaosbasq6er4o2mkovemlp6tgppyeudue6lsx6dbznba56omd6e", + "time": 1698782652 + } + ], + "validationError": false + }, + { + "dpid": "115", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiaqt4amqtdha2affz4caq6qrl3uzk4zutwfnzcc6ba5ziw6itc2ty", + "time": 1699355412 + }, + { + "cid": "bafkreiaqt4amqtdha2affz4caq6qrl3uzk4zutwfnzcc6ba5ziw6itc2ty", + "time": 1699355412 + }, + { + "cid": "bafkreichmxylugiwhtrhomfjc7njdmp6isfivmdsflhmuzenzxnyl76m5i", + "time": 1699355784 + }, + { + "cid": "bafkreichmxylugiwhtrhomfjc7njdmp6isfivmdsflhmuzenzxnyl76m5i", + "time": 1699355784 + } + ], + "validationError": false + }, + { + "dpid": "116", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreid4spqoyg2mk2r7bcju6vkxsgtcx2fl27tyivtvrvnwlqgn26udn4", + "time": 1699608000 + }, + { + "cid": "bafkreid4spqoyg2mk2r7bcju6vkxsgtcx2fl27tyivtvrvnwlqgn26udn4", + "time": 1699608000 + }, + { + "cid": "bafkreiejv6ymnxxum5c67qpkvp2eevgy7rgksq7vhzgyfxg5riwl33lzqe", + "time": 1699887960 + }, + { + "cid": "bafkreiejv6ymnxxum5c67qpkvp2eevgy7rgksq7vhzgyfxg5riwl33lzqe", + "time": 1699887960 + }, + { + "cid": "bafkreibechybrdrnwlsg3unh2pgxg2jgekg653h37e4xzc3wazyzcjzegq", + "time": 1699954776 + }, + { + "cid": "bafkreibechybrdrnwlsg3unh2pgxg2jgekg653h37e4xzc3wazyzcjzegq", + "time": 1699954776 + } + ], + "validationError": false + }, + { + "dpid": "117", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiepbbtkhudgspd6dr4rnckaqwdenedehsvppkyakute6z36bplgpy", + "time": 1699954800 + }, + { + "cid": "bafkreiepbbtkhudgspd6dr4rnckaqwdenedehsvppkyakute6z36bplgpy", + "time": 1699954800 + }, + { + "cid": "bafkreids7cf6gagvaxbmammx6ekl4e3xwhcyw33vkqmy5ml2m4epvpjwua", + "time": 1700053860 + }, + { + "cid": "bafkreids7cf6gagvaxbmammx6ekl4e3xwhcyw33vkqmy5ml2m4epvpjwua", + "time": 1700053860 + } + ], + "validationError": false + }, + { + "dpid": "118", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihv7uzjstazrksvrdwrt6j3oqiw73oqi2krvwlzojbo5yhrfrpcu4", + "time": 1699979532 + }, + { + "cid": "bafkreihv7uzjstazrksvrdwrt6j3oqiw73oqi2krvwlzojbo5yhrfrpcu4", + "time": 1699979532 + }, + { + "cid": "bafkreifwnjaykar4vdhcpyimr73hklty7nqnm77u37rzmdyhldtlleycfy", + "time": 1702053972 + }, + { + "cid": "bafkreifwnjaykar4vdhcpyimr73hklty7nqnm77u37rzmdyhldtlleycfy", + "time": 1702053972 + } + ], + "validationError": false + }, + { + "dpid": "119", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifisxmqzztc3zgleheiakn4xn5w7ze6ap5iynom46djxue54nvk5i", + "time": 1699983900 + }, + { + "cid": "bafkreifisxmqzztc3zgleheiakn4xn5w7ze6ap5iynom46djxue54nvk5i", + "time": 1699983900 + }, + { + "cid": "bafkreihhg6k56gey42vldxac36u3ueleq4nzrm2zw5fxfcdmwcdrfyjpci", + "time": 1699984152 + }, + { + "cid": "bafkreihhg6k56gey42vldxac36u3ueleq4nzrm2zw5fxfcdmwcdrfyjpci", + "time": 1699984152 + } + ], + "validationError": false + }, + { + "dpid": "120", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifonv6z5enzbl44kwvh3i3m5stmagckblhfp4skmilmt72ff3dthe", + "time": 1699984440 + }, + { + "cid": "bafkreifonv6z5enzbl44kwvh3i3m5stmagckblhfp4skmilmt72ff3dthe", + "time": 1699984440 + } + ], + "validationError": false + }, + { + "dpid": "121", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreig7g2zbirxw3spdxicv6igvu4t2frzdbipzh4q2lp7a7vzsnktdym", + "time": 1699984896 + }, + { + "cid": "bafkreig7g2zbirxw3spdxicv6igvu4t2frzdbipzh4q2lp7a7vzsnktdym", + "time": 1699984896 + } + ], + "validationError": false + }, + { + "dpid": "122", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidhtfpm7qcv36eklavzuhq7dxbfq7a2o3ovv6q55qubyr7xnvpnm4", + "time": 1700005716 + }, + { + "cid": "bafkreidhtfpm7qcv36eklavzuhq7dxbfq7a2o3ovv6q55qubyr7xnvpnm4", + "time": 1700005716 + } + ], + "validationError": false + }, + { + "dpid": "123", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifuyc6nxavordwnewceq6tdzbzs4u5u7eiohs2lflwabdmhrrcxtm", + "time": 1700006352 + }, + { + "cid": "bafkreifuyc6nxavordwnewceq6tdzbzs4u5u7eiohs2lflwabdmhrrcxtm", + "time": 1700006352 + } + ], + "validationError": false + }, + { + "dpid": "124", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiccwsruwcne5ctm4bdarr6772xgxqdcy3jg66rthmd5iaq2hnexgi", + "time": 1700046408 + }, + { + "cid": "bafkreiccwsruwcne5ctm4bdarr6772xgxqdcy3jg66rthmd5iaq2hnexgi", + "time": 1700046408 + }, + { + "cid": "bafkreihi36k65e6jlytud7hcvtxru2xbkphtxbdu3xx2pkm53qwb5mjzge", + "time": 1700046432 + }, + { + "cid": "bafkreihi36k65e6jlytud7hcvtxru2xbkphtxbdu3xx2pkm53qwb5mjzge", + "time": 1700046432 + }, + { + "cid": "bafkreiezsp3ibhch3wf4arb4ies65exfex2isowpfsrrlq6pyvatiexr5q", + "time": 1700046552 + }, + { + "cid": "bafkreiezsp3ibhch3wf4arb4ies65exfex2isowpfsrrlq6pyvatiexr5q", + "time": 1700046552 + } + ], + "validationError": false + }, + { + "dpid": "125", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidsdl7s6pqakmfhfvcauof7ovylegxa5nwp2dxuxd5rbb27vsk4d4", + "time": 1700057772 + }, + { + "cid": "bafkreidsdl7s6pqakmfhfvcauof7ovylegxa5nwp2dxuxd5rbb27vsk4d4", + "time": 1700057772 + }, + { + "cid": "bafkreidjcemwjx3ljeuja3lety52fksvk2ojukxkxudbnwu7kgse2zz3tm", + "time": 1700058384 + }, + { + "cid": "bafkreidjcemwjx3ljeuja3lety52fksvk2ojukxkxudbnwu7kgse2zz3tm", + "time": 1700058384 + } + ], + "validationError": false + }, + { + "dpid": "126", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreib6z6ysfnyw6k6ly7cpdp7qjcjbbvjoffn4ppiarimmk33sbxuoy4", + "time": 1700059584 + }, + { + "cid": "bafkreib6z6ysfnyw6k6ly7cpdp7qjcjbbvjoffn4ppiarimmk33sbxuoy4", + "time": 1700059584 + } + ], + "validationError": false + }, + { + "dpid": "127", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibqnmfw4jhrjk4ggz63kqtti7rzxroutotrrey2j37a3ad2wfuojm", + "time": 1700063400 + }, + { + "cid": "bafkreibqnmfw4jhrjk4ggz63kqtti7rzxroutotrrey2j37a3ad2wfuojm", + "time": 1700063400 + }, + { + "cid": "bafkreifgaoapp6ku2zt3awb3svh3ol75stczvu2bon373bit4whaneb2lm", + "time": 1700063832 + }, + { + "cid": "bafkreifgaoapp6ku2zt3awb3svh3ol75stczvu2bon373bit4whaneb2lm", + "time": 1700063832 + }, + { + "cid": "bafkreibbb2gkxihablys2fjtrecr2tvfbujyulblivfqn4jsl6hyx5dghy", + "time": 1708492476 + }, + { + "cid": "bafkreibbb2gkxihablys2fjtrecr2tvfbujyulblivfqn4jsl6hyx5dghy", + "time": 1708492476 + } + ], + "validationError": false + }, + { + "dpid": "128", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihjgheci62x27bgduapkcmwbxldpwyk5af5kqvbpq2nmfmtfxdmmm", + "time": 1700063832 + }, + { + "cid": "bafkreihjgheci62x27bgduapkcmwbxldpwyk5af5kqvbpq2nmfmtfxdmmm", + "time": 1700063832 + } + ], + "validationError": false + }, + { + "dpid": "129", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigtnznzipcb6j4ufpnmde3e66pzl53n7etkxjj4waorkc2vfzban4", + "time": 1700754096 + }, + { + "cid": "bafkreigtnznzipcb6j4ufpnmde3e66pzl53n7etkxjj4waorkc2vfzban4", + "time": 1700754096 + } + ], + "validationError": false + }, + { + "dpid": "130", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiaiwepaj5h3ueggcvsp7rs6zsu5emvcbxg4aantq43mjrvkb46t5i", + "time": 1701434724 + }, + { + "cid": "bafkreiaiwepaj5h3ueggcvsp7rs6zsu5emvcbxg4aantq43mjrvkb46t5i", + "time": 1701434724 + } + ], + "validationError": false + }, + { + "dpid": "131", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidw5k6li7ex6goxdky37t6obgd3472rbgygmvu5rnf6iiptrqkmiy", + "time": 1701702708 + }, + { + "cid": "bafkreidw5k6li7ex6goxdky37t6obgd3472rbgygmvu5rnf6iiptrqkmiy", + "time": 1701702708 + }, + { + "cid": "bafkreiaa4eh2bmuwlutgnvnbbd64npfqdlzxzc75li5pzhlmdkrvj5qjrq", + "time": 1701703056 + }, + { + "cid": "bafkreiaa4eh2bmuwlutgnvnbbd64npfqdlzxzc75li5pzhlmdkrvj5qjrq", + "time": 1701703056 + } + ], + "validationError": false + }, + { + "dpid": "132", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifqxy2ie6a5gwqwjdrjzpuer3d5dwb4sauljj6coojnzprlvfes2e", + "time": 1701788316 + }, + { + "cid": "bafkreifqxy2ie6a5gwqwjdrjzpuer3d5dwb4sauljj6coojnzprlvfes2e", + "time": 1701788316 + } + ], + "validationError": false + }, + { + "dpid": "133", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifyxvaek2nsdtke62wviupn7qqtgzeucrpe5c66lrycvtvestkkau", + "time": 1701795900 + }, + { + "cid": "bafkreifyxvaek2nsdtke62wviupn7qqtgzeucrpe5c66lrycvtvestkkau", + "time": 1701795900 + } + ], + "validationError": false + }, + { + "dpid": "134", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigu4xxysvqtf6cicat3iheugi6g45vsgnptbrht6p6om3txvsttye", + "time": 1701872976 + }, + { + "cid": "bafkreigu4xxysvqtf6cicat3iheugi6g45vsgnptbrht6p6om3txvsttye", + "time": 1701872976 + } + ], + "validationError": false + }, + { + "dpid": "135", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihf45jsg5rnkpv2mz2wwpf5w3u6ixu765a5hckam3j3fbl5i2tgbq", + "time": 1701875664 + }, + { + "cid": "bafkreihf45jsg5rnkpv2mz2wwpf5w3u6ixu765a5hckam3j3fbl5i2tgbq", + "time": 1701875664 + } + ], + "validationError": false + }, + { + "dpid": "136", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreih5g3pbinh264nuwgvsuerueucgpacv5ytill4sbxt7zsexgfntqi", + "time": 1702142316 + }, + { + "cid": "bafkreih5g3pbinh264nuwgvsuerueucgpacv5ytill4sbxt7zsexgfntqi", + "time": 1702142316 + }, + { + "cid": "bafkreiaitokvbuwllmihafculxuniwiydtl2cuuuhqbmkuvpk62uuhmu4e", + "time": 1702145736 + }, + { + "cid": "bafkreiaitokvbuwllmihafculxuniwiydtl2cuuuhqbmkuvpk62uuhmu4e", + "time": 1702145736 + }, + { + "cid": "bafkreifyo3tzgp3bp7a7zwxym6lskt567rdvjn4t334dczglkvgbpglla4", + "time": 1702202688 + }, + { + "cid": "bafkreifyo3tzgp3bp7a7zwxym6lskt567rdvjn4t334dczglkvgbpglla4", + "time": 1702202688 + }, + { + "cid": "bafkreif4yaj5za2adpy3wmklbstwpaciobl3j4uwcwrwcri7bbkcvwik6q", + "time": 1708382904 + }, + { + "cid": "bafkreif4yaj5za2adpy3wmklbstwpaciobl3j4uwcwrwcri7bbkcvwik6q", + "time": 1708382904 + } + ], + "validationError": false + }, + { + "dpid": "137", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiebtockthsjrwsikbjshzdikjsa3j35avolyabw2zl5nxd4np2qa4", + "time": 1702430448 + }, + { + "cid": "bafkreiebtockthsjrwsikbjshzdikjsa3j35avolyabw2zl5nxd4np2qa4", + "time": 1702430448 + }, + { + "cid": "bafkreig5muvzq5a5whji264zbzpkd452kqiswo4on3b3waibrwcte6n2jq", + "time": 1702439796 + }, + { + "cid": "bafkreig5muvzq5a5whji264zbzpkd452kqiswo4on3b3waibrwcte6n2jq", + "time": 1702439796 + } + ], + "validationError": false + }, + { + "dpid": "138", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiezlcl57kasksq7hwdqxsffpqloek4jbr4vrvausbg6ozsrnwnkfq", + "time": 1702512600 + }, + { + "cid": "bafkreiezlcl57kasksq7hwdqxsffpqloek4jbr4vrvausbg6ozsrnwnkfq", + "time": 1702512600 + }, + { + "cid": "bafkreifxevx7yu5noaquu4bojmyl6pubqotkp4wsbjpd6vbz3neuk7nlxu", + "time": 1707153744 + }, + { + "cid": "bafkreifxevx7yu5noaquu4bojmyl6pubqotkp4wsbjpd6vbz3neuk7nlxu", + "time": 1707153744 + } + ], + "validationError": false + }, + { + "dpid": "139", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreictkrrk3arfcy4rstvjjtpwrw3yf7wdgxepf5z2cmjuiv2igkdlnm", + "time": 1702512876 + }, + { + "cid": "bafkreictkrrk3arfcy4rstvjjtpwrw3yf7wdgxepf5z2cmjuiv2igkdlnm", + "time": 1702512876 + } + ], + "validationError": false + }, + { + "dpid": "140", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibz4nvkwdmqxmtxefklebrqrhbbhias3bvt7moko5jgw6hopkhwga", + "time": 1702513068 + }, + { + "cid": "bafkreibz4nvkwdmqxmtxefklebrqrhbbhias3bvt7moko5jgw6hopkhwga", + "time": 1702513068 + }, + { + "cid": "bafkreifbhbxfm6s6djz5taz5buthqlpy2cruaysfnixojzubwgkprsbq4i", + "time": 1708801020 + }, + { + "cid": "bafkreifbhbxfm6s6djz5taz5buthqlpy2cruaysfnixojzubwgkprsbq4i", + "time": 1708801020 + } + ], + "validationError": false + }, + { + "dpid": "141", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifkjw3mjt4ib4dhjjpn2sbv3oqf4c5mcf5n7zlggynvvqlwksdxay", + "time": 1702513164 + }, + { + "cid": "bafkreifkjw3mjt4ib4dhjjpn2sbv3oqf4c5mcf5n7zlggynvvqlwksdxay", + "time": 1702513164 + }, + { + "cid": "bafkreiabv34brs4dnbivmzfyggc2ryaxs7zlb3x3zh2ynie53suktlitva", + "time": 1708802436 + }, + { + "cid": "bafkreiabv34brs4dnbivmzfyggc2ryaxs7zlb3x3zh2ynie53suktlitva", + "time": 1708802436 + }, + { + "cid": "bafkreiabv34brs4dnbivmzfyggc2ryaxs7zlb3x3zh2ynie53suktlitva", + "time": 1708802436 + }, + { + "cid": "bafkreiabv34brs4dnbivmzfyggc2ryaxs7zlb3x3zh2ynie53suktlitva", + "time": 1708802436 + } + ], + "validationError": false + }, + { + "dpid": "142", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidll4iaylvaplqqqotp3e7bolx3qgqnjkzliplbhdz7v7dcrdn65q", + "time": 1702513344 + }, + { + "cid": "bafkreidll4iaylvaplqqqotp3e7bolx3qgqnjkzliplbhdz7v7dcrdn65q", + "time": 1702513344 + }, + { + "cid": "bafkreieszmyc5ph43ft77gk4pj5emhuy53if6vjbeejzxbrtusxb3ouq54", + "time": 1708802160 + }, + { + "cid": "bafkreieszmyc5ph43ft77gk4pj5emhuy53if6vjbeejzxbrtusxb3ouq54", + "time": 1708802160 + } + ], + "validationError": false + }, + { + "dpid": "143", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidjonu3vhm5vd5fogs3zrjzq3qcajjkpvwwj43gdqn2swiops5glm", + "time": 1702513392 + }, + { + "cid": "bafkreidjonu3vhm5vd5fogs3zrjzq3qcajjkpvwwj43gdqn2swiops5glm", + "time": 1702513392 + }, + { + "cid": "bafkreih25vwbntxxybpsxctpg5eqi6f7ewcwzqzpklifbfqffcrbs65k64", + "time": 1708802052 + }, + { + "cid": "bafkreih25vwbntxxybpsxctpg5eqi6f7ewcwzqzpklifbfqffcrbs65k64", + "time": 1708802052 + } + ], + "validationError": false + }, + { + "dpid": "144", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreieogvypbmg7vgut2f76b33kql6cw4vstzm4f7asoenfzh2rudpekm", + "time": 1702513452 + }, + { + "cid": "bafkreieogvypbmg7vgut2f76b33kql6cw4vstzm4f7asoenfzh2rudpekm", + "time": 1702513452 + }, + { + "cid": "bafkreib3b6ztd5tyebhjtxsj4dpl2nw3bipejak5n3zz7u7ta3et2ghyoq", + "time": 1708801908 + }, + { + "cid": "bafkreib3b6ztd5tyebhjtxsj4dpl2nw3bipejak5n3zz7u7ta3et2ghyoq", + "time": 1708801908 + } + ], + "validationError": false + }, + { + "dpid": "145", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibbu3bk7ucli5yaikmcwdduigaien2dqb2bzq4af6ufzrmu6vswty", + "time": 1702513524 + }, + { + "cid": "bafkreibbu3bk7ucli5yaikmcwdduigaien2dqb2bzq4af6ufzrmu6vswty", + "time": 1702513524 + }, + { + "cid": "bafkreig2mtcbf6eu2vraqmy5ftukn4i6fgeiwfou2znswwss5sarsotmcm", + "time": 1708801680 + }, + { + "cid": "bafkreig2mtcbf6eu2vraqmy5ftukn4i6fgeiwfou2znswwss5sarsotmcm", + "time": 1708801680 + } + ], + "validationError": false + }, + { + "dpid": "146", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreied3q6xs3itsgvjgeybu5cnmuuds2puklksrhfvy4ofjddo3nkyle", + "time": 1702513584 + }, + { + "cid": "bafkreied3q6xs3itsgvjgeybu5cnmuuds2puklksrhfvy4ofjddo3nkyle", + "time": 1702513584 + } + ], + "validationError": false + }, + { + "dpid": "147", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiapkcqpkavfwqc4id5mb7e46n3f5nr5uig4ik7bwaxk7a5tox2ztq", + "time": 1702513620 + }, + { + "cid": "bafkreiapkcqpkavfwqc4id5mb7e46n3f5nr5uig4ik7bwaxk7a5tox2ztq", + "time": 1702513620 + }, + { + "cid": "bafkreifxvagntjqfpzrigsjfajflqatzk4dogq56lqotaqjv7d3iugdrtm", + "time": 1708801212 + }, + { + "cid": "bafkreifxvagntjqfpzrigsjfajflqatzk4dogq56lqotaqjv7d3iugdrtm", + "time": 1708801212 + }, + { + "cid": "bafkreifxvagntjqfpzrigsjfajflqatzk4dogq56lqotaqjv7d3iugdrtm", + "time": 1708801236 + }, + { + "cid": "bafkreifxvagntjqfpzrigsjfajflqatzk4dogq56lqotaqjv7d3iugdrtm", + "time": 1708801236 + } + ], + "validationError": false + }, + { + "dpid": "148", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibgprhlr22zfwgrm7y3kx4jxslpozqp4pmofsrj5tbqpkaxi5glpe", + "time": 1702559448 + }, + { + "cid": "bafkreibgprhlr22zfwgrm7y3kx4jxslpozqp4pmofsrj5tbqpkaxi5glpe", + "time": 1702559448 + }, + { + "cid": "bafkreieqjqllffddjuraswoq4pm5d5cd5eu2knqe6yie7rj6aufujtct4e", + "time": 1702907160 + }, + { + "cid": "bafkreieqjqllffddjuraswoq4pm5d5cd5eu2knqe6yie7rj6aufujtct4e", + "time": 1702907160 + } + ], + "validationError": false + }, + { + "dpid": "149", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigcc2l7aay34i5zeot5wjvpspdpwp6ipfzffs3cnnpbpt7c2gqu6i", + "time": 1703003448 + }, + { + "cid": "bafkreigcc2l7aay34i5zeot5wjvpspdpwp6ipfzffs3cnnpbpt7c2gqu6i", + "time": 1703003448 + }, + { + "cid": "bafkreig6lp6265u42llqh6hkzxc54hmyfea7ax7gewg7tdyvthieotmwpy", + "time": 1703003868 + }, + { + "cid": "bafkreig6lp6265u42llqh6hkzxc54hmyfea7ax7gewg7tdyvthieotmwpy", + "time": 1703003868 + }, + { + "cid": "bafkreici3wzz7njqigyo7ebzwn3kibxgwjr43ihowwebl4exmfy75tkpjm", + "time": 1703072388 + }, + { + "cid": "bafkreici3wzz7njqigyo7ebzwn3kibxgwjr43ihowwebl4exmfy75tkpjm", + "time": 1703072388 + }, + { + "cid": "bafkreicgxdcypaq5tmmrrva3tl7k2un47pfolg3mox72j5k65zitsukfii", + "time": 1707406116 + }, + { + "cid": "bafkreicgxdcypaq5tmmrrva3tl7k2un47pfolg3mox72j5k65zitsukfii", + "time": 1707406116 + }, + { + "cid": "bafkreie7j6ji7ynh5d5yoldoxfevak55nkmcx5h7v3c6h4xy7le25sbgke", + "time": 1709143824 + }, + { + "cid": "bafkreie7j6ji7ynh5d5yoldoxfevak55nkmcx5h7v3c6h4xy7le25sbgke", + "time": 1709143824 + } + ], + "validationError": false + }, + { + "dpid": "150", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreif3aoauxavq7sxibkysi4kemqdwbcez4cjtmzoou46bj44r2rc3sa", + "time": 1703205816 + }, + { + "cid": "bafkreif3aoauxavq7sxibkysi4kemqdwbcez4cjtmzoou46bj44r2rc3sa", + "time": 1703205816 + } + ], + "validationError": false + }, + { + "dpid": "151", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicqe2blgjarm3bg6jon5sjvmu773bnuajfnkmlnvo5hd5uj2yr234", + "time": 1703212224 + }, + { + "cid": "bafkreicqe2blgjarm3bg6jon5sjvmu773bnuajfnkmlnvo5hd5uj2yr234", + "time": 1703212224 + } + ], + "validationError": false + }, + { + "dpid": "152", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifiy2ipxllse5z6kspsspgt247eadivoij736j3yehwe6cy5rn6ny", + "time": 1705091376 + }, + { + "cid": "bafkreifiy2ipxllse5z6kspsspgt247eadivoij736j3yehwe6cy5rn6ny", + "time": 1705091376 + }, + { + "cid": "bafkreihvutuhtiehsoyc66u7a7bncnqfhoosynejagkykkfwa7gkr2rsta", + "time": 1705091496 + }, + { + "cid": "bafkreihvutuhtiehsoyc66u7a7bncnqfhoosynejagkykkfwa7gkr2rsta", + "time": 1705091496 + }, + { + "cid": "bafkreiekobyktiisailjk2sauqxembzyqe26z7i7mxkl6xidhhlb62wnyi", + "time": 1706832732 + }, + { + "cid": "bafkreiekobyktiisailjk2sauqxembzyqe26z7i7mxkl6xidhhlb62wnyi", + "time": 1706832732 + } + ], + "validationError": false + }, + { + "dpid": "153", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigr54hmercrddm2nnyo46yfn3w466zeoawph7k23swzr5v6lobcjm", + "time": 1705491780 + }, + { + "cid": "bafkreigr54hmercrddm2nnyo46yfn3w466zeoawph7k23swzr5v6lobcjm", + "time": 1705491780 + } + ], + "validationError": false + }, + { + "dpid": "154", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidzawjc7uaskxy2a55gfd3pjqssl5v6nfqj4ghziglbdfuk3arfri", + "time": 1705579488 + }, + { + "cid": "bafkreidzawjc7uaskxy2a55gfd3pjqssl5v6nfqj4ghziglbdfuk3arfri", + "time": 1705579488 + } + ], + "validationError": false + }, + { + "dpid": "155", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreieqqvt2bx34g44zombuj254dzqng5l4bjc33vnuduiaklfjf7jrza", + "time": 1706550924 + }, + { + "cid": "bafkreieqqvt2bx34g44zombuj254dzqng5l4bjc33vnuduiaklfjf7jrza", + "time": 1706550924 + } + ], + "validationError": false + }, + { + "dpid": "156", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibhuuogniwgsozq6zqgpfg622ktaz4e4xtspvxv6be7zoaknlp7oi", + "time": 1706735148 + }, + { + "cid": "bafkreibhuuogniwgsozq6zqgpfg622ktaz4e4xtspvxv6be7zoaknlp7oi", + "time": 1706735148 + }, + { + "cid": "bafkreicmyxjhueivvlucnysc5sgmdnxgsmn5wryaodmdwl7xhku5o4dwki", + "time": 1706737632 + }, + { + "cid": "bafkreicmyxjhueivvlucnysc5sgmdnxgsmn5wryaodmdwl7xhku5o4dwki", + "time": 1706737632 + } + ], + "validationError": false + }, + { + "dpid": "157", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreificypwhqbtu4acdrxgbzdrpbw5dncxrcwtskrebhv53trsk23ive", + "time": 1706738172 + }, + { + "cid": "bafkreificypwhqbtu4acdrxgbzdrpbw5dncxrcwtskrebhv53trsk23ive", + "time": 1706738172 + } + ], + "validationError": false + }, + { + "dpid": "158", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigmgjpsfxzshdvozllx3m6s5ubiulcx7yumhe7armganzdiu42feu", + "time": 1706834520 + }, + { + "cid": "bafkreigmgjpsfxzshdvozllx3m6s5ubiulcx7yumhe7armganzdiu42feu", + "time": 1706834520 + } + ], + "validationError": false + }, + { + "dpid": "159", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifl7hhai6p5podahrcse5ocklgf2qdayw33raeaugk4cjgugroupq", + "time": 1707473772 + }, + { + "cid": "bafkreifl7hhai6p5podahrcse5ocklgf2qdayw33raeaugk4cjgugroupq", + "time": 1707473772 + } + ], + "validationError": false + }, + { + "dpid": "160", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifjtpqkpatgmy4jpmhsepfvpv2gmiofgyh6qpinfnstyrsufickua", + "time": 1707644916 + }, + { + "cid": "bafkreifjtpqkpatgmy4jpmhsepfvpv2gmiofgyh6qpinfnstyrsufickua", + "time": 1707644916 + }, + { + "cid": "bafkreif2hl47drgqwb6qay5dbdmmm4ivbcfus3wromwaho2wxine6niudm", + "time": 1707645552 + }, + { + "cid": "bafkreif2hl47drgqwb6qay5dbdmmm4ivbcfus3wromwaho2wxine6niudm", + "time": 1707645552 + }, + { + "cid": "bafkreihopqbkiidgwszltgcx3cp3n5m3vkfcyqf5tktaf7zpikdwqkpkmu", + "time": 1707646572 + }, + { + "cid": "bafkreihopqbkiidgwszltgcx3cp3n5m3vkfcyqf5tktaf7zpikdwqkpkmu", + "time": 1707646572 + } + ], + "validationError": false + }, + { + "dpid": "161", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreialnzhaztvhuvwkzpqlst7w3yttviws5tcpdnwvggdmxnx2ydzere", + "time": 1707848244 + }, + { + "cid": "bafkreialnzhaztvhuvwkzpqlst7w3yttviws5tcpdnwvggdmxnx2ydzere", + "time": 1707848244 + } + ], + "validationError": false + }, + { + "dpid": "162", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreieowcw35rvuvocaupds5fsremm4h6j3cris5sscfjun4o2e4bccla", + "time": 1707967356 + }, + { + "cid": "bafkreieowcw35rvuvocaupds5fsremm4h6j3cris5sscfjun4o2e4bccla", + "time": 1707967356 + } + ], + "validationError": false + }, + { + "dpid": "163", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreif4554qs4ppds7364pfeqla623ebon5nlvs5m53ecw4jhdkmtnfre", + "time": 1707967740 + }, + { + "cid": "bafkreif4554qs4ppds7364pfeqla623ebon5nlvs5m53ecw4jhdkmtnfre", + "time": 1707967740 + } + ], + "validationError": false + }, + { + "dpid": "164", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidn5fdrmh62nc4r3g5paqija32flksc23evsc5akqoqftkwfeqm2i", + "time": 1708094712 + }, + { + "cid": "bafkreidn5fdrmh62nc4r3g5paqija32flksc23evsc5akqoqftkwfeqm2i", + "time": 1708094712 + }, + { + "cid": "bafkreibpaflwrfhygpheciwlemvahtkkwdgg35dnevu25rid46iae2ws6i", + "time": 1708453920 + }, + { + "cid": "bafkreibpaflwrfhygpheciwlemvahtkkwdgg35dnevu25rid46iae2ws6i", + "time": 1708453920 + }, + { + "cid": "bafkreif7javbr3hrnuwmoggv7dtprs7axcsdldsqpwmpfcdizy5bk2tfxa", + "time": 1708514124 + }, + { + "cid": "bafkreif7javbr3hrnuwmoggv7dtprs7axcsdldsqpwmpfcdizy5bk2tfxa", + "time": 1708514124 + } + ], + "validationError": false + }, + { + "dpid": "165", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicv2zf35h43m656h2734du5ynp2zctedwxkgwtbhubg34oenhhexa", + "time": 1708109700 + }, + { + "cid": "bafkreicv2zf35h43m656h2734du5ynp2zctedwxkgwtbhubg34oenhhexa", + "time": 1708109700 + } + ], + "validationError": false + }, + { + "dpid": "166", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibfvwqckon265lpmjuinzlg6ebzo4s6dtgh7invz2prf766bvuodm", + "time": 1708372176 + }, + { + "cid": "bafkreibfvwqckon265lpmjuinzlg6ebzo4s6dtgh7invz2prf766bvuodm", + "time": 1708372176 + } + ], + "validationError": false + }, + { + "dpid": "167", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreige2oxxkk4rboadjcxlvwbvlun3e4xmrxp4qtqvdmjdfzhptuyf5a", + "time": 1708458984 + }, + { + "cid": "bafkreige2oxxkk4rboadjcxlvwbvlun3e4xmrxp4qtqvdmjdfzhptuyf5a", + "time": 1708458984 + } + ], + "validationError": false + }, + { + "dpid": "168", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiftjc6urzlqlcffupjwnezhfash4tlvgy2qnstu2vpp6tdk4zpmma", + "time": 1708493796 + }, + { + "cid": "bafkreiftjc6urzlqlcffupjwnezhfash4tlvgy2qnstu2vpp6tdk4zpmma", + "time": 1708493796 + }, + { + "cid": "bafkreic4hj66auaehgtgoz6zzks2w2r7lsxhrisjuh7dbfipvgmkhfpace", + "time": 1708690584 + }, + { + "cid": "bafkreic4hj66auaehgtgoz6zzks2w2r7lsxhrisjuh7dbfipvgmkhfpace", + "time": 1708690584 + } + ], + "validationError": false + }, + { + "dpid": "169", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidguz57tkqtmta44oov6jkgxxeg635asddp2belouydyxjndukspi", + "time": 1708495980 + }, + { + "cid": "bafkreidguz57tkqtmta44oov6jkgxxeg635asddp2belouydyxjndukspi", + "time": 1708495980 + } + ], + "validationError": false + }, + { + "dpid": "170", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidyakyvrrmovwk4ddfw2fxtgkl3f4coef75pybncmoa55jnlxx6tm", + "time": 1708501884 + }, + { + "cid": "bafkreidyakyvrrmovwk4ddfw2fxtgkl3f4coef75pybncmoa55jnlxx6tm", + "time": 1708501884 + }, + { + "cid": "bafkreiddvndkkcaqwdmetqxfl2vhfag45c4cug6aubsnlrl7uk66y3pzrq", + "time": 1710843672 + }, + { + "cid": "bafkreibsbid5gceknfrbun76wrdq73vzglgxq25yy2pg7fnpflfuucem6e", + "time": 1710844824 + }, + { + "cid": "bafkreibsbid5gceknfrbun76wrdq73vzglgxq25yy2pg7fnpflfuucem6e", + "time": 1710845520 + }, + { + "cid": "bafkreiav726womo5gxdii7ootir2uuhdn34fzej3f6ala7xynge6ag543a", + "time": 1710846540 + } + ], + "validationError": false + }, + { + "dpid": "171", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibtajzmf7ty7hhyclz4aj5f74mktbj4liyhobvs3qr7nebqprl2yi", + "time": 1708516896 + }, + { + "cid": "bafkreibtajzmf7ty7hhyclz4aj5f74mktbj4liyhobvs3qr7nebqprl2yi", + "time": 1708516896 + } + ], + "validationError": false + }, + { + "dpid": "172", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicenejlzy2ygk6vflo4xhr7hjqe22nz5f354afoo5pc65d6qf2ojq", + "time": 1708523184 + }, + { + "cid": "bafkreicenejlzy2ygk6vflo4xhr7hjqe22nz5f354afoo5pc65d6qf2ojq", + "time": 1708523184 + }, + { + "cid": "bafkreibhvfaxoampgahsqavwoc3r5qwsmb23cg5lavkgoak77x4htgjism", + "time": 1712669388 + }, + { + "cid": "bafkreiab7zb4iwbnd6atuukrzkjcph7hbc763rqxnhrl3xtk7c73c3ofsi", + "time": 1712679120 + }, + { + "cid": "bafkreifxjj6yjggeno26fceojxb3ibuoaszeettsqwumuw337owiu2goaq", + "time": 1712758368 + }, + { + "cid": "bafkreic5tnpaovahue6zvswongz52o2kog7ngwiawcmwcq63xskxfwltdm", + "time": 1712854176 + }, + { + "cid": "bafkreic5tnpaovahue6zvswongz52o2kog7ngwiawcmwcq63xskxfwltdm", + "time": 1712859180 + }, + { + "cid": "bafkreignqmhx4yaaaqytcf2q7hhvbhyz5nrsqq4sv23jbenzs65luutaqu", + "time": 1713200220 + }, + { + "cid": "bafkreihv4owtfk4yfhljptkfrcsnt6nnaobbgsfl4h2ivxgi3kbtvzspc4", + "time": 1713212124 + } + ], + "validationError": false + }, + { + "dpid": "173", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreie23vmvink27bqo7qzzsdng4ho22uhrgoscencr7s4itekrzreahy", + "time": 1708531344 + }, + { + "cid": "bafkreie23vmvink27bqo7qzzsdng4ho22uhrgoscencr7s4itekrzreahy", + "time": 1708531344 + }, + { + "cid": "bafkreie23vmvink27bqo7qzzsdng4ho22uhrgoscencr7s4itekrzreahy", + "time": 1708531620 + }, + { + "cid": "bafkreie23vmvink27bqo7qzzsdng4ho22uhrgoscencr7s4itekrzreahy", + "time": 1708531620 + }, + { + "cid": "bafkreie23vmvink27bqo7qzzsdng4ho22uhrgoscencr7s4itekrzreahy", + "time": 1708531992 + }, + { + "cid": "bafkreie23vmvink27bqo7qzzsdng4ho22uhrgoscencr7s4itekrzreahy", + "time": 1708531992 + }, + { + "cid": "bafkreie23vmvink27bqo7qzzsdng4ho22uhrgoscencr7s4itekrzreahy", + "time": 1708532064 + }, + { + "cid": "bafkreie23vmvink27bqo7qzzsdng4ho22uhrgoscencr7s4itekrzreahy", + "time": 1708532064 + } + ], + "validationError": false + }, + { + "dpid": "174", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidobtwdrk7dulyc6dghfr6zylbfisjwbs6l6ahd6qfkfdavs76dpa", + "time": 1708602732 + }, + { + "cid": "bafkreidobtwdrk7dulyc6dghfr6zylbfisjwbs6l6ahd6qfkfdavs76dpa", + "time": 1708602732 + } + ], + "validationError": false + }, + { + "dpid": "175", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreignopdmerljfo6nzpq2hj5zr5g7h3wajjxthpuikxjpsdbco4tavm", + "time": 1708619376 + }, + { + "cid": "bafkreignopdmerljfo6nzpq2hj5zr5g7h3wajjxthpuikxjpsdbco4tavm", + "time": 1708619376 + }, + { + "cid": "bafkreiae65pw54dt5vx75oenehagushpi2sh42c3zqld7der3ircmfyqam", + "time": 1708653516 + }, + { + "cid": "bafkreiae65pw54dt5vx75oenehagushpi2sh42c3zqld7der3ircmfyqam", + "time": 1708653516 + }, + { + "cid": "bafkreihm7iuibrdzlr5uyrhhkyijboyheeujettcihcgmegrna43mmvs6a", + "time": 1708672332 + }, + { + "cid": "bafkreihm7iuibrdzlr5uyrhhkyijboyheeujettcihcgmegrna43mmvs6a", + "time": 1708672332 + }, + { + "cid": "bafkreicjzr7d4odl6dzvx3acnng3cwq5sptcjn5wbqeep4juymadohagfi", + "time": 1708674912 + }, + { + "cid": "bafkreicjzr7d4odl6dzvx3acnng3cwq5sptcjn5wbqeep4juymadohagfi", + "time": 1708674912 + }, + { + "cid": "bafkreihdgbp3rrimo3sfayouabpfy5awspr6lues5rj5pjld2mcwi5ftsm", + "time": 1708729500 + }, + { + "cid": "bafkreihdgbp3rrimo3sfayouabpfy5awspr6lues5rj5pjld2mcwi5ftsm", + "time": 1708729500 + }, + { + "cid": "bafkreidpouvko3ht6dkhplrx44r4cbycx4irvw6mnunven3x2mll5kgaie", + "time": 1708890600 + }, + { + "cid": "bafkreidpouvko3ht6dkhplrx44r4cbycx4irvw6mnunven3x2mll5kgaie", + "time": 1708890600 + } + ], + "validationError": false + }, + { + "dpid": "176", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidwx6vv43n4vyd2gvnc7a7hoalg3nj6ncuxtzete7bay6lgkdjrji", + "time": 1708695348 + }, + { + "cid": "bafkreidwx6vv43n4vyd2gvnc7a7hoalg3nj6ncuxtzete7bay6lgkdjrji", + "time": 1708695348 + }, + { + "cid": "bafkreibjcr22ex3uibpoxf3fpzriafscmbivizzkqrjx7iqh5qbkg4oizq", + "time": 1708695612 + }, + { + "cid": "bafkreibjcr22ex3uibpoxf3fpzriafscmbivizzkqrjx7iqh5qbkg4oizq", + "time": 1708695612 + } + ], + "validationError": false + }, + { + "dpid": "177", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihnul5baol6hg5vsq6sokqwbm5txyb5honlphs3rpjklc4d7pj4qi", + "time": 1708882260 + }, + { + "cid": "bafkreihnul5baol6hg5vsq6sokqwbm5txyb5honlphs3rpjklc4d7pj4qi", + "time": 1708882260 + }, + { + "cid": "bafkreidp7tepg63xchd2sxngslv6douzhg53j7ndnf4bwbxgwthvjxgmhq", + "time": 1715951676 + } + ], + "validationError": false + }, + { + "dpid": "178", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibnvu2kmntm4p2ttebfqukas5hdzzthyahkkgxizihb4f3fwvszoy", + "time": 1708900272 + }, + { + "cid": "bafkreibnvu2kmntm4p2ttebfqukas5hdzzthyahkkgxizihb4f3fwvszoy", + "time": 1708900272 + }, + { + "cid": "bafkreibax2nwfvcmewzi4muxbtywulni6zvvihnipob3hvweohuu3lmawu", + "time": 1708900680 + }, + { + "cid": "bafkreibax2nwfvcmewzi4muxbtywulni6zvvihnipob3hvweohuu3lmawu", + "time": 1708900680 + }, + { + "cid": "bafkreiaicia5j7xdpo5gr3nukomg7kylxpnyfiguflr7ff5z6v45rbg3om", + "time": 1708909188 + }, + { + "cid": "bafkreiaicia5j7xdpo5gr3nukomg7kylxpnyfiguflr7ff5z6v45rbg3om", + "time": 1708909188 + } + ], + "validationError": false + }, + { + "dpid": "179", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiekmumtbr6fg6ksitwx3744knbituhthjis3mnd5facdbqc6526fy", + "time": 1708930572 + }, + { + "cid": "bafkreiekmumtbr6fg6ksitwx3744knbituhthjis3mnd5facdbqc6526fy", + "time": 1708930572 + } + ], + "validationError": false + }, + { + "dpid": "180", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihyn2pm7mqzcjabytkoszcetquu4q6zouwaeqhp6bavvlmijqvj2m", + "time": 1708965960 + }, + { + "cid": "bafkreihyn2pm7mqzcjabytkoszcetquu4q6zouwaeqhp6bavvlmijqvj2m", + "time": 1708965960 + }, + { + "cid": "bafkreigksvcw5f67h2kzbxnndwf47ch74nb4vbniepacjt6y5nm74ote4m", + "time": 1708966848 + }, + { + "cid": "bafkreigksvcw5f67h2kzbxnndwf47ch74nb4vbniepacjt6y5nm74ote4m", + "time": 1708966848 + }, + { + "cid": "bafkreifhzq76yqo66hcvcj2e7554odbcppblavfrobmyuxynaj2wv2ydlm", + "time": 1708974048 + }, + { + "cid": "bafkreifhzq76yqo66hcvcj2e7554odbcppblavfrobmyuxynaj2wv2ydlm", + "time": 1708974048 + } + ], + "validationError": false + }, + { + "dpid": "181", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreieqzlofquf3yakkfcqwzzg77ea6qrirnbli6iedpeo5zk2hktedfe", + "time": 1709032560 + }, + { + "cid": "bafkreieqzlofquf3yakkfcqwzzg77ea6qrirnbli6iedpeo5zk2hktedfe", + "time": 1709032560 + } + ], + "validationError": false + }, + { + "dpid": "182", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidjaowinhp5e3m6ikq32mfgqg5mqw6ttzccngl5aa2imyryscenjq", + "time": 1709070444 + }, + { + "cid": "bafkreidjaowinhp5e3m6ikq32mfgqg5mqw6ttzccngl5aa2imyryscenjq", + "time": 1709070444 + }, + { + "cid": "bafkreidjaowinhp5e3m6ikq32mfgqg5mqw6ttzccngl5aa2imyryscenjq", + "time": 1709070600 + }, + { + "cid": "bafkreidjaowinhp5e3m6ikq32mfgqg5mqw6ttzccngl5aa2imyryscenjq", + "time": 1709070600 + } + ], + "validationError": false + }, + { + "dpid": "183", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihfy4ibvcrdxlq3n6y6ahskxglvyhskwugy7xwi4amk4dcek7hvvi", + "time": 1709074644 + }, + { + "cid": "bafkreihfy4ibvcrdxlq3n6y6ahskxglvyhskwugy7xwi4amk4dcek7hvvi", + "time": 1709074644 + } + ], + "validationError": false + }, + { + "dpid": "184", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreif4pg7ph3qxuj4yoapw4tez3jxt52m5fhp7nkd3q2ai4xrwva46oq", + "time": 1709709132 + }, + { + "cid": "bafkreif4pg7ph3qxuj4yoapw4tez3jxt52m5fhp7nkd3q2ai4xrwva46oq", + "time": 1709709132 + } + ], + "validationError": false + }, + { + "dpid": "185", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibbt24dc64gwzwhcjtyha5qsdvmj4ztlkbhg7p7s74hjpdlrveo5a", + "time": 1709710296 + }, + { + "cid": "bafkreibbt24dc64gwzwhcjtyha5qsdvmj4ztlkbhg7p7s74hjpdlrveo5a", + "time": 1709710296 + } + ], + "validationError": false + }, + { + "dpid": "186", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiezmycqcs3426uhlpamwfidxlt72njmc22cuma47fxx5e3oi7zrpq", + "time": 1709713596 + }, + { + "cid": "bafkreiezmycqcs3426uhlpamwfidxlt72njmc22cuma47fxx5e3oi7zrpq", + "time": 1709713596 + } + ], + "validationError": false + }, + { + "dpid": "187", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiemcbfxzi5v3sjiztw4zqs7ngbbirmbcza2sxag4ur4gx3jc57weu", + "time": 1709713968 + }, + { + "cid": "bafkreiemcbfxzi5v3sjiztw4zqs7ngbbirmbcza2sxag4ur4gx3jc57weu", + "time": 1709713968 + } + ], + "validationError": false + }, + { + "dpid": "188", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifc7blw4sfdrqqyinooyk2zajg4kvobazfpxmmyxhky67xyrtg2bi", + "time": 1709717856 + }, + { + "cid": "bafkreifc7blw4sfdrqqyinooyk2zajg4kvobazfpxmmyxhky67xyrtg2bi", + "time": 1709717856 + } + ], + "validationError": false + }, + { + "dpid": "189", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreib5w5wqatnhuuekzdmqe33ci4jmczwtcw235mdugsk6sbjkewhycq", + "time": 1709718156 + }, + { + "cid": "bafkreib5w5wqatnhuuekzdmqe33ci4jmczwtcw235mdugsk6sbjkewhycq", + "time": 1709718156 + } + ], + "validationError": false + }, + { + "dpid": "190", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidlwnin6u3lbb5me7gsaomtrz3xfxruteb3oqvng2isup6dq2md2u", + "time": 1710044316 + }, + { + "cid": "bafkreidlwnin6u3lbb5me7gsaomtrz3xfxruteb3oqvng2isup6dq2md2u", + "time": 1710044316 + } + ], + "validationError": false + }, + { + "dpid": "191", + "owner": "0x371e269bff1aaA342b43b74Cf1Ad9789BaF183F7", + "versions": [ + { + "cid": "bafkreif7hsizhhb3pe5onhq7lnteu65c4wjdlhlh2yhokzsssnjiqhbizy", + "time": 1710848280 + }, + { + "cid": "bafkreif7hsizhhb3pe5onhq7lnteu65c4wjdlhlh2yhokzsssnjiqhbizy", + "time": 1710848496 + } + ], + "validationError": false + }, + { + "dpid": "192", + "owner": "0x371e269bff1aaA342b43b74Cf1Ad9789BaF183F7", + "versions": [ + { + "cid": "bafkreifup6tri42y77u4cyu5dtceve4hbesvkfhwod6cnlwnworm5kg5jy", + "time": 1710934908 + } + ], + "validationError": false + }, + { + "dpid": "193", + "owner": "0xec29aCa1a8740B8C5e2e06EBB52290700B9a2c40", + "versions": [ + { + "cid": "bafkreibs5jouyrflaifdy5h46qcao4ifl6k2uxkkdbjjhztowrzrdi7uey", + "time": 1711110348 + } + ], + "validationError": false + }, + { + "dpid": "194", + "owner": "0xec29aCa1a8740B8C5e2e06EBB52290700B9a2c40", + "versions": [ + { + "cid": "bafkreie4ql2xrlaaa3gydydecs62q6llw6ph3nql4wtv4vrvk7qlry5mii", + "time": 1711112832 + }, + { + "cid": "bafkreie4ql2xrlaaa3gydydecs62q6llw6ph3nql4wtv4vrvk7qlry5mii", + "time": 1711112916 + }, + { + "cid": "bafkreie4ql2xrlaaa3gydydecs62q6llw6ph3nql4wtv4vrvk7qlry5mii", + "time": 1711112964 + }, + { + "cid": "bafkreie4ql2xrlaaa3gydydecs62q6llw6ph3nql4wtv4vrvk7qlry5mii", + "time": 1711113060 + } + ], + "validationError": false + }, + { + "dpid": "195", + "owner": "0x4d0EC1B776aE7d57AFa42294cd6F5fa8Ab659819", + "versions": [ + { + "cid": "bafkreigl33hhuzyxtipdx26wsu4u775m47ceu7aryim3dbkquzxdzxw2cm", + "time": 1711250184 + } + ], + "validationError": false + }, + { + "dpid": "196", + "owner": "0x4d0EC1B776aE7d57AFa42294cd6F5fa8Ab659819", + "versions": [ + { + "cid": "bafkreicrbew4z2xa5msag2xqluych2cqvu4q37if7c4myrlgrso7clyr5m", + "time": 1711283700 + } + ], + "validationError": false + }, + { + "dpid": "197", + "owner": "0x711E9b9e8aD75CBD3AC024a8e4Aeeff59AfBae6c", + "versions": [ + { + "cid": "bafkreihzdyg7sncus6iiyywrmq3ieg6jpanwhopp3nermvdbj6twldqz4a", + "time": 1711484460 + } + ], + "validationError": false + }, + { + "dpid": "198", + "owner": "0xDAF8752DDcCE8a6B709aa271e7Efc60F75CDDF64", + "versions": [ + { + "cid": "bafkreifnbtsbubgr4igy3d2bdfm3t7wglonaefcpb6hltgx5ddemoirxbq", + "time": 1711485360 + } + ], + "validationError": false + }, + { + "dpid": "199", + "owner": "0xE713c665AC962155Ce2230b67034FBbc68Aa001E", + "versions": [ + { + "cid": "bafkreidrgw7m3dqhrhtkv3oof2tbuyaspmo3j7mfbyt4mcoiwsfzrelntm", + "time": 1712586828 + }, + { + "cid": "bafkreie6idsoipa3agkyg3widjx2qkqhyqesw7a4inbtf3v5bjwqmgvbu4", + "time": 1712746296 + }, + { + "cid": "bafkreifxbvttafs77huxssiyh7cia2aeds44qn7u3i6mo37rv5ok4n3yx4", + "time": 1712849196 + } + ], + "validationError": false + }, + { + "dpid": "200", + "owner": "0xb7633a1C95CDeFf14Fe90A18C61eA2EeA56ADd6F", + "versions": [ + { + "cid": "bafkreibr74kptq3taaq6vkk5ncliqjlaxfudeteoapwfj5dbk7lvabpa7a", + "time": 1712589912 + }, + { + "cid": "bafkreiehg2co367mlvhwga322q27m6k6ed3cll3jfhbeotrjr5uji4vuvy", + "time": 1712590308 + } + ], + "validationError": false + }, + { + "dpid": "201", + "owner": "0xbC4f75a4579c55B3b347C316159e03Ad9A233346", + "versions": [ + { + "cid": "bafkreigaex4kn6t5jtwjvfg6fhvu5ernugv4c2oyijj5c6sitlp7feyz4i", + "time": 1712699136 + }, + { + "cid": "bafkreibbutjlx6mftck5cdrghtnec7pupin5tmocw3jjnltk5b6ymepreu", + "time": 1712758008 + }, + { + "cid": "bafkreiasprpssrqrmt6csyxvp6h2hosczpnuhy5yet3ebdmp44nwqmnnxa", + "time": 1712910312 + }, + { + "cid": "bafkreiaml7ltpqcdawuri4pgze6lwst74dlwkkrxvu7ycxwcmucm54pzw4", + "time": 1712924748 + }, + { + "cid": "bafkreie44bdq6au5k544axgyh3t5u557sgojmk77jo6iebd2nuxdoboale", + "time": 1713181740 + }, + { + "cid": "bafkreifz6sboaziz6ozlws755w4xfa3agxerpcqfz2x3tyzpardhte57lu", + "time": 1713202788 + }, + { + "cid": "bafkreieebhdtnluia3gdhpi7cm3gskmnytq2vfmgi6mc7hkv3kqakcjqku", + "time": 1713210492 + }, + { + "cid": "bafkreicazrs2upqf67gb5z57oyoqd5p2ffsn3w4m4mpib5ttk4skwsoha4", + "time": 1713820044 + }, + { + "cid": "bafkreif33f5fja4xlt5hfng7au7u56pqxmhq7cwbsqqbo74kvh4dfmzt3a", + "time": 1713876336 + }, + { + "cid": "bafkreiffrskcqxf6sxlgi4vyfc6i7ppvsqd6fak5fr5azzxwurobetsvtm", + "time": 1713910788 + }, + { + "cid": "bafkreiffrskcqxf6sxlgi4vyfc6i7ppvsqd6fak5fr5azzxwurobetsvtm", + "time": 1713912876 + }, + { + "cid": "bafkreidymyibcfrjg6gjfdwdrsfxt2veregxrbxeilcqwawz5jstr2wgje", + "time": 1713966252 + }, + { + "cid": "bafkreiczragradkmshlydspr2hbkuj2ze5jptfrvh3ahygx2fvwxmx3eia", + "time": 1714743048 + }, + { + "cid": "bafkreicwl624bosttcswwvtkyisg2uqs2c5n65rsakaxa4c56xlxqwbnc4", + "time": 1715089932 + }, + { + "cid": "bafkreibomeyu2ha74ghyeargxgmne3zccrq3laf2hl5moilp62u5imaktq", + "time": 1715093316 + } + ], + "validationError": false + }, + { + "dpid": "202", + "owner": "0x371e269bff1aaA342b43b74Cf1Ad9789BaF183F7", + "versions": [ + { + "cid": "bafkreiblksmeh2h2rukdd3yyw2qpm2fspl233fccd3dmnjycukacslxtlu", + "time": 1712828544 + } + ], + "validationError": false + }, + { + "dpid": "203", + "owner": "0xbC4f75a4579c55B3b347C316159e03Ad9A233346", + "versions": [ + { + "cid": "bafkreieyuphulyypkgqyrenp5bsa4fmhdyjm6sxupuazdzdjr7bck3b6t4", + "time": 1712905908 + } + ], + "validationError": false + }, + { + "dpid": "204", + "owner": "0x29E9454e1Ee1bAf582403E1Dd3352134b044d6c6", + "versions": [ + { + "cid": "bafkreia3hv332uc5hjtjufiaptgqccnirp6glgqlp3kkmqqxzckk2wtque", + "time": 1714895436 + }, + { + "cid": "bafkreia3hv332uc5hjtjufiaptgqccnirp6glgqlp3kkmqqxzckk2wtque", + "time": 1714899456 + }, + { + "cid": "bafkreicedcwhhshszz4yorw4dsc67juu4eywrkfr2viacv3awmcvt7xroi", + "time": 1714902324 + } + ], + "validationError": false + }, + { + "dpid": "205", + "owner": "0x5249a44B2abEa543b2C441AC4964A08deB3Ed3CB", + "versions": [ + { + "cid": "bafkreihjkupfxvnrf5rgtwrrwacpatea6p6rfkpptk7tbyqug2yey56vmm", + "time": 1714902900 + }, + { + "cid": "bafkreifj7ps2uj2ovgbdx73j2rjrdgbsv5v52vsqbku73jk57mfo36e4ea", + "time": 1715097528 + } + ], + "validationError": false + }, + { + "dpid": "206", + "owner": "0x42d4fF8298dfcDCbb70823B146D0a1a3AF128a45", + "versions": [ + { + "cid": "bafkreibwzk6k24vak2utess6b4g3ymvoduf2wmmjq5ckp74zffetkvtp7y", + "time": 1715105532 + } + ], + "validationError": false + }, + { + "dpid": "207", + "owner": "0x29E9454e1Ee1bAf582403E1Dd3352134b044d6c6", + "versions": [ + { + "cid": "bafkreifsokpngt7o5nnf3svrjwq52a4jfmpsbo5dxrtfu7gxutn5b35zdq", + "time": 1715324136 + }, + { + "cid": "bafkreief5hvxfazsnkfzeuebbbyrqgrncfvzs62ixodku5bd2es7dxafmy", + "time": 1717411476 + } + ], + "validationError": false + }, + { + "dpid": "208", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreiecniqyzhz3ydgr6qalq2v64cptmc75ziriagcqumrg5mmldqs6ui", + "time": 1715706588 + } + ], + "validationError": false + }, + { + "dpid": "209", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreibcnzl5mhvil6ossyaldtmhvci3pgrop34rodde6nsqo4seymk35u", + "time": 1715754924 + } + ], + "validationError": false + }, + { + "dpid": "210", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreice6ojx5rphjrv3ghcwpmyceb4ftvogpjgueis7oysx4iwofux7tq", + "time": 1715756148 + } + ], + "validationError": false + }, + { + "dpid": "211", + "owner": "0xE713c665AC962155Ce2230b67034FBbc68Aa001E", + "versions": [ + { + "cid": "bafkreifxkw7fxmqs73xjkvpqib25ogct6sh7j5ult7ouemn27eyus6vteq", + "time": 1715758284 + } + ], + "validationError": false + }, + { + "dpid": "212", + "owner": "0xE713c665AC962155Ce2230b67034FBbc68Aa001E", + "versions": [ + { + "cid": "bafkreibd6z4ez67iorgtngwjgyzunrfafqp6ckd4rzxqcdkldsynzircbq", + "time": 1715758332 + } + ], + "validationError": false + }, + { + "dpid": "213", + "owner": "0xE713c665AC962155Ce2230b67034FBbc68Aa001E", + "versions": [ + { + "cid": "bafkreiftabtiwceukykjj7djbll6o7vj2b5nqljq2ayqos7a4q5bfj26qe", + "time": 1715759052 + } + ], + "validationError": false + }, + { + "dpid": "214", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreib4lne5chotkvctuooguqtknxwcu62tcg2f3czrhekq55yopr326y", + "time": 1715759664 + } + ], + "validationError": false + }, + { + "dpid": "215", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreidlca6x7or4cu26j42ujpauito7lu36sgrnkzikwtbblhxxj7ou5q", + "time": 1715783532 + } + ], + "validationError": false + }, + { + "dpid": "216", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreidxpaqx4emlzuyny7nwptse7v43fnldv6scxwerzf52ifwtj2zpmq", + "time": 1715846040 + }, + { + "cid": "bafkreidxpaqx4emlzuyny7nwptse7v43fnldv6scxwerzf52ifwtj2zpmq", + "time": 1715846232 + } + ], + "validationError": false + }, + { + "dpid": "217", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreielmjyyh4huzlvdfq5zpkq4yfynqkir7nzyw2hraph34z6pk6vpta", + "time": 1715852172 + } + ], + "validationError": false + }, + { + "dpid": "218", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreial2hxxfcpzkm474ommsvbywgkoz7giyai5y2vnzt2yuswt3qwvhe", + "time": 1715852724 + } + ], + "validationError": false + }, + { + "dpid": "219", + "owner": "0x42d4fF8298dfcDCbb70823B146D0a1a3AF128a45", + "versions": [ + { + "cid": "bafkreih5rxnqa74dgehy5vlzf2c3bjpdd4d37wjsmd6umklvtpravrymii", + "time": 1715852904 + }, + { + "cid": "bafkreif7bdndzubravkpbgllcz2uejzxvuagbrxw4kg3afvzqcz5u2epji", + "time": 1715853012 + } + ], + "validationError": false + }, + { + "dpid": "220", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreihdis2gtow2vyjw3lfrrk75nwhimvr3mol5tw2yg5m6yb4qkfzusm", + "time": 1715853288 + } + ], + "validationError": false + }, + { + "dpid": "221", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreieykztli6himlvsp66y4eq5e6olhmd57mq3ff7q5lpkl3h57gdzhy", + "time": 1715854884 + } + ], + "validationError": false + }, + { + "dpid": "222", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreigduiq7h6qo3eszrpbgfaxllcboxxa7isr35ajf3qkax2522stlhu", + "time": 1715857896 + } + ], + "validationError": false + }, + { + "dpid": "223", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreifz5uvrar2vdxtcmd2sh3xhibyansyg2joqmnclce6spwopswo7qm", + "time": 1715858892 + } + ], + "validationError": false + }, + { + "dpid": "224", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreihjdwdspwjdptweikwbzpzthv2b3vkaablm6yrgzg2syf34ay5zo4", + "time": 1715858988 + } + ], + "validationError": false + }, + { + "dpid": "225", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreibd4v3nmp6n652mrgmuha6q65cul6pq625gzirsrka4wiftdrbxkm", + "time": 1715859360 + } + ], + "validationError": false + }, + { + "dpid": "226", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreicikabkude4odfkc3h55d7tbma527qzcbq5f7urusu2f65jy2qdr4", + "time": 1715862000 + } + ], + "validationError": false + }, + { + "dpid": "227", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreickxvmqpwkg3hoiqaibcsz5mxgcquhoivflzgqloupgfvgxiahgmm", + "time": 1715862264 + } + ], + "validationError": false + }, + { + "dpid": "228", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreigpxc4535atofw53qhlwy5ljmku7cgvi64yzohjaqllh63e75iigm", + "time": 1715862396 + } + ], + "validationError": false + }, + { + "dpid": "229", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreibyqg4efuc4je3szq6augfzrlknk4kyo56jvmtlv6v3u34olfjw5q", + "time": 1715862828 + } + ], + "validationError": false + }, + { + "dpid": "230", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreice2sc42ahkjmt2fdkgrdgbpr2jbb462swclyamdykpc6guyigg3e", + "time": 1715863632 + } + ], + "validationError": false + }, + { + "dpid": "231", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreihdynlkgw62oeknjc6cpbibmk6hmql46haes3sw77twqxzxj4p7dy", + "time": 1715863932 + } + ], + "validationError": false + }, + { + "dpid": "232", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreidbb6rj2zcaufmhdqf2ioqa4ub573fsjwve3xsqtihz4t2mu7mfvm", + "time": 1715864112 + } + ], + "validationError": false + }, + { + "dpid": "233", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreih3wosdxfpkdajepb6fr6mpnbzotvx3757aapwh5jc4uj5ki4nsb4", + "time": 1715864796 + } + ], + "validationError": false + }, + { + "dpid": "234", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreieaqwjyk5oueqxkhoqbmh4priqdl2d5htgyp7euofym22t2vup2n4", + "time": 1715864856 + } + ], + "validationError": false + }, + { + "dpid": "235", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreicegqhkh77pjlaffif4jptccfjcug4x2v6uzkuhgzk7mvkp3h3pje", + "time": 1715864988 + } + ], + "validationError": false + }, + { + "dpid": "236", + "owner": "0x371e269bff1aaA342b43b74Cf1Ad9789BaF183F7", + "versions": [ + { + "cid": "bafkreiaovnmdbwprrbe2ol5wmsiohpepr74eobdzp7mnhmolazca6rmk3u", + "time": 1715945640 + } + ], + "validationError": false + }, + { + "dpid": "237", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreia5h5rgnj3tckolwznad5ufivrdkrfcwwb7ybvhauqy3tpvsanxbe", + "time": 1715966676 + } + ], + "validationError": false + }, + { + "dpid": "238", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreihna43pr26bwxltihgzpby4pfamdojeyuusiikodzsfx2cx4nizwi", + "time": 1716044616 + }, + { + "cid": "bafkreiawwiamv3sm7ujwtusakl33ncwprbmvgqygsugcjc63e57o4qedrm", + "time": 1716195456 + }, + { + "cid": "bafkreifsn65szz2c7oigkpaj7zf5vveme2bdvyimhikvcthzpfamx4amqa", + "time": 1716195624 + }, + { + "cid": "bafkreiffpqp5eqhtb5twcggyfdwxd6zciqqrm43356m5g64tkozw6ox2um", + "time": 1716196968 + }, + { + "cid": "bafkreibhvf342535vnaxqpjvapnfvuh563g6fqq26ifmmks3edyig2bqje", + "time": 1716197688 + } + ], + "validationError": false + }, + { + "dpid": "239", + "owner": "0xbC4f75a4579c55B3b347C316159e03Ad9A233346", + "versions": [ + { + "cid": "bafkreida4e3jtx44nqujveh7qstktsiwvmgvqvdrxfp6oxwtgtj3yt7rtq", + "time": 1716299616 + } + ], + "validationError": false + }, + { + "dpid": "240", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreicc35sby7tw62yixogr7cdyb74ogud2oks7ucxoqm2dxl2ns7iqxe", + "time": 1716455376 + }, + { + "cid": "bafkreih4fwgcdcuanlvqrfe23gtssi2ry5qn5aiartyyxnrgwie47vogjq", + "time": 1716456924 + }, + { + "cid": "bafkreibmiu4or57a3zt2oqwpyo55sxilbohbekoio7ar6xctre4rplmctm", + "time": 1716457200 + }, + { + "cid": "bafkreig2frbnikhvo7ybhocvvtcxemjqjkzausxmea75mj4yes4vrh3ly4", + "time": 1716457332 + }, + { + "cid": "bafkreibrhymhxsjll5amkbh4xqpi3ndr5bp5lbs6vs5x43aqzdynbzrlxa", + "time": 1716559284 + }, + { + "cid": "bafkreidwe7ueatapvutqf34m6sdvqt2deyhmzgnkme45filbvjxcqhnhya", + "time": 1717161096 + }, + { + "cid": "bafkreiaipcdk567t72ftbuvqeuyec64zw57ed4ttaftjazoy3how25y254", + "time": 1717161504 + }, + { + "cid": "bafkreiglntmzkq4nhkaqjkukhdyngilz33lmqmlclyeich6kbx6h5cayau", + "time": 1717393608 + }, + { + "cid": "bafkreiefx4s7oqovph4lyzx53gwki53jgb3dikvp43ccdiraviw5wks7aq", + "time": 1718458956 + }, + { + "cid": "bafkreiablucsqmv2wvztfpvfnkk5fm5ep5m4ebzwkfl23yjhsndb7u3gau", + "time": 1718461368 + } + ], + "validationError": false + }, + { + "dpid": "241", + "owner": "0x51A257aAF108c9b0A3e140519bD14e5B4bf15e47", + "versions": [ + { + "cid": "bafkreici76b6bx7smkkihhzjpv7hj26q4uowye5vnmia36gn6lkaa65f6a", + "time": 1716458616 + } + ], + "validationError": false + }, + { + "dpid": "242", + "owner": "0x29E9454e1Ee1bAf582403E1Dd3352134b044d6c6", + "versions": [ + { + "cid": "bafkreibzcu3iwi7buqwy2ibujh2sbe4gmbyhycil7w4xeuvldsa2mrbypy", + "time": 1716464784 + } + ], + "validationError": false + }, + { + "dpid": "243", + "owner": "0x008292E57A2d9B34525d82876068652e639e61D8", + "versions": [ + { + "cid": "bafkreiaxbwjw2cp7mvfaul4xlxkguafmfkxxhym7ik5bty7dfehxff3tgu", + "time": 1716551616 + } + ], + "validationError": false + }, + { + "dpid": "244", + "owner": "0xb4096E016F162d10EfC8C20F8Db22a54D80935c8", + "versions": [ + { + "cid": "bafkreiflayannh3vsjxn2khne5gjtupt3mtso4rd6x4dnmfh3rhxzkvhfm", + "time": 1717158900 + } + ], + "validationError": false + }, + { + "dpid": "245", + "owner": "0x371e269bff1aaA342b43b74Cf1Ad9789BaF183F7", + "versions": [ + { + "cid": "bafkreic56m4scp5t7fdb2zajue3tupjevoxlwaly2skqbdbncy5zbydike", + "time": 1717159332 + } + ], + "validationError": false + }, + { + "dpid": "246", + "owner": "0x42d4fF8298dfcDCbb70823B146D0a1a3AF128a45", + "versions": [ + { + "cid": "bafkreib23oradn74sxmdji6ofw4iffliheytyq7kq3ge3bnz2tooz764cu", + "time": 1717160400 + } + ], + "validationError": false + }, + { + "dpid": "247", + "owner": "0x371e269bff1aaA342b43b74Cf1Ad9789BaF183F7", + "versions": [ + { + "cid": "bafkreiakdqljwmvvzkmwjrgkto4meyyghrl3tigocnoapejdquuiigy2si", + "time": 1718012544 + }, + { + "cid": "bafkreiehku747l4loyvugbfby55tig4qjgyj66ujbcpuohucktx6dg72k4", + "time": 1718015760 + } + ], + "validationError": false + }, + { + "dpid": "248", + "owner": "0x371e269bff1aaA342b43b74Cf1Ad9789BaF183F7", + "versions": [ + { + "cid": "bafkreic65zfq5ryxtmxtei3264qafrmcdyysxnmxl2krldoaitrjymogta", + "time": 1718017368 + } + ], + "validationError": false + }, + { + "dpid": "249", + "owner": "0x29E9454e1Ee1bAf582403E1Dd3352134b044d6c6", + "versions": [ + { + "cid": "bafkreihriifz5cqqdfrw2ujetfvcqdpgtpggjoqnp6tbj5y5lmveyz3bbm", + "time": 1718720688 + }, + { + "cid": "bafkreihriifz5cqqdfrw2ujetfvcqdpgtpggjoqnp6tbj5y5lmveyz3bbm", + "time": 1718720964 + } + ], + "validationError": false + }, + { + "dpid": "250", + "owner": "0x42d4fF8298dfcDCbb70823B146D0a1a3AF128a45", + "versions": [ + { + "cid": "bafkreibibwtxsjbc7yy55uzezyt47b6hr3tkkpawchcckm5xwv2pdbxfxe", + "time": 1718864520 + } + ], + "validationError": false + }, + { + "dpid": "251", + "owner": "0x42d4fF8298dfcDCbb70823B146D0a1a3AF128a45", + "versions": [ + { + "cid": "bafkreielbfrhhntmclgpnlamnx3rxnmmnqape5cshvdh5midwpdvkwodui", + "time": 1718883600 + } + ], + "validationError": false + }, + { + "dpid": "252", + "owner": "0x42d4fF8298dfcDCbb70823B146D0a1a3AF128a45", + "versions": [ + { + "cid": "bafkreicfnp7rt3uez2ououz26l7y5ydhfqwsttvx4nlbcjtlytvjzmerka", + "time": 1718886312 + } + ], + "validationError": false + }, + { + "dpid": "253", + "owner": "0x371e269bff1aaA342b43b74Cf1Ad9789BaF183F7", + "versions": [ + { + "cid": "bafkreieb3nnzilijzawo4uyzxwrqhhgwxw34xgtyvdxgjedmdz36jhi2aq", + "time": 1718973660 + } + ], + "validationError": false + }, + { + "dpid": "254", + "owner": "0x42d4fF8298dfcDCbb70823B146D0a1a3AF128a45", + "versions": [ + { + "cid": "bafkreicurjfzvv7ab5bivgo5kkqpnx4xvtsozkaamjbnrasfbxcncrr73e", + "time": 1718973792 + } + ], + "validationError": false + } +] \ No newline at end of file diff --git a/desci-contracts/migration-data/aliasRegistry_prod_Tue,_25_Jun_2024_08:36:06_GMT.json b/desci-contracts/migration-data/aliasRegistry_prod_Tue,_25_Jun_2024_08:36:06_GMT.json new file mode 100644 index 00000000..81d36d14 --- /dev/null +++ b/desci-contracts/migration-data/aliasRegistry_prod_Tue,_25_Jun_2024_08:36:06_GMT.json @@ -0,0 +1,3200 @@ +{ + "address": "0x935e08ce8AFdefa17CD1579f5a3CD31224e47456", + "dpids": [ + { + "dpid": "0", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreie2idd2yuwibppujafgtfc6cczopht4q47y563q4paml2me2dsh6y", + "time": 1675737468 + } + ], + "validationError": false + }, + { + "dpid": "1", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigbp7bahnrxujbz5uu3j6hzmyimq7wijkucwyi4bc5tbvka5xw3wq", + "time": 1675781796 + }, + { + "cid": "bafkreigwzsizb76b62ln5xnhhqeypxhyqwwyp56zcprl52siut2q7h2lky", + "time": 1682818404 + }, + { + "cid": "bafkreigwzsizb76b62ln5xnhhqeypxhyqwwyp56zcprl52siut2q7h2lky", + "time": 1682818608 + } + ], + "validationError": false + }, + { + "dpid": "2", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihlsxjw3gzrikm2att6sd2yty4qx37z3fgmzokrm6fd3oony2qqby", + "time": 1676095440 + }, + { + "cid": "bafkreigvalv7basyqxn57b5ittssieecsccy7qaypmy6s7egr2o5tcqnda", + "time": 1676096820 + } + ], + "validationError": false + }, + { + "dpid": "3", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiancsq3yywjzkoyevwhn4hxyzgcfbdb72jspegmwy6uacd2cztpra", + "time": 1676725008 + } + ], + "validationError": false + }, + { + "dpid": "4", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreick32zk4ennjwwy7vqva7wpjo2w5d4fkwhg7hkrdjk63xq5r6gup4", + "time": 1676988612 + } + ], + "validationError": false + }, + { + "dpid": "5", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihra4e2ejsm7yqra4wmo2ww43j4ndvylfsrv5obobkl2k666baram", + "time": 1676996292 + } + ], + "validationError": false + }, + { + "dpid": "6", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiee7atuqdvq7dtxf2msslelz2ubst2g64oigetxunn352ryqvuoti", + "time": 1677066240 + } + ], + "validationError": false + }, + { + "dpid": "7", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidi2idvbbbg5y6iuf3bnbdo7gkyzgoz3hik2hghr3rl3gd7nplnwe", + "time": 1677080820 + }, + { + "cid": "bafkreicyvzgk632l2zn55dkbscjrwrlrxlckrxjhpxn6kiv4roegwzprpi", + "time": 1677081012 + } + ], + "validationError": false + }, + { + "dpid": "8", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibnhuq4tliestyutqxrfco4wwr3gxyrp7dlydxvgkddo6euet5yyu", + "time": 1677144720 + } + ], + "validationError": false + }, + { + "dpid": "9", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigjjlyedw3l7yfunjhaooe226hemiqz7pkeqb3arfmwvujknaa7pe", + "time": 1677230328 + } + ], + "validationError": false + }, + { + "dpid": "10", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihbcdgctujsajvlhbbcghfkg766pprlgatvujzkw6utteryn737wi", + "time": 1677510672 + }, + { + "cid": "bafkreif6omh6d2nosj7exr4gybupz3i6owb7ig7mfha23bebzbbzgtj3ty", + "time": 1677511224 + } + ], + "validationError": false + }, + { + "dpid": "11", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreig75cxpsu2zhnkej7nwqszduw6l32luo3opikzsqa5wpfchnl7sua", + "time": 1678309056 + } + ], + "validationError": false + }, + { + "dpid": "12", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigvec6jtxth3eessemov7x62wjhtfpfihdleanekwx5l47rkxclcu", + "time": 1678771692 + } + ], + "validationError": false + }, + { + "dpid": "13", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreienztazc23yp5ejvwymgekqf2kmx6foasxul7yzt6w5crjwceqsea", + "time": 1678814328 + }, + { + "cid": "bafkreid4yx77dkhlbmx2gqwwki6y2rjmuybnqkxqmxnoyjtx7uhgdkdeu4", + "time": 1680117252 + } + ], + "validationError": false + }, + { + "dpid": "14", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiasx7tcckutok7a7yk7ej2pv6bolo5naihlk2gny6tpykcfvzxqm4", + "time": 1679014104 + } + ], + "validationError": false + }, + { + "dpid": "15", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifjuqlmsnnr2vlhwxrjsgu5zczwgodqjuzmo4kzgpzzu5zn42ivby", + "time": 1679219244 + }, + { + "cid": "bafkreiar3d6vkcyvfnk7kfhu4yrvul6hsn4fnjrwgq7wbl27t4e3ehfhwq", + "time": 1679219328 + }, + { + "cid": "bafkreiar3d6vkcyvfnk7kfhu4yrvul6hsn4fnjrwgq7wbl27t4e3ehfhwq", + "time": 1679219484 + } + ], + "validationError": false + }, + { + "dpid": "16", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreig27rnst73rqnqgtesyo32xhrhaqtdxbvtdohwnjdzua7cyapghbu", + "time": 1679343324 + } + ], + "validationError": false + }, + { + "dpid": "17", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigggibyev5x4w3tcydslfl3j5g2fl2sabfcxvdzqeajzfg3tqignq", + "time": 1679409324 + } + ], + "validationError": false + }, + { + "dpid": "18", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigghoctitgbpsjl6elgjkdlpu26t6zon7gqfx7cuhprsyykcjgvee", + "time": 1679409744 + } + ], + "validationError": false + }, + { + "dpid": "19", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicvdmmzw7tyaa7dkaikb7dcowjjbu3cv76rhvxqdbzm7gcg4inrfq", + "time": 1679539764 + } + ], + "validationError": false + }, + { + "dpid": "20", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreie6bxf7u3z45sn2amk7ocsjihloiecfncmwsgvqoamqjnczfwnexy", + "time": 1679540424 + }, + { + "cid": "bafkreibnxznsx2xwdasyhjr2epkypjohuvz5qy35iu2elyoygjnfbk7im4", + "time": 1680554796 + } + ], + "validationError": false + }, + { + "dpid": "21", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiecholb67ldemsvyr7js2x6dewjnsylvpk47ejyhrokkbnqbl4i4y", + "time": 1679637204 + }, + { + "cid": "bafkreih6jpxxvs5ruwhfms7t4kg3qv27x6cf4qn7rzoffcjhgctjjcn7my", + "time": 1679637252 + }, + { + "cid": "bafkreih6jpxxvs5ruwhfms7t4kg3qv27x6cf4qn7rzoffcjhgctjjcn7my", + "time": 1679637288 + } + ], + "validationError": false + }, + { + "dpid": "22", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreid4d4543faobctzfxh53tfa7u2q7jwqll7g3o52b6ko2vxbq6gya4", + "time": 1679658768 + } + ], + "validationError": false + }, + { + "dpid": "23", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifzp4vuudwvek33rcft2rd2szjrimey7yezcsbm2awkx2tjsunwwi", + "time": 1680567024 + } + ], + "validationError": false + }, + { + "dpid": "24", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicqcgfswelv7jvt3o5mirsrwbegst354jzl5znfhsysfi5kwa5oem", + "time": 1681191960 + } + ], + "validationError": false + }, + { + "dpid": "25", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiai7ekqchod7c7na6bsc5aeicugtqr2ai4jhdyjal4ukzzjdoxdoi", + "time": 1681495752 + } + ], + "validationError": false + }, + { + "dpid": "26", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiasg744hrz2h6tkkw4a2z55orh33v5rs2j62mx3arsuqxa5dppyzq", + "time": 1681497684 + }, + { + "cid": "bafkreicbh5ytfk7ohfa7tw44q5nmjkzmqseiesoskwcjntwc6apx7ifyyi", + "time": 1681497900 + } + ], + "validationError": false + }, + { + "dpid": "27", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiehj4xqrpk5m6sdemt5nv6ktb5uxp6ihmg3apdwiu6xhkjzlcmuka", + "time": 1681505184 + } + ], + "validationError": false + }, + { + "dpid": "28", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihmuuks36pyt5quuvjbxkhyu6lhdf3sfbqvfii6j2gemwpu2uc67q", + "time": 1681506588 + } + ], + "validationError": false + }, + { + "dpid": "29", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigifwmh35byvn2yzg2vojm6r6qpjyoce6dfdsacmch336adgqmyee", + "time": 1681736556 + }, + { + "cid": "bafkreicxifdkouaya7pzrj2upqft2c637t6awklqjsbd76dfog42hxvlqu", + "time": 1681736628 + } + ], + "validationError": false + }, + { + "dpid": "30", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidtjqvqyoq7ehafmy7vvhjlewgtxkxaqr7anwtwtgkzvlogmfwaey", + "time": 1681761420 + }, + { + "cid": "bafkreif6imae7ikphst6f2opahy2bn4qnm3srzj4rmnpdhrqtykwr6c4yu", + "time": 1681762272 + } + ], + "validationError": false + }, + { + "dpid": "31", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiahcqh7zzoz27gzh2chwto2u5kabmf2vmca3xbmzrlmgoqucrmfky", + "time": 1681805808 + } + ], + "validationError": false + }, + { + "dpid": "32", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiaakpmpc5jr4bp3puzzpdjv5nh3maunzbaug2p335ngmdfsfekkxe", + "time": 1681830960 + } + ], + "validationError": false + }, + { + "dpid": "33", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreic2zkjdknqf5kfelzzstfovdwuc2dolbaej7eduedn6md7rpfo27y", + "time": 1682014560 + } + ], + "validationError": false + }, + { + "dpid": "34", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibkbhhedb3yazc6rze6772ouoymv3yy5vqmilmwi6eq7yuw3n6tue", + "time": 1682144088 + } + ], + "validationError": false + }, + { + "dpid": "35", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreih4kylr5z5oppj6wprw2luiyngsn3xq324kfbiku4ehi42dess4oi", + "time": 1682534976 + }, + { + "cid": "bafkreidasu577tdw76nprafzy7oa42nlr6gcyk45agx3tawrw3zyxu7mva", + "time": 1682746284 + }, + { + "cid": "bafkreieaozkgywz6vonai3kmhr6cct5jjpeau3lhy2zrb2ft3dsnudaxym", + "time": 1682813004 + } + ], + "validationError": false + }, + { + "dpid": "36", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifc4so5xny7vpkj62oejlxlnh2zp6w76idbvx3mi2t5nkhxpbenbe", + "time": 1682670864 + } + ], + "validationError": false + }, + { + "dpid": "37", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiadoa3b3hvlzpfliappjvhzoacqst2tnu5x7cjvhwcdjhplqakmmy", + "time": 1682793228 + }, + { + "cid": "bafkreiad7vwyvhxpgy5i6azrynsnu5g2x5ef7iwjafbnnvukkbc7dvygru", + "time": 1682793408 + } + ], + "validationError": false + }, + { + "dpid": "38", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiagyoholq6ypx4pdby56vfzq7a44q3sn6esvho7wcf6m4eghpcjoa", + "time": 1682813880 + }, + { + "cid": "bafkreiapfszw7l5sysx2hgophrztwyeonpppem2xxwbujhhwa5kipypyky", + "time": 1682814000 + }, + { + "cid": "bafkreiapfszw7l5sysx2hgophrztwyeonpppem2xxwbujhhwa5kipypyky", + "time": 1682822136 + } + ], + "validationError": false + }, + { + "dpid": "39", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiayluo2hglsq2qfahpzwqopgwaad7bqxma5we6l2bqzs2zfvk6eka", + "time": 1682820648 + }, + { + "cid": "bafkreiayluo2hglsq2qfahpzwqopgwaad7bqxma5we6l2bqzs2zfvk6eka", + "time": 1682821080 + }, + { + "cid": "bafkreiero2ggetbv2g5voe4yg7lr53cl7aocrcdbn5ndz754ani2c4xwye", + "time": 1682849124 + } + ], + "validationError": false + }, + { + "dpid": "40", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreih3uvxd3entelbnsrhijwkperswmy4d27cjvx2fnurjqqjzvp7v54", + "time": 1682821224 + } + ], + "validationError": false + }, + { + "dpid": "41", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihesv24wbwkhgjeplqi7lu2rm5d75o6es3krxbj4rfmhk3bcxavhe", + "time": 1682854224 + }, + { + "cid": "bafkreifmd5ucm3ypfkph7klhghsgyvfinkrwxw6uuiwpdjoarmxotflwaa", + "time": 1682854344 + } + ], + "validationError": false + }, + { + "dpid": "42", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreie46ed23xpsfgxasdbhzq4zrni5v4dv3lbohasnqkgmohq4g6bjam", + "time": 1682856480 + } + ], + "validationError": false + }, + { + "dpid": "43", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigumcdo4dafutywplrgg7xgo6swf2qygljyzwktsafuhvednvpmhy", + "time": 1682951112 + } + ], + "validationError": false + }, + { + "dpid": "44", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihqpbdqrgnp6mebwfcqqt3izgreiw4zgiw42zmkezipmktv777itu", + "time": 1682962248 + } + ], + "validationError": false + }, + { + "dpid": "45", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihfrfianmcigzvnnetxkzwlcgza75dsah7ab5anx43phu3mke3uky", + "time": 1682993892 + } + ], + "validationError": false + }, + { + "dpid": "46", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreia2nvcwknooiu6t6ywob4dhd6exb3aamogse4n7kkydybjaugdr6u", + "time": 1683053508 + }, + { + "cid": "bafkreih5koqw5nvxucidlihwfslknj674oeuroclit74rkaqpe4mq6xuka", + "time": 1683222132 + }, + { + "cid": "bafkreif3d644utirvwvkmukcrhg64palp3r4xociwsn6b6o2hxmkdxalby", + "time": 1683227616 + }, + { + "cid": "bafkreibn3jhdlsdsonv25t7i2bwtrbkl3jzwjbnnwylpeih3jmmzdhsfmi", + "time": 1683298680 + }, + { + "cid": "bafkreiepot62powegf7tt73gyiz24facsdloywggattt2asz5y4eaqhkyi", + "time": 1683299940 + }, + { + "cid": "bafkreihge5qw7sc3mqc4wkf4cgpv6udtvrgipfxwyph7dhlyu6bkkt7tfq", + "time": 1705420740 + } + ], + "validationError": false + }, + { + "dpid": "47", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreia7orsrr4pwxe5m2gnklknpc25kjs7gnzemofki3aeh6ydh4hkfju", + "time": 1683222948 + } + ], + "validationError": false + }, + { + "dpid": "48", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreieahbi5tzb2od7nb2j5up4ooiglvh2lty2bgcrwjc3km7fnsplaxu", + "time": 1683232692 + } + ], + "validationError": false + }, + { + "dpid": "49", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiet6onaozwmqyflpbjsa7f6f5jkhou5n3vxxkxmkgalhnr54bzftu", + "time": 1683236460 + }, + { + "cid": "bafkreibp3hplo3b2hfetbrargv2gv2dkx3kfqfsqbxhkuved2k2nebxcpa", + "time": 1683236760 + }, + { + "cid": "bafkreigym3lzf2ruzd3r23mflxjzafqfxoi5bncru3t4ky35vfaubbke34", + "time": 1683236760 + }, + { + "cid": "bafkreife4uk2mkecur54sq774ybtrka5l4gd5777j5cjjscfmx4vcqnfbm", + "time": 1683237288 + } + ], + "validationError": false + }, + { + "dpid": "50", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibroag6m5tps4srrtdxbfq74sskvpfu4sbhadhkh3vfonjrlmsvda", + "time": 1683886968 + } + ], + "validationError": false + }, + { + "dpid": "51", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiheezwrynuxo6gnjd2pmahkcw3wstooxs6fvaflpjouewmh4qi3aa", + "time": 1683930000 + }, + { + "cid": "bafkreiasjo5wzkkk2s56tvdkmbe56vj4j7gyq345vnqpwvnvwozzhtkxfq", + "time": 1683931428 + } + ], + "validationError": false + }, + { + "dpid": "52", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicxw5tzwajvwa757ihut3hvlgnfbpu7fa4oxfvvlssu4rikfrtmv4", + "time": 1684412244 + } + ], + "validationError": false + }, + { + "dpid": "53", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreia7yjdhq6tdxjtwyr4ajfhxypq3jxbo5augryzzeos7cqrbyy6jmi", + "time": 1684862784 + }, + { + "cid": "bafkreifutouvscu3pbsaabgxdxqfd6zaphkcuei6i3fibdeefmrh4oujby", + "time": 1686612108 + } + ], + "validationError": false + }, + { + "dpid": "54", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigtfrsogce5ixgj4dvjgvj2qgjsujs5g4sa64svziiyz6j2bajise", + "time": 1685098464 + }, + { + "cid": "bafkreihocw2lexz7nz4sfwmy576guhbecxnzq4wfltnx5twqn2clng3ewu", + "time": 1685098776 + } + ], + "validationError": false + }, + { + "dpid": "55", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicup2qewrwovkkgk5bun4vpws7cbq3qnv2rbt7truyw54owvtwovm", + "time": 1685442360 + } + ], + "validationError": false + }, + { + "dpid": "56", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreieis5ac2evezkciy26fvswybmyyarfnrlvyh7p5acvbhcsceayorq", + "time": 1685444172 + }, + { + "cid": "bafkreid6ibvbiblu6vviuc3l6ivmpmpdbj2rzt625capmi4igns2r7k4ue", + "time": 1685448060 + } + ], + "validationError": false + }, + { + "dpid": "57", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiaulqrzufg3qnw55rwzqtn5h2cvsawdunrfwt4j32ywt6oswi5bfm", + "time": 1685525952 + } + ], + "validationError": false + }, + { + "dpid": "58", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidlxqbem5m3kgtntq6243vujhuyvt2s72ry2k5uy4f6hmjwbezdje", + "time": 1685526132 + }, + { + "cid": "bafkreib2gln7ztcpt6z7q7yo6isznl6lam4zv74hwslwhplh6g55re26lm", + "time": 1685536224 + } + ], + "validationError": false + }, + { + "dpid": "59", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigj2svt7njv2nxznzm42pisbjgpfjzhoorlcsryjlx5coa2klssku", + "time": 1685613060 + }, + { + "cid": "bafkreigvuao6ogwtnr2oknvxl3a5mtulhats7dqsiuturbxnnablevorai", + "time": 1685613240 + } + ], + "validationError": false + }, + { + "dpid": "60", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiefsjhlwr6bcq4nscdoz2q2tkca5i7ocxgtn5nxggkf2lr5a2z2lq", + "time": 1685613216 + }, + { + "cid": "bafkreifmohd57nd6xbcjrc3b6dxgpycgijleopks7hrmza4t23dvqxd2au", + "time": 1685613708 + } + ], + "validationError": false + }, + { + "dpid": "61", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreid5vwbe6ri74rgtdevbjznreexoedsocftjqgpopx3bih656jwzni", + "time": 1685614104 + } + ], + "validationError": false + }, + { + "dpid": "62", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiapjbbsrowag6txt3wuilla2vp6dhhijkylklmvdzc4es3qb27buq", + "time": 1685615388 + } + ], + "validationError": false + }, + { + "dpid": "63", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicjmhgi5sbjvo2i3nzwfkwfmahgipbyq6iasekibgqpl75cdiqdsi", + "time": 1685615724 + } + ], + "validationError": false + }, + { + "dpid": "64", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreib2rkswbatx7qqcnymxcajqrgrywfzlsiischsrfowhbd5vjfskfi", + "time": 1685719428 + } + ], + "validationError": false + }, + { + "dpid": "65", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifdylfaiep4lc4544mow5aiq4vg37buebiybfx5wyznfi4pov6qri", + "time": 1686220584 + } + ], + "validationError": false + }, + { + "dpid": "66", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibelil5fgqul2o3chxv7g7xmdqkv2krqkv6r6mdbiw72vcqp4wxky", + "time": 1687805292 + }, + { + "cid": "bafkreiefvtk6gcvlxq3hw3lkxcjjy5aqkaxyu4swucs2wd3imjhi2yfdpm", + "time": 1687805484 + } + ], + "validationError": false + }, + { + "dpid": "67", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiazlufpwemnsbzscuycou7gi5m7t2p4yxbxvozkvxex47uczuokba", + "time": 1687807524 + }, + { + "cid": "bafkreidupix2c3fizisuv2z6tluypvssf6solprgnmev6ul6vp6dprwop4", + "time": 1687808232 + } + ], + "validationError": false + }, + { + "dpid": "68", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihakt3w53hwvneg2o3e4xysgegwk5j5rs6mug6ywlwb2bmprm4wzy", + "time": 1687812132 + } + ], + "validationError": false + }, + { + "dpid": "69", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigfelcudmytsq2s2j4wcy3j7tsyatpnffpcthf6zz7q5wa4snafdm", + "time": 1687812804 + } + ], + "validationError": false + }, + { + "dpid": "70", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicandi5eh3gwuxwlq6k6fpeuurnbpbx33q3ijndg44go2p5ekni3y", + "time": 1687817568 + } + ], + "validationError": false + }, + { + "dpid": "71", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibb5g5ujmxeve56ktnuolb7rrncmbgedtrjemeshn6rxbrhn4uepe", + "time": 1688024628 + }, + { + "cid": "bafkreiddtartrk6isrs3j5ltx6nkcv437jsu62vc6ew3cwvxk3msebzg5e", + "time": 1688024676 + } + ], + "validationError": false + }, + { + "dpid": "72", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicj4c44gghcoy2ztvwe32fmbv7cuvty2hv2y4ndrnd6ghrl3ciaea", + "time": 1688552688 + } + ], + "validationError": false + }, + { + "dpid": "73", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifdgjfu3g4qddc7g5kvnk3lshkuyfau7o2qle5ut5msptulbxsqme", + "time": 1688720808 + }, + { + "cid": "bafkreifdgjfu3g4qddc7g5kvnk3lshkuyfau7o2qle5ut5msptulbxsqme", + "time": 1689009768 + } + ], + "validationError": false + }, + { + "dpid": "74", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifqxkjzypbtz7snjp3ghjrv56bd5umihchpwfppnoz67tcmhuq7wi", + "time": 1689041640 + } + ], + "validationError": false + }, + { + "dpid": "75", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibtsll3aq2bynvlxnqh6nxafzdm4cpiovr3bcncbkzjcy32xalp7i", + "time": 1689294216 + } + ], + "validationError": false + }, + { + "dpid": "76", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiatjdpouudloenzdzb7d3e5pogruvwbhurcnm2g5h64jmkpk2uebe", + "time": 1689518988 + }, + { + "cid": "bafkreigg3xk6ojueylnninvwsrw62nqpt7pyjnz6thaipbydb5ltclctly", + "time": 1692182952 + }, + { + "cid": "bafkreicrggm7jpxgaj2vgydvefuravrs2bh4emlt6eadx3zsbubtpulmcq", + "time": 1692330000 + }, + { + "cid": "bafkreifgfzjltrvcz3qixyjkiubgms2r3figm37euwxzbi6pvej2me6tje", + "time": 1701997248 + }, + { + "cid": "bafkreic4wiuatha4wclfbwft4vaeeqifrbb2f3tqm4eoajommogudbvswu", + "time": 1702000140 + }, + { + "cid": "bafkreicraffpobz3k5rzdmigl5tzklihwuim4kwe7xl5uulmfrkr4uvm2u", + "time": 1702045680 + }, + { + "cid": "bafkreidtkraxowlx26oz5g6qyfuawhx5nroil4a4mo6ywa7knfel7ft2dq", + "time": 1702045944 + } + ], + "validationError": false + }, + { + "dpid": "77", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiaqxrcrai2j2lpk2moare5abq4vtyhxk6m5jxo5fbqkrsy24kdm7q", + "time": 1691492520 + }, + { + "cid": "bafkreihjozked2lgpgtdcuvzejanhnm65sccwglgblxfdg3cwi72vlrtvq", + "time": 1691493636 + }, + { + "cid": "bafkreieodz3e4kzbnlg4nka5pwrgafwuuemfuejxqa5dpdaqlgt6bjs7fm", + "time": 1691496348 + } + ], + "validationError": false + }, + { + "dpid": "78", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifixmk6tierh6qompfouk63r6clg5jbeuvwherrxacq4uoedk4o5q", + "time": 1691501736 + } + ], + "validationError": false + }, + { + "dpid": "79", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibtuuiejhyxu4zr2od34biucedhlmqdmqem6v2ruqu6ov2kgsfnfa", + "time": 1692472464 + } + ], + "validationError": false + }, + { + "dpid": "80", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiawwe6os5lxye3hojdmwgcdt4nrs7xwfqy3p3vuv7xolhbnc2nqaq", + "time": 1693245804 + }, + { + "cid": "bafkreichlzplxpphzyoo3mnjg6tm2e4uplpm4d2q667a6dbz6xhctvktai", + "time": 1693246872 + } + ], + "validationError": false + }, + { + "dpid": "81", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreieefydw5dajtfgz5xqecgyyqxt7kzzyibihy4dvnrtwakaahkn34y", + "time": 1693246440 + }, + { + "cid": "bafkreicpdjfhoxg3gyc2xn63ppbxf7a7wvehkl4h34dapqeqekfetwunme", + "time": 1700147784 + } + ], + "validationError": false + }, + { + "dpid": "82", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicmvrritjqe4eatfkix3k6kgxz7oxlxengyfhg7rkubpagmxymiqa", + "time": 1693247148 + } + ], + "validationError": false + }, + { + "dpid": "83", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreia6ccnzt76b23xkq7slvzxgebltmlkmvcbvr77nzfyca7wpq6qkru", + "time": 1693247616 + }, + { + "cid": "bafkreidrb3cry4mh6fcik54rotatfnz2mapg3olcsxqpodgdbecrh5iu54", + "time": 1700147268 + } + ], + "validationError": false + }, + { + "dpid": "84", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibgfpmyizfiu6mpmdcn6aqvqrli72za72ccrxsim24nhtfv3cqb7m", + "time": 1693248192 + }, + { + "cid": "bafkreidfksyvtp5vjzoczjupn6h6h72dcr2p2rm63l7l5qwn6sq6d2nyjy", + "time": 1700146980 + } + ], + "validationError": false + }, + { + "dpid": "85", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreichgcyenem343rn3cgpyymyicdgoe7vgkev7z7bccskncaux7rxt4", + "time": 1693248672 + }, + { + "cid": "bafkreiejwrzg3vtvrvxm75dzgmk3736v4wrhl6uin64hzq76oekbkqi2ci", + "time": 1700146392 + } + ], + "validationError": false + }, + { + "dpid": "86", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihxqrtbvhxg3w2nu3ahpcu2it6qvnmca4xb72vq4w27er3v4rsjgi", + "time": 1693249560 + }, + { + "cid": "bafkreidlqc6jfns3ftpxoopx7etmfqp75xwoptd6es36xir2fl4nkvmx6i", + "time": 1700145552 + } + ], + "validationError": false + }, + { + "dpid": "87", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidlb227q7gvv622itmewvsdli726msbjgtsoufaepsaajrc66d27u", + "time": 1693249908 + }, + { + "cid": "bafkreibaiviks6ed4yuwaidz4zzerlhmlkbdcxucky74ah4nu37cm443lm", + "time": 1700146176 + } + ], + "validationError": false + }, + { + "dpid": "88", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibdpyr6vlsifgi3cebv7ip26ynplllfzpekxz4zfj7xna7uolpjgy", + "time": 1693250244 + }, + { + "cid": "bafkreif7e3nkqyrpa6pkhlnv7sdrwkgyct7fhgzqsteo457kpa46wuflhe", + "time": 1700146776 + } + ], + "validationError": false + }, + { + "dpid": "89", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidp3ed42l6cizgero5c7zfmxpmwp5hkc4tx6uz7mgioxsep4wb6rm", + "time": 1693251900 + } + ], + "validationError": false + }, + { + "dpid": "90", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiaw34rnu36p2ccawj3gopyxgl64qj3dc3ip3pzvfh5anzrvmu4z5u", + "time": 1694114940 + }, + { + "cid": "bafkreidk7ihar3swjjf46wtttjl52govxa256725urm5upcefu4wfvnxpm", + "time": 1694187648 + }, + { + "cid": "bafkreic6n2x6jlvss4iepnkkb4o4wre4nezbbff7kw46mz2egtzxast5xe", + "time": 1695653376 + } + ], + "validationError": false + }, + { + "dpid": "91", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigpcnierfxljhffgj4d6oyuwec4pcbkbjys6goaggw75rcobd6vnu", + "time": 1694197140 + }, + { + "cid": "bafkreidtiuwpwyewgjp3r5a7shvzgir7pvbeguxlv6zebpdbxrraialhxu", + "time": 1695653220 + } + ], + "validationError": false + }, + { + "dpid": "92", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicqezpklsjtuszjnsekc2dcyadgtbcfouhlc57vclrwco45gzbul4", + "time": 1695218412 + } + ], + "validationError": false + }, + { + "dpid": "93", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreie2p56t2d3i762v3bow3jweile6fmryt2qlcjq3cmkz7kpqtaic2a", + "time": 1695246144 + } + ], + "validationError": false + }, + { + "dpid": "94", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiaqnt5raa6b4ujpkgd4veg73rtp5csn6fwxrckbhq4mkrl7ws63dy", + "time": 1695246324 + } + ], + "validationError": false + }, + { + "dpid": "95", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreied6xbi65zwpzqiiaqnhq3cdq42c7yqrx6sd32ncv6avkovcb6f6y", + "time": 1695324696 + } + ], + "validationError": false + }, + { + "dpid": "96", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigurq54verb4sihjuonnx2pbo77lbjlviol2jfjxxgyzzko7o42ka", + "time": 1695816576 + } + ], + "validationError": false + }, + { + "dpid": "97", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreig76u6of7za2h5pdphz2ztsl5xdsgg2vrsh2dximjx3q2aszfjq6m", + "time": 1696295376 + }, + { + "cid": "bafkreig76u6of7za2h5pdphz2ztsl5xdsgg2vrsh2dximjx3q2aszfjq6m", + "time": 1696296012 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696299000 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696299600 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696299876 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696299912 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696299996 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696440036 + }, + { + "cid": "bafkreigul3gpywn3nes5jjxsh2ddfue4lg37ftg7sdqctmzxqp7cxdw3iy", + "time": 1696440996 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696459560 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696459584 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696466724 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696466820 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696466964 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696468416 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696479552 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696480608 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696480764 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696480884 + }, + { + "cid": "bafkreifcfaudesj7f5jxjn3fecovikw6khhvvspxhc4b5rca6swcdvhdca", + "time": 1696481172 + }, + { + "cid": "bafkreiciddswj3e6ho5of7x7a7liaqehnwqeg35w3cp3l5knv6k2tdlswa", + "time": 1696594740 + } + ], + "validationError": false + }, + { + "dpid": "98", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicsn4qia64pf7eim7sjggvmnggqadmfmrrcm5gecbpfdzxwzlk7i4", + "time": 1696303560 + }, + { + "cid": "bafkreicsn4qia64pf7eim7sjggvmnggqadmfmrrcm5gecbpfdzxwzlk7i4", + "time": 1696303944 + } + ], + "validationError": false + }, + { + "dpid": "99", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696336296 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696469268 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536756 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536804 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536828 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536888 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536912 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536936 + }, + { + "cid": "bafkreibx7segie7e5ttf2x4j3vuarqbsjfrnakn6srf6myqadz3kbimqhe", + "time": 1696536972 + } + ], + "validationError": false + }, + { + "dpid": "100", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreib2fs7g7yawpqeyjzatsv3bip5p6xr27pnblzjase3zyr4ixtbu6a", + "time": 1696506528 + }, + { + "cid": "bafkreihirj6fsasmvqmzngnyqitl6fpt3ljapgwx7dpfelgvruqsu7smw4", + "time": 1696507296 + }, + { + "cid": "bafkreid5osij2amlc67sm7uzqp22j7y3dn6lseyuy72oh64z5rqoh5qity", + "time": 1696840824 + } + ], + "validationError": false + }, + { + "dpid": "101", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiaoby2dmz4sljyhxsizjj2yd2jvbzz2vsywii3vp6xqi4rjefxl4q", + "time": 1696589760 + } + ], + "validationError": false + }, + { + "dpid": "102", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiceiefmvnwozgtpvvwv5exwsdxm36yl5ovunmcnjx5kjtcqvm6lwe", + "time": 1696605300 + } + ], + "validationError": false + }, + { + "dpid": "103", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreif6p22atw6ekbaxkrnfmetfdqtnhldaqw6qtqiqc7lqbus6aizru4", + "time": 1696841976 + } + ], + "validationError": false + }, + { + "dpid": "104", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiautwruptenrd4xbq5actpbmirrxprmnnxyxf37ixblmcynebjaqq", + "time": 1696842144 + }, + { + "cid": "bafkreie37zoipwpgqrupcmxfnhqfqpztumhcurzb27rfasa5ipao32w3ia", + "time": 1697792352 + }, + { + "cid": "bafkreiebcm7batu7zyp4aw6pzisbkldtlqsghh5jhczhkh63lxgjxp5wte", + "time": 1698779592 + } + ], + "validationError": false + }, + { + "dpid": "105", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreig33qp67gaov32ibvtb5gqtcnfrntrsrbzst2lcgrgnkbu4hbtcj4", + "time": 1696842444 + }, + { + "cid": "bafkreig33qp67gaov32ibvtb5gqtcnfrntrsrbzst2lcgrgnkbu4hbtcj4", + "time": 1698911760 + } + ], + "validationError": false + }, + { + "dpid": "106", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibbbm7623bsdoftewbedqd3peny6zhqpt6tjgx67ouf6hhvbv2idi", + "time": 1696941732 + }, + { + "cid": "bafkreihemsbpld4yuzrn4ckrlriyq5ortlkycxx74ayfugnoce7oetsmam", + "time": 1696942104 + }, + { + "cid": "bafkreic4gpc3k5mrttk57w6k5fvtgvubvh6xfwgmubecx53b55xsxoavxe", + "time": 1696944228 + }, + { + "cid": "bafkreickteh2tt3oy43o42ikwei6tppghmtbkockk22a3niovi57ugor7q", + "time": 1696961232 + } + ], + "validationError": false + }, + { + "dpid": "107", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicgst5gqckb4bzduzxqhn2v5an2xjnmhv6qwscwtn3gjhuplpv3jm", + "time": 1697040396 + } + ], + "validationError": false + }, + { + "dpid": "108", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifzh36eve7dsmbebnvxhpalxdgcjcur7anxllzyfwnmetlsvq2f54", + "time": 1697792640 + } + ], + "validationError": false + }, + { + "dpid": "109", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibiziudxe62de7g443yl453tpnky25ujrcdhuaudtwq7hxrrr6q3m", + "time": 1698054684 + } + ], + "validationError": false + }, + { + "dpid": "110", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreic65maz27f7atu7a4euzl6jv4c2kz66ddvcxuhdajl4i4l27uwwii", + "time": 1698079308 + }, + { + "cid": "bafkreic65maz27f7atu7a4euzl6jv4c2kz66ddvcxuhdajl4i4l27uwwii", + "time": 1698323460 + } + ], + "validationError": false + }, + { + "dpid": "111", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiejskdyqkcsnvcl6njkivjvptts656x3qvr64nsjdnx6pcn6bdht4", + "time": 1698177444 + }, + { + "cid": "bafkreialaclllbtsaxzdhbbut4mk57xh4r7bsj56cb44fockdxokcznbk4", + "time": 1698178344 + } + ], + "validationError": false + }, + { + "dpid": "112", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreictzmcsbe3bkmb7vyludvy7q37brvsw6q7xayblyn45r23n7ru224", + "time": 1698747720 + }, + { + "cid": "bafkreifpbperacf57typaumiauqsf3kcmljgm7ehu2vjmlflwepddpeth4", + "time": 1698747864 + } + ], + "validationError": false + }, + { + "dpid": "113", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreig2nlksggv4ghb24xw7ng23klrttx3kiu3tdlnsa2gcn2zacpmxa4", + "time": 1698782484 + } + ], + "validationError": false + }, + { + "dpid": "114", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibsaosbasq6er4o2mkovemlp6tgppyeudue6lsx6dbznba56omd6e", + "time": 1698782652 + } + ], + "validationError": false + }, + { + "dpid": "115", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiaqt4amqtdha2affz4caq6qrl3uzk4zutwfnzcc6ba5ziw6itc2ty", + "time": 1699355412 + }, + { + "cid": "bafkreichmxylugiwhtrhomfjc7njdmp6isfivmdsflhmuzenzxnyl76m5i", + "time": 1699355784 + } + ], + "validationError": false + }, + { + "dpid": "116", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreid4spqoyg2mk2r7bcju6vkxsgtcx2fl27tyivtvrvnwlqgn26udn4", + "time": 1699608000 + }, + { + "cid": "bafkreiejv6ymnxxum5c67qpkvp2eevgy7rgksq7vhzgyfxg5riwl33lzqe", + "time": 1699887960 + }, + { + "cid": "bafkreibechybrdrnwlsg3unh2pgxg2jgekg653h37e4xzc3wazyzcjzegq", + "time": 1699954776 + } + ], + "validationError": false + }, + { + "dpid": "117", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiepbbtkhudgspd6dr4rnckaqwdenedehsvppkyakute6z36bplgpy", + "time": 1699954800 + }, + { + "cid": "bafkreids7cf6gagvaxbmammx6ekl4e3xwhcyw33vkqmy5ml2m4epvpjwua", + "time": 1700053860 + } + ], + "validationError": false + }, + { + "dpid": "118", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihv7uzjstazrksvrdwrt6j3oqiw73oqi2krvwlzojbo5yhrfrpcu4", + "time": 1699979532 + }, + { + "cid": "bafkreifwnjaykar4vdhcpyimr73hklty7nqnm77u37rzmdyhldtlleycfy", + "time": 1702053972 + } + ], + "validationError": false + }, + { + "dpid": "119", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifisxmqzztc3zgleheiakn4xn5w7ze6ap5iynom46djxue54nvk5i", + "time": 1699983900 + }, + { + "cid": "bafkreihhg6k56gey42vldxac36u3ueleq4nzrm2zw5fxfcdmwcdrfyjpci", + "time": 1699984152 + } + ], + "validationError": false + }, + { + "dpid": "120", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifonv6z5enzbl44kwvh3i3m5stmagckblhfp4skmilmt72ff3dthe", + "time": 1699984440 + } + ], + "validationError": false + }, + { + "dpid": "121", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreig7g2zbirxw3spdxicv6igvu4t2frzdbipzh4q2lp7a7vzsnktdym", + "time": 1699984896 + } + ], + "validationError": false + }, + { + "dpid": "122", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidhtfpm7qcv36eklavzuhq7dxbfq7a2o3ovv6q55qubyr7xnvpnm4", + "time": 1700005716 + } + ], + "validationError": false + }, + { + "dpid": "123", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifuyc6nxavordwnewceq6tdzbzs4u5u7eiohs2lflwabdmhrrcxtm", + "time": 1700006352 + } + ], + "validationError": false + }, + { + "dpid": "124", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiccwsruwcne5ctm4bdarr6772xgxqdcy3jg66rthmd5iaq2hnexgi", + "time": 1700046408 + }, + { + "cid": "bafkreihi36k65e6jlytud7hcvtxru2xbkphtxbdu3xx2pkm53qwb5mjzge", + "time": 1700046432 + }, + { + "cid": "bafkreiezsp3ibhch3wf4arb4ies65exfex2isowpfsrrlq6pyvatiexr5q", + "time": 1700046552 + } + ], + "validationError": false + }, + { + "dpid": "125", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidsdl7s6pqakmfhfvcauof7ovylegxa5nwp2dxuxd5rbb27vsk4d4", + "time": 1700057772 + }, + { + "cid": "bafkreidjcemwjx3ljeuja3lety52fksvk2ojukxkxudbnwu7kgse2zz3tm", + "time": 1700058384 + } + ], + "validationError": false + }, + { + "dpid": "126", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreib6z6ysfnyw6k6ly7cpdp7qjcjbbvjoffn4ppiarimmk33sbxuoy4", + "time": 1700059584 + } + ], + "validationError": false + }, + { + "dpid": "127", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibqnmfw4jhrjk4ggz63kqtti7rzxroutotrrey2j37a3ad2wfuojm", + "time": 1700063400 + }, + { + "cid": "bafkreifgaoapp6ku2zt3awb3svh3ol75stczvu2bon373bit4whaneb2lm", + "time": 1700063832 + }, + { + "cid": "bafkreibbb2gkxihablys2fjtrecr2tvfbujyulblivfqn4jsl6hyx5dghy", + "time": 1708492476 + } + ], + "validationError": false + }, + { + "dpid": "128", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihjgheci62x27bgduapkcmwbxldpwyk5af5kqvbpq2nmfmtfxdmmm", + "time": 1700063832 + } + ], + "validationError": false + }, + { + "dpid": "129", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigtnznzipcb6j4ufpnmde3e66pzl53n7etkxjj4waorkc2vfzban4", + "time": 1700754096 + } + ], + "validationError": false + }, + { + "dpid": "130", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiaiwepaj5h3ueggcvsp7rs6zsu5emvcbxg4aantq43mjrvkb46t5i", + "time": 1701434724 + } + ], + "validationError": false + }, + { + "dpid": "131", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidw5k6li7ex6goxdky37t6obgd3472rbgygmvu5rnf6iiptrqkmiy", + "time": 1701702708 + }, + { + "cid": "bafkreiaa4eh2bmuwlutgnvnbbd64npfqdlzxzc75li5pzhlmdkrvj5qjrq", + "time": 1701703056 + } + ], + "validationError": false + }, + { + "dpid": "132", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifqxy2ie6a5gwqwjdrjzpuer3d5dwb4sauljj6coojnzprlvfes2e", + "time": 1701788316 + } + ], + "validationError": false + }, + { + "dpid": "133", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifyxvaek2nsdtke62wviupn7qqtgzeucrpe5c66lrycvtvestkkau", + "time": 1701795900 + } + ], + "validationError": false + }, + { + "dpid": "134", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigu4xxysvqtf6cicat3iheugi6g45vsgnptbrht6p6om3txvsttye", + "time": 1701872976 + } + ], + "validationError": false + }, + { + "dpid": "135", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihf45jsg5rnkpv2mz2wwpf5w3u6ixu765a5hckam3j3fbl5i2tgbq", + "time": 1701875664 + } + ], + "validationError": false + }, + { + "dpid": "136", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreih5g3pbinh264nuwgvsuerueucgpacv5ytill4sbxt7zsexgfntqi", + "time": 1702142316 + }, + { + "cid": "bafkreiaitokvbuwllmihafculxuniwiydtl2cuuuhqbmkuvpk62uuhmu4e", + "time": 1702145736 + }, + { + "cid": "bafkreifyo3tzgp3bp7a7zwxym6lskt567rdvjn4t334dczglkvgbpglla4", + "time": 1702202688 + }, + { + "cid": "bafkreif4yaj5za2adpy3wmklbstwpaciobl3j4uwcwrwcri7bbkcvwik6q", + "time": 1708382904 + } + ], + "validationError": false + }, + { + "dpid": "137", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiebtockthsjrwsikbjshzdikjsa3j35avolyabw2zl5nxd4np2qa4", + "time": 1702430448 + }, + { + "cid": "bafkreig5muvzq5a5whji264zbzpkd452kqiswo4on3b3waibrwcte6n2jq", + "time": 1702439796 + }, + { + "cid": "bafkreie7zyrvboq3ygb3tm74qkuvbldwq3ocdltnz6lngud3s2fpdaquiy", + "time": 1711224288 + }, + { + "cid": "bafkreie7zyrvboq3ygb3tm74qkuvbldwq3ocdltnz6lngud3s2fpdaquiy", + "time": 1711224408 + } + ], + "validationError": false + }, + { + "dpid": "138", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiezlcl57kasksq7hwdqxsffpqloek4jbr4vrvausbg6ozsrnwnkfq", + "time": 1702512600 + }, + { + "cid": "bafkreifxevx7yu5noaquu4bojmyl6pubqotkp4wsbjpd6vbz3neuk7nlxu", + "time": 1707153744 + } + ], + "validationError": false + }, + { + "dpid": "139", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreictkrrk3arfcy4rstvjjtpwrw3yf7wdgxepf5z2cmjuiv2igkdlnm", + "time": 1702512876 + } + ], + "validationError": false + }, + { + "dpid": "140", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibz4nvkwdmqxmtxefklebrqrhbbhias3bvt7moko5jgw6hopkhwga", + "time": 1702513068 + }, + { + "cid": "bafkreifbhbxfm6s6djz5taz5buthqlpy2cruaysfnixojzubwgkprsbq4i", + "time": 1708801020 + } + ], + "validationError": false + }, + { + "dpid": "141", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifkjw3mjt4ib4dhjjpn2sbv3oqf4c5mcf5n7zlggynvvqlwksdxay", + "time": 1702513164 + }, + { + "cid": "bafkreiabv34brs4dnbivmzfyggc2ryaxs7zlb3x3zh2ynie53suktlitva", + "time": 1708802436 + }, + { + "cid": "bafkreiabv34brs4dnbivmzfyggc2ryaxs7zlb3x3zh2ynie53suktlitva", + "time": 1708802436 + } + ], + "validationError": false + }, + { + "dpid": "142", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidll4iaylvaplqqqotp3e7bolx3qgqnjkzliplbhdz7v7dcrdn65q", + "time": 1702513344 + }, + { + "cid": "bafkreieszmyc5ph43ft77gk4pj5emhuy53if6vjbeejzxbrtusxb3ouq54", + "time": 1708802160 + } + ], + "validationError": false + }, + { + "dpid": "143", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidjonu3vhm5vd5fogs3zrjzq3qcajjkpvwwj43gdqn2swiops5glm", + "time": 1702513392 + }, + { + "cid": "bafkreih25vwbntxxybpsxctpg5eqi6f7ewcwzqzpklifbfqffcrbs65k64", + "time": 1708802052 + } + ], + "validationError": false + }, + { + "dpid": "144", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreieogvypbmg7vgut2f76b33kql6cw4vstzm4f7asoenfzh2rudpekm", + "time": 1702513452 + }, + { + "cid": "bafkreib3b6ztd5tyebhjtxsj4dpl2nw3bipejak5n3zz7u7ta3et2ghyoq", + "time": 1708801908 + } + ], + "validationError": false + }, + { + "dpid": "145", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibbu3bk7ucli5yaikmcwdduigaien2dqb2bzq4af6ufzrmu6vswty", + "time": 1702513524 + }, + { + "cid": "bafkreig2mtcbf6eu2vraqmy5ftukn4i6fgeiwfou2znswwss5sarsotmcm", + "time": 1708801680 + } + ], + "validationError": false + }, + { + "dpid": "146", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreied3q6xs3itsgvjgeybu5cnmuuds2puklksrhfvy4ofjddo3nkyle", + "time": 1702513584 + } + ], + "validationError": false + }, + { + "dpid": "147", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiapkcqpkavfwqc4id5mb7e46n3f5nr5uig4ik7bwaxk7a5tox2ztq", + "time": 1702513620 + }, + { + "cid": "bafkreifxvagntjqfpzrigsjfajflqatzk4dogq56lqotaqjv7d3iugdrtm", + "time": 1708801212 + }, + { + "cid": "bafkreifxvagntjqfpzrigsjfajflqatzk4dogq56lqotaqjv7d3iugdrtm", + "time": 1708801236 + } + ], + "validationError": false + }, + { + "dpid": "148", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibgprhlr22zfwgrm7y3kx4jxslpozqp4pmofsrj5tbqpkaxi5glpe", + "time": 1702559448 + }, + { + "cid": "bafkreieqjqllffddjuraswoq4pm5d5cd5eu2knqe6yie7rj6aufujtct4e", + "time": 1702907160 + } + ], + "validationError": false + }, + { + "dpid": "149", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigcc2l7aay34i5zeot5wjvpspdpwp6ipfzffs3cnnpbpt7c2gqu6i", + "time": 1703003448 + }, + { + "cid": "bafkreig6lp6265u42llqh6hkzxc54hmyfea7ax7gewg7tdyvthieotmwpy", + "time": 1703003868 + }, + { + "cid": "bafkreici3wzz7njqigyo7ebzwn3kibxgwjr43ihowwebl4exmfy75tkpjm", + "time": 1703072388 + }, + { + "cid": "bafkreicgxdcypaq5tmmrrva3tl7k2un47pfolg3mox72j5k65zitsukfii", + "time": 1707406116 + }, + { + "cid": "bafkreie7j6ji7ynh5d5yoldoxfevak55nkmcx5h7v3c6h4xy7le25sbgke", + "time": 1709143824 + }, + { + "cid": "bafkreic4vm34jfrdp3qu7bx7np3qhvrxlwx5gkn3kf3c4pv6mzbavc3twu", + "time": 1716286500 + }, + { + "cid": "bafkreidsqfd326zx3svaszqm76arwjsonwxpzer24keqt7lv3bpgt5guzu", + "time": 1717067124 + }, + { + "cid": "bafkreid5jzrqitombqlytxoyb36q5avzmxkmxl2nyidtv3pho5godqxbim", + "time": 1717607268 + }, + { + "cid": "bafkreid5jzrqitombqlytxoyb36q5avzmxkmxl2nyidtv3pho5godqxbim", + "time": 1717607316 + } + ], + "validationError": false + }, + { + "dpid": "150", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreif3aoauxavq7sxibkysi4kemqdwbcez4cjtmzoou46bj44r2rc3sa", + "time": 1703205816 + } + ], + "validationError": false + }, + { + "dpid": "151", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicqe2blgjarm3bg6jon5sjvmu773bnuajfnkmlnvo5hd5uj2yr234", + "time": 1703212224 + } + ], + "validationError": false + }, + { + "dpid": "152", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifiy2ipxllse5z6kspsspgt247eadivoij736j3yehwe6cy5rn6ny", + "time": 1705091376 + }, + { + "cid": "bafkreihvutuhtiehsoyc66u7a7bncnqfhoosynejagkykkfwa7gkr2rsta", + "time": 1705091496 + }, + { + "cid": "bafkreiekobyktiisailjk2sauqxembzyqe26z7i7mxkl6xidhhlb62wnyi", + "time": 1706832732 + } + ], + "validationError": false + }, + { + "dpid": "153", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigr54hmercrddm2nnyo46yfn3w466zeoawph7k23swzr5v6lobcjm", + "time": 1705491780 + } + ], + "validationError": false + }, + { + "dpid": "154", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidzawjc7uaskxy2a55gfd3pjqssl5v6nfqj4ghziglbdfuk3arfri", + "time": 1705579488 + } + ], + "validationError": false + }, + { + "dpid": "155", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreieqqvt2bx34g44zombuj254dzqng5l4bjc33vnuduiaklfjf7jrza", + "time": 1706550924 + }, + { + "cid": "bafkreih4hi7mhwe3uwmf2xa4lfpgmqlt4o5vagzqqr3c54alnnl5wr3r4q", + "time": 1712673828 + }, + { + "cid": "bafkreicamnoitiweehqqlvfa6xmoq7qoooz7kvbuhqy3tdoralmjgwrju4", + "time": 1712674440 + }, + { + "cid": "bafkreidl3wopg6piqc5xba3tvtfcxsvldxcudax4mmwzjtgwsu4hj6t5je", + "time": 1712765676 + } + ], + "validationError": false + }, + { + "dpid": "156", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibhuuogniwgsozq6zqgpfg622ktaz4e4xtspvxv6be7zoaknlp7oi", + "time": 1706735148 + }, + { + "cid": "bafkreicmyxjhueivvlucnysc5sgmdnxgsmn5wryaodmdwl7xhku5o4dwki", + "time": 1706737632 + } + ], + "validationError": false + }, + { + "dpid": "157", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreificypwhqbtu4acdrxgbzdrpbw5dncxrcwtskrebhv53trsk23ive", + "time": 1706738172 + } + ], + "validationError": false + }, + { + "dpid": "158", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreigmgjpsfxzshdvozllx3m6s5ubiulcx7yumhe7armganzdiu42feu", + "time": 1706834520 + } + ], + "validationError": false + }, + { + "dpid": "159", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifl7hhai6p5podahrcse5ocklgf2qdayw33raeaugk4cjgugroupq", + "time": 1707473772 + } + ], + "validationError": false + }, + { + "dpid": "160", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifjtpqkpatgmy4jpmhsepfvpv2gmiofgyh6qpinfnstyrsufickua", + "time": 1707644916 + }, + { + "cid": "bafkreif2hl47drgqwb6qay5dbdmmm4ivbcfus3wromwaho2wxine6niudm", + "time": 1707645552 + }, + { + "cid": "bafkreihopqbkiidgwszltgcx3cp3n5m3vkfcyqf5tktaf7zpikdwqkpkmu", + "time": 1707646572 + }, + { + "cid": "bafkreih7n6cnpgftyn3paqmvvd3bfm7hna7qqgwlqhcpldjtdwabvg5syq", + "time": 1711656132 + } + ], + "validationError": false + }, + { + "dpid": "161", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreialnzhaztvhuvwkzpqlst7w3yttviws5tcpdnwvggdmxnx2ydzere", + "time": 1707848244 + } + ], + "validationError": false + }, + { + "dpid": "162", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreieowcw35rvuvocaupds5fsremm4h6j3cris5sscfjun4o2e4bccla", + "time": 1707967356 + } + ], + "validationError": false + }, + { + "dpid": "163", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreif4554qs4ppds7364pfeqla623ebon5nlvs5m53ecw4jhdkmtnfre", + "time": 1707967740 + } + ], + "validationError": false + }, + { + "dpid": "164", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidn5fdrmh62nc4r3g5paqija32flksc23evsc5akqoqftkwfeqm2i", + "time": 1708094712 + }, + { + "cid": "bafkreibpaflwrfhygpheciwlemvahtkkwdgg35dnevu25rid46iae2ws6i", + "time": 1708453920 + }, + { + "cid": "bafkreif7javbr3hrnuwmoggv7dtprs7axcsdldsqpwmpfcdizy5bk2tfxa", + "time": 1708514124 + } + ], + "validationError": false + }, + { + "dpid": "165", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicv2zf35h43m656h2734du5ynp2zctedwxkgwtbhubg34oenhhexa", + "time": 1708109700 + } + ], + "validationError": false + }, + { + "dpid": "166", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibfvwqckon265lpmjuinzlg6ebzo4s6dtgh7invz2prf766bvuodm", + "time": 1708372176 + } + ], + "validationError": false + }, + { + "dpid": "167", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreige2oxxkk4rboadjcxlvwbvlun3e4xmrxp4qtqvdmjdfzhptuyf5a", + "time": 1708458984 + } + ], + "validationError": false + }, + { + "dpid": "168", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiftjc6urzlqlcffupjwnezhfash4tlvgy2qnstu2vpp6tdk4zpmma", + "time": 1708493796 + }, + { + "cid": "bafkreic4hj66auaehgtgoz6zzks2w2r7lsxhrisjuh7dbfipvgmkhfpace", + "time": 1708690584 + } + ], + "validationError": false + }, + { + "dpid": "169", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidguz57tkqtmta44oov6jkgxxeg635asddp2belouydyxjndukspi", + "time": 1708495980 + } + ], + "validationError": false + }, + { + "dpid": "170", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidyakyvrrmovwk4ddfw2fxtgkl3f4coef75pybncmoa55jnlxx6tm", + "time": 1708501884 + } + ], + "validationError": false + }, + { + "dpid": "171", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibtajzmf7ty7hhyclz4aj5f74mktbj4liyhobvs3qr7nebqprl2yi", + "time": 1708516896 + } + ], + "validationError": false + }, + { + "dpid": "172", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreicenejlzy2ygk6vflo4xhr7hjqe22nz5f354afoo5pc65d6qf2ojq", + "time": 1708523184 + } + ], + "validationError": false + }, + { + "dpid": "173", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreie23vmvink27bqo7qzzsdng4ho22uhrgoscencr7s4itekrzreahy", + "time": 1708531344 + }, + { + "cid": "bafkreie23vmvink27bqo7qzzsdng4ho22uhrgoscencr7s4itekrzreahy", + "time": 1708531620 + }, + { + "cid": "bafkreie23vmvink27bqo7qzzsdng4ho22uhrgoscencr7s4itekrzreahy", + "time": 1708531992 + }, + { + "cid": "bafkreie23vmvink27bqo7qzzsdng4ho22uhrgoscencr7s4itekrzreahy", + "time": 1708532064 + } + ], + "validationError": false + }, + { + "dpid": "174", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidobtwdrk7dulyc6dghfr6zylbfisjwbs6l6ahd6qfkfdavs76dpa", + "time": 1708602732 + } + ], + "validationError": false + }, + { + "dpid": "175", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreignopdmerljfo6nzpq2hj5zr5g7h3wajjxthpuikxjpsdbco4tavm", + "time": 1708619376 + }, + { + "cid": "bafkreiae65pw54dt5vx75oenehagushpi2sh42c3zqld7der3ircmfyqam", + "time": 1708653516 + }, + { + "cid": "bafkreihm7iuibrdzlr5uyrhhkyijboyheeujettcihcgmegrna43mmvs6a", + "time": 1708672332 + }, + { + "cid": "bafkreicjzr7d4odl6dzvx3acnng3cwq5sptcjn5wbqeep4juymadohagfi", + "time": 1708674912 + }, + { + "cid": "bafkreihdgbp3rrimo3sfayouabpfy5awspr6lues5rj5pjld2mcwi5ftsm", + "time": 1708729500 + }, + { + "cid": "bafkreidpouvko3ht6dkhplrx44r4cbycx4irvw6mnunven3x2mll5kgaie", + "time": 1708890600 + } + ], + "validationError": false + }, + { + "dpid": "176", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidwx6vv43n4vyd2gvnc7a7hoalg3nj6ncuxtzete7bay6lgkdjrji", + "time": 1708695348 + }, + { + "cid": "bafkreibjcr22ex3uibpoxf3fpzriafscmbivizzkqrjx7iqh5qbkg4oizq", + "time": 1708695612 + } + ], + "validationError": false + }, + { + "dpid": "177", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihnul5baol6hg5vsq6sokqwbm5txyb5honlphs3rpjklc4d7pj4qi", + "time": 1708882260 + } + ], + "validationError": false + }, + { + "dpid": "178", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibnvu2kmntm4p2ttebfqukas5hdzzthyahkkgxizihb4f3fwvszoy", + "time": 1708900272 + }, + { + "cid": "bafkreibax2nwfvcmewzi4muxbtywulni6zvvihnipob3hvweohuu3lmawu", + "time": 1708900680 + }, + { + "cid": "bafkreiaicia5j7xdpo5gr3nukomg7kylxpnyfiguflr7ff5z6v45rbg3om", + "time": 1708909188 + } + ], + "validationError": false + }, + { + "dpid": "179", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiekmumtbr6fg6ksitwx3744knbituhthjis3mnd5facdbqc6526fy", + "time": 1708930572 + } + ], + "validationError": false + }, + { + "dpid": "180", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihyn2pm7mqzcjabytkoszcetquu4q6zouwaeqhp6bavvlmijqvj2m", + "time": 1708965960 + }, + { + "cid": "bafkreigksvcw5f67h2kzbxnndwf47ch74nb4vbniepacjt6y5nm74ote4m", + "time": 1708966848 + }, + { + "cid": "bafkreifhzq76yqo66hcvcj2e7554odbcppblavfrobmyuxynaj2wv2ydlm", + "time": 1708974048 + } + ], + "validationError": false + }, + { + "dpid": "181", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreieqzlofquf3yakkfcqwzzg77ea6qrirnbli6iedpeo5zk2hktedfe", + "time": 1709032560 + } + ], + "validationError": false + }, + { + "dpid": "182", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidjaowinhp5e3m6ikq32mfgqg5mqw6ttzccngl5aa2imyryscenjq", + "time": 1709070444 + }, + { + "cid": "bafkreidjaowinhp5e3m6ikq32mfgqg5mqw6ttzccngl5aa2imyryscenjq", + "time": 1709070600 + } + ], + "validationError": false + }, + { + "dpid": "183", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreihfy4ibvcrdxlq3n6y6ahskxglvyhskwugy7xwi4amk4dcek7hvvi", + "time": 1709074644 + } + ], + "validationError": false + }, + { + "dpid": "184", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreif4pg7ph3qxuj4yoapw4tez3jxt52m5fhp7nkd3q2ai4xrwva46oq", + "time": 1709709132 + } + ], + "validationError": false + }, + { + "dpid": "185", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreibbt24dc64gwzwhcjtyha5qsdvmj4ztlkbhg7p7s74hjpdlrveo5a", + "time": 1709710296 + } + ], + "validationError": false + }, + { + "dpid": "186", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiezmycqcs3426uhlpamwfidxlt72njmc22cuma47fxx5e3oi7zrpq", + "time": 1709713596 + } + ], + "validationError": false + }, + { + "dpid": "187", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreiemcbfxzi5v3sjiztw4zqs7ngbbirmbcza2sxag4ur4gx3jc57weu", + "time": 1709713968 + } + ], + "validationError": false + }, + { + "dpid": "188", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreifc7blw4sfdrqqyinooyk2zajg4kvobazfpxmmyxhky67xyrtg2bi", + "time": 1709717856 + } + ], + "validationError": false + }, + { + "dpid": "189", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreib5w5wqatnhuuekzdmqe33ci4jmczwtcw235mdugsk6sbjkewhycq", + "time": 1709718156 + } + ], + "validationError": false + }, + { + "dpid": "190", + "owner": "0xF0C6957a0CaFf18D4a18E1CE99b769d20026685e", + "versions": [ + { + "cid": "bafkreidlwnin6u3lbb5me7gsaomtrz3xfxruteb3oqvng2isup6dq2md2u", + "time": 1710044316 + } + ], + "validationError": false + }, + { + "dpid": "191", + "owner": "0xec29aCa1a8740B8C5e2e06EBB52290700B9a2c40", + "versions": [ + { + "cid": "bafkreiekjqv27pmrf3tk6tn4mimvbivhtln7jefgjmzeui6vm43oes2giy", + "time": 1711113468 + }, + { + "cid": "bafkreiekjqv27pmrf3tk6tn4mimvbivhtln7jefgjmzeui6vm43oes2giy", + "time": 1711115796 + }, + { + "cid": "bafkreiekjqv27pmrf3tk6tn4mimvbivhtln7jefgjmzeui6vm43oes2giy", + "time": 1711118604 + } + ], + "validationError": false + }, + { + "dpid": "192", + "owner": "0x955bcC4a744f7a63c064bcDCb41d3da32ab59fA2", + "versions": [ + { + "cid": "bafkreif7cyujbmdodoxfmvwg7vtllo57eqyl4jqx2ldugcdgbn4l37aide", + "time": 1711224600 + } + ], + "validationError": false + }, + { + "dpid": "193", + "owner": "0xBaf4a58783150abaAec703E43e6cca151D4Ff475", + "versions": [ + { + "cid": "bafkreifxdilgiuozcbyxrbmyij3rh5a75br7ree7finitlfgpdgsuovbu4", + "time": 1711371324 + } + ], + "validationError": false + }, + { + "dpid": "194", + "owner": "0xBaf4a58783150abaAec703E43e6cca151D4Ff475", + "versions": [ + { + "cid": "bafkreibir2ytu4y3ckuntnyq4bd2hn7e7v4st4qznhmymulunoag6htkli", + "time": 1711371840 + } + ], + "validationError": false + }, + { + "dpid": "195", + "owner": "0xBaf4a58783150abaAec703E43e6cca151D4Ff475", + "versions": [ + { + "cid": "bafkreibwwiqyfdk57mulox3kkndbjzrpauwifhjlx4a5mcd3xyghi3phnm", + "time": 1711372188 + }, + { + "cid": "bafkreibwwiqyfdk57mulox3kkndbjzrpauwifhjlx4a5mcd3xyghi3phnm", + "time": 1711372224 + } + ], + "validationError": false + }, + { + "dpid": "196", + "owner": "0xBaf4a58783150abaAec703E43e6cca151D4Ff475", + "versions": [ + { + "cid": "bafkreib2bldqjixzqdxfgawln7nkmho7au4cu4vpp3luyziih6i5v24fyu", + "time": 1711372332 + } + ], + "validationError": false + }, + { + "dpid": "197", + "owner": "0xBaf4a58783150abaAec703E43e6cca151D4Ff475", + "versions": [ + { + "cid": "bafkreibckw6mcb7w6ocnrftdcj5ua2ynp44athn37uj5a2luejt4sbag74", + "time": 1711372704 + } + ], + "validationError": false + }, + { + "dpid": "198", + "owner": "0xBaf4a58783150abaAec703E43e6cca151D4Ff475", + "versions": [ + { + "cid": "bafkreig2oyjlgt2tm5o5w66lroxithj2yyokcgiirlqgtxi2rx5fmcnl3u", + "time": 1711373136 + } + ], + "validationError": false + }, + { + "dpid": "199", + "owner": "0xBaf4a58783150abaAec703E43e6cca151D4Ff475", + "versions": [ + { + "cid": "bafkreia6bshsvigqmwl6gczqkekbe6n5vrm5oqk4mlpqxzuqvm6pnvcz4u", + "time": 1711373508 + } + ], + "validationError": false + }, + { + "dpid": "200", + "owner": "0xBaf4a58783150abaAec703E43e6cca151D4Ff475", + "versions": [ + { + "cid": "bafkreiaj3hoxxa6ejl6wbbxmj5yyvwgjbxqcwvutbuffjdmz6bjo4aeuua", + "time": 1711373664 + }, + { + "cid": "bafkreihuphbjewu6gy7bhu3pojq4wzauo4eysrjwf2yjqxauakfm2oycwa", + "time": 1711895628 + } + ], + "validationError": false + }, + { + "dpid": "201", + "owner": "0xBaf4a58783150abaAec703E43e6cca151D4Ff475", + "versions": [ + { + "cid": "bafkreib75qhje5orxp6x73krgk4gxs4zjma235jakvaz7nmjmidxotqvay", + "time": 1711373808 + }, + { + "cid": "bafkreidfhctv5tsybphthhsi64pvjtnfqal6u4yio7ntuossddyoeqktle", + "time": 1711895736 + } + ], + "validationError": false + }, + { + "dpid": "202", + "owner": "0x93aF2e3057F7A1dEec2bEDaB92014372529917b2", + "versions": [ + { + "cid": "bafkreihw7nmfo37bcnovdiuarejedgnesfbjcrx6yfylnapsruv3cxmwca", + "time": 1711379508 + }, + { + "cid": "bafkreig7tkfx63cprx4p62exwlob3fdpnbz67732yivzjvvp4upvqvtaue", + "time": 1711388652 + }, + { + "cid": "bafkreiefzc365jagtqbqlay6enzcetdqntxmpnamknxvub523cbqe5vhii", + "time": 1711535616 + } + ], + "validationError": false + }, + { + "dpid": "203", + "owner": "0x711E9b9e8aD75CBD3AC024a8e4Aeeff59AfBae6c", + "versions": [ + { + "cid": "bafkreicatliyp3ucb74vsyjutro5gj3f4ido7g2g3lpqq44mejhnft4nhe", + "time": 1711480872 + } + ], + "validationError": false + }, + { + "dpid": "204", + "owner": "0x711E9b9e8aD75CBD3AC024a8e4Aeeff59AfBae6c", + "versions": [ + { + "cid": "bafkreihzsc3ukfifnwrn2pwbi7nslahwducpjpanw6whgnmlqrzmzudboa", + "time": 1711483248 + } + ], + "validationError": false + }, + { + "dpid": "205", + "owner": "0x711E9b9e8aD75CBD3AC024a8e4Aeeff59AfBae6c", + "versions": [ + { + "cid": "bafkreib72txikuh4u63nb3jtsxj4r3q7cdeaaq7lzwejqjchminj7smhhu", + "time": 1711484040 + } + ], + "validationError": false + }, + { + "dpid": "206", + "owner": "0xDAF8752DDcCE8a6B709aa271e7Efc60F75CDDF64", + "versions": [ + { + "cid": "bafkreigwpvacu6jfho5bn3dh6kddxjxcz3tmp5ukglfds2vgqbetburmyu", + "time": 1711485180 + } + ], + "validationError": false + }, + { + "dpid": "207", + "owner": "0x3946A420ac849229918AE4C27e4CED2299646b03", + "versions": [ + { + "cid": "bafkreif5vmdusp7spdvopv6gtiaywnxf566hvxqj4y5xajxslad5hjoomq", + "time": 1712129772 + }, + { + "cid": "bafkreianwyrn4e57d5ebpnrxnxnwc7j7t6x7sbm3tyib7gzu4dugt23qlu", + "time": 1712130636 + }, + { + "cid": "bafkreihn7si3rxrrgwie53k4w4nuaztmq3eajbvv2gdesfos3bgpdjgl2i", + "time": 1712134152 + }, + { + "cid": "bafkreiawd2bsrkwxrsqfsxuxgxbilgs3zzbosdruplsklludfmuprszgli", + "time": 1712143392 + } + ], + "validationError": false + }, + { + "dpid": "208", + "owner": "0xF84bb22037D7977f78FefFBA75D1dda938B73E2e", + "versions": [ + { + "cid": "bafkreicjmmge75m2pcqhi2iiae5ab2byztxbcnyukyljje7s3nefbsmdwe", + "time": 1713698724 + } + ], + "validationError": false + }, + { + "dpid": "209", + "owner": "0xF84bb22037D7977f78FefFBA75D1dda938B73E2e", + "versions": [ + { + "cid": "bafkreidye2q5xg5mqqbfup32fvs7hkg3lpwbcl3kojzu67vmtnavopwrea", + "time": 1714405584 + } + ], + "validationError": false + }, + { + "dpid": "210", + "owner": "0x72Dc927773e3d453Fff9B083C45eBE9d256Db16E", + "versions": [ + { + "cid": "bafkreifbpagid6fj4gp2z3qbynl7w676ulpnv5lqgibhyf6a4ckgdzdt7y", + "time": 1714769952 + } + ], + "validationError": false + }, + { + "dpid": "211", + "owner": "0x9381995264d304e514Ad3Dfe5eF8C79341D1C5b7", + "versions": [ + { + "cid": "bafkreibm2j2doneeuabi6crd3bguaj3ua4c6hpwrtfzje762noq63rkrhy", + "time": 1715358132 + }, + { + "cid": "bafkreibm2j2doneeuabi6crd3bguaj3ua4c6hpwrtfzje762noq63rkrhy", + "time": 1715358684 + }, + { + "cid": "bafkreih3nstwkg6iakafg45kwshw6db4hhshsuhkwruebe5ziydzevmney", + "time": 1715866908 + }, + { + "cid": "bafkreih3nstwkg6iakafg45kwshw6db4hhshsuhkwruebe5ziydzevmney", + "time": 1715868780 + }, + { + "cid": "bafkreih3nstwkg6iakafg45kwshw6db4hhshsuhkwruebe5ziydzevmney", + "time": 1715978748 + }, + { + "cid": "bafkreifgflgcb7ldns2k5eobjqzo566zt4d7hisqzo3tav5flyc7sprpyq", + "time": 1716021840 + } + ], + "validationError": false + }, + { + "dpid": "212", + "owner": "0x48801eB4DD5e49A9849055ddfD2388f704d96701", + "versions": [ + { + "cid": "bafkreic7t74rbgla2l5jv6dafmtccpzqkechgweeyqqs7tsyemvc3jefae", + "time": 1715851488 + } + ], + "validationError": false + }, + { + "dpid": "213", + "owner": "0x08E424b69851b7b210bA3E5E4233Ca6fcc1ADEdb", + "versions": [ + { + "cid": "bafkreiezhimuxptmz5n6yimve6ydawge4ghihw3r7u45ky65c2ryaqqmce", + "time": 1716409680 + }, + { + "cid": "bafkreia6tgjva2f2bgjs4x3w5t53iiauj6c72o3nurztlc5pzcnicuciou", + "time": 1716826812 + } + ], + "validationError": false + }, + { + "dpid": "214", + "owner": "0x0F81A4d0553f09767027B4c15D0C374B939Cd5F1", + "versions": [ + { + "cid": "bafkreih7ayew5fbjl6qswqxhczbnpvjocbrh25sndnausewyvzyqfqfn3i", + "time": 1717068456 + } + ], + "validationError": false + }, + { + "dpid": "215", + "owner": "0xBaf4a58783150abaAec703E43e6cca151D4Ff475", + "versions": [ + { + "cid": "bafkreiamkomiad6wgakicshmb2jbttwkzvl3pvz7dg3dk4limjudjs7fze", + "time": 1719238548 + }, + { + "cid": "bafkreicgr4sw55zkzcvsymlbzuwycyumbaxbddsfs4fmpqgop26ao6kwai", + "time": 1719239016 + } + ], + "validationError": false + }, + { + "dpid": "216", + "owner": "0xBaf4a58783150abaAec703E43e6cca151D4Ff475", + "versions": [ + { + "cid": "bafkreiahiziyaeq433h3kcujkgiiv5ttk3ouls6clr66o3t6dfaecmjleq", + "time": 1719238956 + } + ], + "validationError": false + }, + { + "dpid": "217", + "owner": "0xBaf4a58783150abaAec703E43e6cca151D4Ff475", + "versions": [ + { + "cid": "bafkreif2l2vqwzocmgmfyy2ejvrqd5uhhrzkqk45hthwcw4mt4oz7i4u7q", + "time": 1719239808 + } + ], + "validationError": false + }, + { + "dpid": "218", + "owner": "0xBaf4a58783150abaAec703E43e6cca151D4Ff475", + "versions": [ + { + "cid": "bafkreigldutspcrrahapdsj7sr4zrikxirwsjbqvrcuzlwwyuk2zhtho2e", + "time": 1719240072 + } + ], + "validationError": false + }, + { + "dpid": "219", + "owner": "0xBaf4a58783150abaAec703E43e6cca151D4Ff475", + "versions": [ + { + "cid": "bafkreifkiw3ckd6n6nkzhx3benfz2ct4acqrq3kaepv2dod4b3twwnxsti", + "time": 1719242676 + } + ], + "validationError": false + }, + { + "dpid": "220", + "owner": "0xBaf4a58783150abaAec703E43e6cca151D4Ff475", + "versions": [ + { + "cid": "bafkreift27e5crnj2osffmq6rmbrxaade74cang4gjwwo6eurf5owodm2a", + "time": 1719242796 + } + ], + "validationError": false + }, + { + "dpid": "221", + "owner": "0xBaf4a58783150abaAec703E43e6cca151D4Ff475", + "versions": [ + { + "cid": "bafkreic6ief4i2lfgi7mz27nqxn7usvs7huh77nmzpactmi63v6dbzv2nq", + "time": 1719243324 + } + ], + "validationError": false + }, + { + "dpid": "222", + "owner": "0xBaf4a58783150abaAec703E43e6cca151D4Ff475", + "versions": [ + { + "cid": "bafkreiaurllsr2nc4ejbuq2dc35aftk3din4l7fumw2csslajq43e67tsa", + "time": 1719243792 + } + ], + "validationError": false + }, + { + "dpid": "223", + "owner": "0xBaf4a58783150abaAec703E43e6cca151D4Ff475", + "versions": [ + { + "cid": "bafkreig2zp6cnz2sifbdtwliamt2edelxvdioc5bph4pxetkvknfvavfvi", + "time": 1719244032 + } + ], + "validationError": false + }, + { + "dpid": "224", + "owner": "0xBaf4a58783150abaAec703E43e6cca151D4Ff475", + "versions": [ + { + "cid": "bafkreicuitjqpveaxjoqil77g5l2apesvrmowym5p5n4b4xbneh5eonaay", + "time": 1719244260 + } + ], + "validationError": false + } + ] +} \ No newline at end of file diff --git a/desci-contracts/package.json b/desci-contracts/package.json index 1ead0e72..2260c9b8 100644 --- a/desci-contracts/package.json +++ b/desci-contracts/package.json @@ -1,7 +1,7 @@ { "name": "@desci-labs/desci-contracts", "description": "Smart contracts implementing DeSci Nodes on-chain state and logic", - "version": "0.2.5-rc7", + "version": "0.2.6", "license": "MIT", "scripts": { "test": "hardhat clean && hardhat test", From 9c6d7f498b18c93f8d601a475cadbe40257a4abe Mon Sep 17 00:00:00 2001 From: m0ar Date: Tue, 25 Jun 2024 11:46:35 +0200 Subject: [PATCH 215/278] contracts: fix docs in activateAliasRegistry.mjs --- .../alias-registry/activateAliasRegistry.mjs | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/desci-contracts/scripts/alias-registry/activateAliasRegistry.mjs b/desci-contracts/scripts/alias-registry/activateAliasRegistry.mjs index 89ead36e..d4a13545 100644 --- a/desci-contracts/scripts/alias-registry/activateAliasRegistry.mjs +++ b/desci-contracts/scripts/alias-registry/activateAliasRegistry.mjs @@ -1,25 +1,14 @@ /** - * ALIAS REGISTRY MIGRATION + * ALIAS REGISTRY ACTIVATION * - * Deploys a new dPID alias registry, through proxy. Imports existing dPID's as - * legacy entries, and validates the correctness of these imports afterward. - * If the imports are interrupted, it can be continued using the syncAliasRegistryMigration.mjs - * script. The registry is initialized in a paused state, meaning minting new dPID's - * is disabled, but imports and other administration like configuring the dPID - * counter can still be done. - * - * The script performs the following actions: - * - Deploys new instance of the registry - * - Imports legacy dPID's, validating correctness - * - Immediately pauses minting of new dPID's - * - * Steps required to fully activate: - * - Admin calls `setNextDpid` to whatever is the next when legacy contract is disabled - * - Admin calls `unpause` to allow minting new dPID's + * Activates a dPID alias contract, by setting the next available dPID and + * unpausing it. The old contract needs to be paused, so no overlapping dPID's + * are minted. Alternatively, set the next dPID with some gap in between. * * Required arguments (env variables): - * 1. PRIVATE_KEY - Owner/admin identity (see hardhat.config.ts) - * 2. ENV - Environment to sync legacy entires from ("dev" or "prod") + * 1. REGISTRY_ADDRESS - Address of existing alias registry (proxy) contract + * 2. PRIVATE_KEY - Owner/admin identity (see hardhat.config.ts) + * 2. NEXT_DPID - The next mintable dPID */ import hardhat from "hardhat"; const { ethers, hardhatArguments } = hardhat; From 1049b2244bc947408e4674411224da5a849b65ed Mon Sep 17 00:00:00 2001 From: m0ar Date: Tue, 25 Jun 2024 12:12:43 +0200 Subject: [PATCH 216/278] server: change server to use op sepolia for prod alias registry, bump contracts pkg --- desci-server/package.json | 2 +- desci-server/src/controllers/nodes/createDpid.ts | 8 ++++---- desci-server/yarn.lock | 8 ++++---- yarn.lock | 4 ---- 4 files changed, 9 insertions(+), 13 deletions(-) delete mode 100644 yarn.lock diff --git a/desci-server/package.json b/desci-server/package.json index ba987795..3d38e909 100755 --- a/desci-server/package.json +++ b/desci-server/package.json @@ -57,7 +57,7 @@ "@automerge/automerge-repo-network-websocket": "^1.0.19", "@aws-sdk/client-s3": "^3.537.0", "@desci-labs/desci-codex-lib": "^1.1.7", - "@desci-labs/desci-contracts": "0.2.5-rc7", + "@desci-labs/desci-contracts": "^0.2.6", "@desci-labs/desci-models": "0.2.9", "@honeycombio/opentelemetry-node": "^0.3.2", "@ipld/dag-pb": "^4.0.0", diff --git a/desci-server/src/controllers/nodes/createDpid.ts b/desci-server/src/controllers/nodes/createDpid.ts index 5811227c..f119bcfa 100644 --- a/desci-server/src/controllers/nodes/createDpid.ts +++ b/desci-server/src/controllers/nodes/createDpid.ts @@ -29,8 +29,8 @@ const CERAMIC_API_URLS = { const OPTIMISM_RPC_URLS = { local: 'http://host.docker.internal:8545', - dev: 'https://reverse-proxy-dev.desci.com/rpc_opt_sepolia', - prod: 'https://reverse-proxy-prod.desci.com/rpc_opt_mainnet', + opSepolia: 'https://reverse-proxy-dev.desci.com/rpc_opt_sepolia', + opMainnet: 'https://reverse-proxy-prod.desci.com/rpc_opt_mainnet', } as const; /** Not secret: pre-seeded ganache account for local dev */ @@ -50,11 +50,11 @@ if (apiServerUrl.includes('localhost') || apiServerUrl.includes('host.docker.int } else if (apiServerUrl.includes('dev') || apiServerUrl.includes('staging')) { aliasRegistryAddress = contracts.devDpidAliasInfo.proxies.at(0).address; ceramicApiUrl = CERAMIC_API_URLS.dev; - optimismRpcUrl = OPTIMISM_RPC_URLS.dev; + optimismRpcUrl = OPTIMISM_RPC_URLS.opSepolia; } else if (process.env.NODE_ENV === 'production') { aliasRegistryAddress = contracts.prodDpidAliasInfo.proxies.at(0).address; ceramicApiUrl = CERAMIC_API_URLS.prod; - optimismRpcUrl = OPTIMISM_RPC_URLS.prod; + optimismRpcUrl = OPTIMISM_RPC_URLS.opSepolia; } else { console.error('Cannot derive contract address due to ambiguous environment'); throw new Error('Ambiguous environment'); diff --git a/desci-server/yarn.lock b/desci-server/yarn.lock index 96236887..5b344985 100644 --- a/desci-server/yarn.lock +++ b/desci-server/yarn.lock @@ -2205,10 +2205,10 @@ key-did-resolver "^4.0.0" uint8arrays "^4.0.6" -"@desci-labs/desci-contracts@0.2.5-rc7": - version "0.2.5-rc7" - resolved "https://registry.yarnpkg.com/@desci-labs/desci-contracts/-/desci-contracts-0.2.5-rc7.tgz#a8a49c9518107305be712bcbdbb352faa4057a44" - integrity sha512-W1hf+mv5KWnqCuXX3uBiBsll+iMD82GJbsGs3huzH6qY2TySVFUCLov017B0RGz2Ap1WRB9w7h3o9CEwDuV5lQ== +"@desci-labs/desci-contracts@^0.2.6": + version "0.2.6" + resolved "https://registry.yarnpkg.com/@desci-labs/desci-contracts/-/desci-contracts-0.2.6.tgz#71e0dd8b953f8729fce899cdf6cdf4898acbcb9b" + integrity sha512-1PTKgGtHIrWZ/UMIrOs/tVrAdGUQC+QW+OLiBlEi2sV2UXsazZTjMbiGxjErP+VBPoMkFbfsWiLMvgjs6Pw/5A== "@desci-labs/desci-models@0.2.9": version "0.2.9" diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index fb57ccd1..00000000 --- a/yarn.lock +++ /dev/null @@ -1,4 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - From f54400987c6729fa0562cb96aa7cde384e9e04da Mon Sep 17 00:00:00 2001 From: m0ar Date: Tue, 25 Jun 2024 12:14:23 +0200 Subject: [PATCH 217/278] nodeslib: use op sepolia RPC for prod contracts, bump contracts pkg --- nodes-lib/package-lock.json | 14 +++++++------- nodes-lib/package.json | 4 ++-- nodes-lib/src/config/chain.ts | 24 ++++++++++++------------ 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/nodes-lib/package-lock.json b/nodes-lib/package-lock.json index 84fd74ba..d27e4227 100644 --- a/nodes-lib/package-lock.json +++ b/nodes-lib/package-lock.json @@ -10,7 +10,7 @@ "license": "MIT", "dependencies": { "@desci-labs/desci-codex-lib": "^1.1.7", - "@desci-labs/desci-contracts": "^0.2.5-rc7", + "@desci-labs/desci-contracts": "^0.2.6", "@desci-labs/desci-models": "^0.2.3-rc1", "@didtools/cacao": "^3.0.1", "@didtools/pkh-ethereum": "^0.5.0", @@ -1010,9 +1010,9 @@ } }, "node_modules/@desci-labs/desci-contracts": { - "version": "0.2.5-rc7", - "resolved": "https://registry.npmjs.org/@desci-labs/desci-contracts/-/desci-contracts-0.2.5-rc7.tgz", - "integrity": "sha512-W1hf+mv5KWnqCuXX3uBiBsll+iMD82GJbsGs3huzH6qY2TySVFUCLov017B0RGz2Ap1WRB9w7h3o9CEwDuV5lQ==" + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/@desci-labs/desci-contracts/-/desci-contracts-0.2.6.tgz", + "integrity": "sha512-1PTKgGtHIrWZ/UMIrOs/tVrAdGUQC+QW+OLiBlEi2sV2UXsazZTjMbiGxjErP+VBPoMkFbfsWiLMvgjs6Pw/5A==" }, "node_modules/@desci-labs/desci-models": { "version": "0.2.3-rc1", @@ -10840,9 +10840,9 @@ } }, "@desci-labs/desci-contracts": { - "version": "0.2.5-rc7", - "resolved": "https://registry.npmjs.org/@desci-labs/desci-contracts/-/desci-contracts-0.2.5-rc7.tgz", - "integrity": "sha512-W1hf+mv5KWnqCuXX3uBiBsll+iMD82GJbsGs3huzH6qY2TySVFUCLov017B0RGz2Ap1WRB9w7h3o9CEwDuV5lQ==" + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/@desci-labs/desci-contracts/-/desci-contracts-0.2.6.tgz", + "integrity": "sha512-1PTKgGtHIrWZ/UMIrOs/tVrAdGUQC+QW+OLiBlEi2sV2UXsazZTjMbiGxjErP+VBPoMkFbfsWiLMvgjs6Pw/5A==" }, "@desci-labs/desci-models": { "version": "0.2.3-rc1", diff --git a/nodes-lib/package.json b/nodes-lib/package.json index 9a6fa008..897891b9 100644 --- a/nodes-lib/package.json +++ b/nodes-lib/package.json @@ -1,6 +1,6 @@ { "name": "@desci-labs/nodes-lib", - "version": "0.0.7-rc0", + "version": "0.0.7", "homepage": "https://github.com/desci-labs/nodes#readme", "description": "Stand-alone client library for interacting with desci-server", "repository": { @@ -27,7 +27,7 @@ }, "dependencies": { "@desci-labs/desci-codex-lib": "^1.1.7", - "@desci-labs/desci-contracts": "^0.2.5-rc7", + "@desci-labs/desci-contracts": "^0.2.6", "@desci-labs/desci-models": "^0.2.3-rc1", "@didtools/cacao": "^3.0.1", "@didtools/pkh-ethereum": "^0.5.0", diff --git a/nodes-lib/src/config/chain.ts b/nodes-lib/src/config/chain.ts index d11da6fc..01e6bfb8 100644 --- a/nodes-lib/src/config/chain.ts +++ b/nodes-lib/src/config/chain.ts @@ -42,11 +42,11 @@ export const LEGACY_CHAIN_CONFIGS = { chainId: "1337", rpcUrl: "http://localhost:8545", researchObjectConnector: signerOrProvider => tc.ResearchObjectV2__factory.connect( - contracts.localRoInfo.proxies.at(0)!.address, + contracts.localRoInfo.proxies[0].address, signerOrProvider ), dpidRegistryConnector: signerOrProvider => tc.DpidRegistry__factory.connect( - contracts.localDpidInfo.proxies.at(0)!.address, + contracts.localDpidInfo.proxies[0].address, signerOrProvider ), }, @@ -54,11 +54,11 @@ export const LEGACY_CHAIN_CONFIGS = { chainId: "11155111", rpcUrl: "https://reverse-proxy-dev.desci.com/rpc_sepolia", researchObjectConnector: signerOrProvider => tc.ResearchObjectV2__factory.connect( - contracts.devRoInfo.proxies.at(0)!.address, + contracts.devRoInfo.proxies[0].address, signerOrProvider ), dpidRegistryConnector: signerOrProvider => tc.DpidRegistry__factory.connect( - contracts.devDpidInfo.proxies.at(0)!.address, + contracts.devDpidInfo.proxies[0].address, signerOrProvider ), }, @@ -66,11 +66,11 @@ export const LEGACY_CHAIN_CONFIGS = { chainId: "11155111", rpcUrl: "https://reverse-proxy-staging.desci.com/rpc_sepolia", researchObjectConnector: signerOrProvider => tc.ResearchObjectV2__factory.connect( - contracts.devRoInfo.proxies.at(0)!.address, + contracts.devRoInfo.proxies[0].address, signerOrProvider ), dpidRegistryConnector: signerOrProvider => tc.DpidRegistry__factory.connect( - contracts.devDpidInfo.proxies.at(0)!.address, + contracts.devDpidInfo.proxies[0].address, signerOrProvider ), }, @@ -78,11 +78,11 @@ export const LEGACY_CHAIN_CONFIGS = { chainId: "11155111", rpcUrl: "https://reverse-proxy-prod.desci.com/rpc_sepolia", researchObjectConnector: signerOrProvider => tc.ResearchObjectV2__factory.connect( - contracts.prodRoInfo.proxies.at(0)!.address, + contracts.prodRoInfo.proxies[0].address, signerOrProvider ), dpidRegistryConnector: signerOrProvider => tc.DpidRegistry__factory.connect( - contracts.prodDpidInfo.proxies.at(0)!.address, + contracts.prodDpidInfo.proxies[0].address, signerOrProvider ), }, @@ -101,7 +101,7 @@ export const CHAIN_CONFIGS = { chainId: "11155420", rpcUrl: "https://reverse-proxy-dev.desci.com/rpc_opt_sepolia", dpidAliasRegistryConnector: signerOrProvider => tc.DpidAliasRegistry__factory.connect( - contracts.devDpidAliasInfo.proxies.at(0)!.address, + contracts.devDpidAliasInfo.proxies[0].address, signerOrProvider, ), }, @@ -109,15 +109,15 @@ export const CHAIN_CONFIGS = { chainId: "11155420", rpcUrl: "https://reverse-proxy-staging.desci.com/rpc_opt_sepolia", dpidAliasRegistryConnector: signerOrProvider => tc.DpidAliasRegistry__factory.connect( - contracts.devDpidAliasInfo.proxies.at(0)!.address, + contracts.devDpidAliasInfo.proxies[0].address, signerOrProvider, ), }, prod: { chainId: "10", - rpcUrl: "https://reverse-proxy-prod.desci.com/rpc_opt_mainnet", + rpcUrl: "https://reverse-proxy-prod.desci.com/rpc_opt_sepolia", dpidAliasRegistryConnector: signerOrProvider => tc.DpidAliasRegistry__factory.connect( - contracts.prodDpidAliasInfo.proxies.at(0)!.address, + contracts.prodDpidAliasInfo.proxies[0].address, signerOrProvider, ), } From 30586e7f702cd2cd9763bd8885e5d9979134562e Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Tue, 25 Jun 2024 18:46:17 +0200 Subject: [PATCH 218/278] fix: community radar/curation node resolver should resolve last published manifest --- desci-server/src/controllers/communities/feed.ts | 6 +----- desci-server/src/controllers/communities/util.ts | 7 +++---- desci-server/src/services/Communities.ts | 4 +++- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/desci-server/src/controllers/communities/feed.ts b/desci-server/src/controllers/communities/feed.ts index 0c014209..875df854 100644 --- a/desci-server/src/controllers/communities/feed.ts +++ b/desci-server/src/controllers/communities/feed.ts @@ -19,10 +19,7 @@ export const getCommunityFeed = async (req: Request, res: Response, next: NextFu // accounts for only engagements on community selected attestations const nodes = await asyncMap(curatedNodes, async (node) => { const engagements = await attestationService.getNodeEngagementSignals(node.nodeDpid10); - // const verifiedEngagements = await communityService.getNodeVerifiedEngagementsByCommunity( - // node.nodeDpid10, - // parseInt(req.params.communityId), - // ); + const verifiedEngagements = node.NodeAttestation.reduce( (total, claim) => ({ reactions: total.reactions + claim.reactions, @@ -79,7 +76,6 @@ export const getAllFeeds = async (req: Request, res: Response, next: NextFunctio }; }); - logger.info({ nodes }, 'CHECK Verification SignalS'); let data = await Promise.all(nodes.map(resolveLatestNode)); /** diff --git a/desci-server/src/controllers/communities/util.ts b/desci-server/src/controllers/communities/util.ts index 657e6637..a84da974 100644 --- a/desci-server/src/controllers/communities/util.ts +++ b/desci-server/src/controllers/communities/util.ts @@ -40,7 +40,8 @@ export const resolveLatestNode = async (radar: Partial) => { node['publishedDate'] = publisedVersions[0].createdAt; radar.node = node; - let gatewayUrl = discovery.manifestUrl; + logger.info({ publisedVersions }, 'publisedVersions'); + let gatewayUrl = publisedVersions[0].manifestUrl; // discovery.manifestUrl; try { gatewayUrl = cleanupManifestUrl(gatewayUrl); @@ -48,9 +49,7 @@ export const resolveLatestNode = async (radar: Partial) => { const manifest = (await axios.get(gatewayUrl)).data; radar.manifest = manifest; - logger.info({ manifest }, '[SHOW API GET DRAFT MANIFEST]'); - - logger.info({}, 'Retrive DraftManifest For /SHOW'); + logger.info({ manifest }, '[SHOW API GET LAST PUBLISHED MANIFEST]'); } catch (err) { const manifest = await repoService.getDraftManifest(uuid as NodeUuid); radar.manifest = manifest; diff --git a/desci-server/src/services/Communities.ts b/desci-server/src/services/Communities.ts index ab01d5a4..bb23fd24 100644 --- a/desci-server/src/services/Communities.ts +++ b/desci-server/src/services/Communities.ts @@ -2,7 +2,7 @@ import { Attestation, CommunityMembershipRole, NodeAttestation, NodeFeedItem, Pr import _ from 'lodash'; import { prisma } from '../client.js'; -import { DuplicateDataError } from '../internal.js'; +import { DuplicateDataError, logger } from '../internal.js'; import { attestationService } from '../internal.js'; export type CommunityRadarNode = NodeAttestation & { annotations: number; reactions: number; verifications: number }; @@ -124,9 +124,11 @@ export class CommunityService { */ async getCuratedNodes(communityId: number) { const nodesOnRadar = await this.getCommunityRadar(communityId); + logger.info({ nodesOnRadar, communityId }, 'Radar'); const curated = nodesOnRadar.filter((node) => node.NodeAttestation.every((attestation) => attestation.verifications > 0), ); + logger.info({ curated, communityId }, 'CURATED'); return curated; } From b419337f92e036db4d034b2748341842cf9d776d Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Tue, 25 Jun 2024 20:01:55 +0000 Subject: [PATCH 219/278] create proxy controller for generating ephemeral previews on media server --- .../controllers/proxy/ephemeralThumbnail.ts | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 desci-server/src/controllers/proxy/ephemeralThumbnail.ts diff --git a/desci-server/src/controllers/proxy/ephemeralThumbnail.ts b/desci-server/src/controllers/proxy/ephemeralThumbnail.ts new file mode 100644 index 00000000..05511158 --- /dev/null +++ b/desci-server/src/controllers/proxy/ephemeralThumbnail.ts @@ -0,0 +1,50 @@ +import { Readable } from 'stream'; + +import type { Request, Response } from 'express'; + +import { logger as parentLogger } from '../../logger.js'; +import { thumbnailsService } from '../../services/Thumbnails.js'; + +const logger = parentLogger.child({ + module: 'NODES::EphemeralThumbnail', +}); + +type EphemeralThumbnailReqQuery = { + height?: string; +}; + +type EphemeralThumbnailResponse = { + ok: boolean; + error?: string; +}; + +export const ephemeralThumbnail = async ( + req: Request, + res: Response, +): Promise => { + const user = (req as any).user; + const height = req.query.height ? parseInt(req.query.height) : undefined; + + logger.trace({ fn: 'Generating ephemeral thumbnail', userId: user?.id, height }); + + if (!req.file) { + logger.error('No file uploaded'); + res.status(400).json({ ok: false, error: 'No file uploaded.' }); + return; + } + + try { + const fileStream = Readable.from(req.file.buffer); + const thumbnailStream = await thumbnailsService.generateThumbnailFromStream( + fileStream, + req.file.originalname, + height, + ); + + res.setHeader('Content-Type', 'image/png'); + thumbnailStream.pipe(res); + } catch (error) { + logger.error('Error generating ephemeral thumbnail:', error); + res.status(500).json({ ok: false, error: 'Error generating thumbnail' }); + } +}; From bb1e7cdd4ee66253cfa3d0fc74cef98f2e4624a8 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Tue, 25 Jun 2024 20:03:43 +0000 Subject: [PATCH 220/278] add proxy thumbnail gen route --- desci-server/src/routes/v1/services.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/desci-server/src/routes/v1/services.ts b/desci-server/src/routes/v1/services.ts index 548be06e..37f5e2f4 100644 --- a/desci-server/src/routes/v1/services.ts +++ b/desci-server/src/routes/v1/services.ts @@ -1,10 +1,17 @@ import { Router } from 'express'; +import multer from 'multer'; +import { ephemeralThumbnail } from '../../controllers/proxy/ephemeralThumbnail.js'; import { orcidDid, orcidProfile } from '../../controllers/proxy/orcidProfile.js'; +import { ensureUser } from '../../internal.js'; const router = Router(); +const upload = multer(); + router.get('/orcid/profile/:orcidId', [], orcidProfile); router.get('/orcid/did/:did', [], orcidDid); +router.post('/thumbnails/ephemeral', [ensureUser, upload.single('file')], ephemeralThumbnail); + export default router; From 1eb08ac0ef21172bc3f76b539b56c776f003be19 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Tue, 25 Jun 2024 20:04:33 +0000 Subject: [PATCH 221/278] adjust thumbnail gen service on backend to accept file streams --- desci-server/src/services/Thumbnails.ts | 42 +++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/desci-server/src/services/Thumbnails.ts b/desci-server/src/services/Thumbnails.ts index 5c3b4f4c..76f1a9d4 100644 --- a/desci-server/src/services/Thumbnails.ts +++ b/desci-server/src/services/Thumbnails.ts @@ -1,11 +1,14 @@ +import { Readable } from 'stream'; + import { ResearchObjectComponentType } from '@desci-labs/desci-models'; import axios from 'axios'; +import FormData from 'form-data'; import { prisma } from '../client.js'; import { logger as parentLogger } from '../logger.js'; import { ensureUuidEndsWithDot } from '../utils.js'; -import { getManifestByCid, getManifestFromNode, pinNewFiles } from './data/processing.js'; +import { getManifestByCid } from './data/processing.js'; import { pinFile } from './ipfs.js'; import { NodeUuid, getLatestManifestFromNode } from './manifestRepo.js'; @@ -107,7 +110,7 @@ export class ThumbnailsService { // Generate the thumbnail // debugger; const thumbnailStream = await axios.post( - `${process.env.ISOLATED_MEDIA_SERVER_URL}/v1/thumbnails?height${heightPx}`, + `${process.env.ISOLATED_MEDIA_SERVER_URL}/v1/thumbnails?height=${heightPx}`, { cid: cid, fileName: componentFileName }, { responseType: 'stream', @@ -137,6 +140,41 @@ export class ThumbnailsService { // Return the CID return { componentCid: cid, height: heightPx, thumbnailCid: pinned.cid }; } + + async generateThumbnailFromStream( + fileStream: Readable, + fileName: string, + heightPx: HeightPx = HEIGHT_PX, + ): Promise { + if (process.env.ISOLATED_MEDIA_SERVER_URL === undefined) { + logger.error('process.env.ISOLATED_MEDIA_SERVER_URL is not defined'); + throw new Error('Isolated media server URL is not defined'); + } + + try { + const form = new FormData(); + form.append('file', fileStream, { + filename: fileName, + contentType: 'application/octet-stream', + }); + + const response = await axios.post( + `${process.env.ISOLATED_MEDIA_SERVER_URL}/v1/thumbnails?height=${heightPx}`, + form, + { + headers: { + ...form.getHeaders(), + }, + responseType: 'stream', + }, + ); + + return response.data; + } catch (error) { + logger.error('Error generating thumbnail from stream:', error); + throw new Error('Failed to generate thumbnail from stream'); + } + } } export const thumbnailsService = new ThumbnailsService(); From 8382c23464dad4871790aac49e3a27d4a0a73baf Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Tue, 25 Jun 2024 20:05:18 +0000 Subject: [PATCH 222/278] fix media server contrroller/multer middleware to correctly pass up the stream received from the backend --- .../src/controllers/thumbnails/create.ts | 14 +++++--------- .../src/middleware/uploadHandler.ts | 11 +++++++---- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/desci-media-isolated/src/controllers/thumbnails/create.ts b/desci-media-isolated/src/controllers/thumbnails/create.ts index 360883e4..f289fa34 100644 --- a/desci-media-isolated/src/controllers/thumbnails/create.ts +++ b/desci-media-isolated/src/controllers/thumbnails/create.ts @@ -24,19 +24,17 @@ const __dirname = path.dirname(__filename); const BASE_TEMP_DIR = path.resolve(__dirname, '../../..', TEMP_DIR); export const generateThumbnail = async (req: GenerateThumbnailRequest, res: Response) => { - const { cid, fileName } = req.body; + const { cid } = req.body; const height = parseInt(req.query.height || '300'); - const finalFileName = fileName || (req.file && req.file.originalname); - if (!finalFileName) throw new BadRequestError('Missing fileName in request body or file upload'); - try { let thumbnailPath: string; if (cid) { - thumbnailPath = await ThumbnailsService.generateThumbnailFromCid(cid, finalFileName, height); + if (!req.body.fileName) throw new BadRequestError('fileName is required when using cid'); + thumbnailPath = await ThumbnailsService.generateThumbnailFromCid(cid, req.body.fileName, height); } else if (req.file) { - thumbnailPath = await ThumbnailsService.generateThumbnailFromFile(req.file.path, finalFileName, height); + thumbnailPath = await ThumbnailsService.generateThumbnailFromFile(req.file.path, req.file.originalname, height); } else { throw new BadRequestError('Either cid or file is required'); } @@ -45,14 +43,12 @@ export const generateThumbnail = async (req: GenerateThumbnailRequest, res: Resp fs.access(fullThumbnailPath, fs.constants.F_OK, (err) => { if (err) { - throw new NotFoundError(`Thumbnail not found for file: ${finalFileName}`); + throw new NotFoundError(`Thumbnail not found for file`); } res.setHeader('Content-Type', 'image/png'); const readStream = fs.createReadStream(fullThumbnailPath); readStream.pipe(res); }); - - return res.status(200); } catch (err: any) { return res.status(500).json({ message: err.message }); } diff --git a/desci-media-isolated/src/middleware/uploadHandler.ts b/desci-media-isolated/src/middleware/uploadHandler.ts index f8d764fc..678de7ea 100644 --- a/desci-media-isolated/src/middleware/uploadHandler.ts +++ b/desci-media-isolated/src/middleware/uploadHandler.ts @@ -22,9 +22,12 @@ const upload = multer({ storage: storage }); // Middleware to determine if it's a file upload or JSON request export const uploadHandler = (req: Request, res: Response, next: NextFunction) => { - if (req.is('multipart/form-data')) { - upload.single('file')(req, res, next); - } else { + upload.single('file')(req, res, (err) => { + if (err instanceof multer.MulterError) { + return res.status(400).json({ error: 'File upload error' }); + } else if (err) { + return res.status(500).json({ error: 'Server error during file upload' }); + } next(); - } + }); }; From 6e2780d3c51e6b33aad1b81660ca83b4efe74952 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Wed, 26 Jun 2024 10:37:27 +0200 Subject: [PATCH 223/278] fix: draft node data leak --- desci-server/src/controllers/communities/util.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/desci-server/src/controllers/communities/util.ts b/desci-server/src/controllers/communities/util.ts index a84da974..059c8599 100644 --- a/desci-server/src/controllers/communities/util.ts +++ b/desci-server/src/controllers/communities/util.ts @@ -29,19 +29,19 @@ export const resolveLatestNode = async (radar: Partial) => { logger.warn({ uuid }, 'uuid not found'); } - const selectAttributes = ['manifestUrl', 'ownerId', 'title', 'NodeCover']; + const selectAttributes: (keyof typeof discovery)[] = ['ownerId', 'NodeCover']; const node: Partial = _.pick(discovery, selectAttributes); - const publisedVersions = + const publishedVersions = (await prisma.$queryRaw`SELECT * from "NodeVersion" where "nodeId" = ${discovery.id} AND "transactionId" IS NOT NULL ORDER BY "createdAt" DESC`) as NodeVersion[]; // const nodeVersions = (await getNodeVersion - logger.info({ uuid: discovery.uuid, publisedVersions }, 'Resolve node'); - node['versions'] = publisedVersions.length; - node['publishedDate'] = publisedVersions[0].createdAt; + logger.info({ uuid: discovery.uuid, publishedVersions }, 'Resolve node'); + node['versions'] = publishedVersions.length; + node['publishedDate'] = publishedVersions[0].createdAt; + node.manifestUrl = publishedVersions[0].manifestUrl; radar.node = node; - logger.info({ publisedVersions }, 'publisedVersions'); - let gatewayUrl = publisedVersions[0].manifestUrl; // discovery.manifestUrl; + let gatewayUrl = publishedVersions[0].manifestUrl; try { gatewayUrl = cleanupManifestUrl(gatewayUrl); From fb88b5e8e3a3ca4419a139d21904ed04ae73450c Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Wed, 26 Jun 2024 10:54:47 +0200 Subject: [PATCH 224/278] refactor: apply formatting changes and clean ups --- .env.example | 2 +- desci-server/src/controllers/nodes/doi.ts | 9 ++------- desci-server/src/routes/v1/nodes.ts | 2 +- desci-server/src/services/AutomatedMetadata.ts | 4 ++-- desci-server/src/services/crossRef/client.ts | 2 +- desci-server/src/services/index.ts | 3 +-- 6 files changed, 8 insertions(+), 14 deletions(-) diff --git a/.env.example b/.env.example index c1beb2d7..2eae5d58 100755 --- a/.env.example +++ b/.env.example @@ -133,5 +133,5 @@ CROSSREF_API_KEY= CROSSREF_EMAIL= # Automated metadata -AUTOMATED_METADATA_API= +AUTOMATED_METADATA_API=http://host.docker.internal:5005 AUTOMATED_METADATA_API_KEY= \ No newline at end of file diff --git a/desci-server/src/controllers/nodes/doi.ts b/desci-server/src/controllers/nodes/doi.ts index 9b4b1195..4470acfa 100644 --- a/desci-server/src/controllers/nodes/doi.ts +++ b/desci-server/src/controllers/nodes/doi.ts @@ -82,11 +82,6 @@ export const automateManuscriptDoi = async (req: RequestWithNode, res: Response, metadata = transformWorkToMetadata(matchFound); } - // if (!(works.ok && matchFound)) { - // logger.info({ data: works?.data?.message?.items }, 'DOI Not Found'); - // throw new NotFoundError('DOI not found'); - // } - // pull metadata from AM service metadata = await metadataClient.getResourceMetadata({ cid: component.payload.cid, @@ -114,10 +109,10 @@ export const automateManuscriptDoi = async (req: RequestWithNode, res: Response, }); } - if (metadata?.abstract) { + if (metadata?.abstract.trim()) { actions.push({ type: 'Update Description', - description: metadata.abstract, + description: metadata.abstract.trim(), }); } diff --git a/desci-server/src/routes/v1/nodes.ts b/desci-server/src/routes/v1/nodes.ts index 1b281a1b..7956a697 100755 --- a/desci-server/src/routes/v1/nodes.ts +++ b/desci-server/src/routes/v1/nodes.ts @@ -97,7 +97,7 @@ router.post('/generate-metadata', [ensureUser, validate(generateMetadataSchema)] // doi automation router.post( - '/:uuid/attachManuscriptDoi', + '/:uuid/automate-manuscript', [ensureUser, ensureNodeAccess, validate(attachDoiSchema)], asyncHander(automateManuscriptDoi), ); diff --git a/desci-server/src/services/AutomatedMetadata.ts b/desci-server/src/services/AutomatedMetadata.ts index dcb6917f..01da7c26 100644 --- a/desci-server/src/services/AutomatedMetadata.ts +++ b/desci-server/src/services/AutomatedMetadata.ts @@ -184,9 +184,9 @@ export class AutomatedMetadataClient { (author) => ({ name: author.name, - orcid: author.orcid, role: ResearchObjectV1AuthorRole.AUTHOR, - organisations: author.affiliations, // [{ id: author.affiliation, name: author.affiliation }], + ...(author.affiliations.length > 0 && { organizations: author.affiliations }), + ...(author.orcid && { orcid: author.orcid }), }) as ResearchObjectV1Author, ), }); // diff --git a/desci-server/src/services/crossRef/client.ts b/desci-server/src/services/crossRef/client.ts index d8821503..8c32186f 100644 --- a/desci-server/src/services/crossRef/client.ts +++ b/desci-server/src/services/crossRef/client.ts @@ -104,7 +104,7 @@ class CrossRefClient { */ async getDoiMetadata(doi: string) { const params: { [k: string]: any } = {}; - let url = `https://www.crossref.org/openurl/?pid=myemail@crossref.org&format=unixref&id=${doi}`; + let url = `https://www.crossref.org/openurl/?pid=${this._mailto}&format=unixref&id=${doi}`; const config: RequestInit = { method: 'GET', mode: 'cors', diff --git a/desci-server/src/services/index.ts b/desci-server/src/services/index.ts index 293c3c11..d751bd94 100644 --- a/desci-server/src/services/index.ts +++ b/desci-server/src/services/index.ts @@ -11,7 +11,6 @@ export const crossRefClient = new CrossRefClient( process.env.CROSSREF_EMAIL, ); export const metadataClient = new AutomatedMetadataClient( - // 'process.env.AUTOMATED_METADATA_API', - 'http://host.docker.internal:5005', + process.env.AUTOMATED_METADATA_API, process.env.AUTOMATED_METADATA_API_KEY, ); From 59d7dbb271a3700202a9dddccd3388a18e115d4d Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Wed, 26 Jun 2024 11:42:29 +0200 Subject: [PATCH 225/278] fix: failing test startup due to missing env --- desci-server/src/services/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desci-server/src/services/index.ts b/desci-server/src/services/index.ts index d751bd94..946e7029 100644 --- a/desci-server/src/services/index.ts +++ b/desci-server/src/services/index.ts @@ -11,6 +11,6 @@ export const crossRefClient = new CrossRefClient( process.env.CROSSREF_EMAIL, ); export const metadataClient = new AutomatedMetadataClient( - process.env.AUTOMATED_METADATA_API, + process.env.AUTOMATED_METADATA_API || 'http://host.docker.internal:5005', // remove this after env have been added to CI process.env.AUTOMATED_METADATA_API_KEY, ); From ad0232a9ff42aad8b013088078bcd17dc454cc51 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Wed, 26 Jun 2024 11:44:03 +0200 Subject: [PATCH 226/278] fix formatting --- desci-server/src/routes/v1/nodes.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/desci-server/src/routes/v1/nodes.ts b/desci-server/src/routes/v1/nodes.ts index e4003e75..1b09feaf 100755 --- a/desci-server/src/routes/v1/nodes.ts +++ b/desci-server/src/routes/v1/nodes.ts @@ -1,5 +1,7 @@ import { Router } from 'express'; +import { checkIfPublishedNode } from '../../controllers/nodes/checkIfPublishedNode.js'; +import { checkNodeAccess } from '../../controllers/nodes/checkNodeAccess.js'; import { addContributor } from '../../controllers/nodes/contributions/create.js'; import { deleteContributor } from '../../controllers/nodes/contributions/delete.js'; import { getNodeContributions } from '../../controllers/nodes/contributions/getNodeContributions.js'; @@ -11,6 +13,9 @@ import { createDpid } from '../../controllers/nodes/createDpid.js'; import { dispatchDocumentChange, getNodeDocument } from '../../controllers/nodes/documents.js'; import { feed } from '../../controllers/nodes/feed.js'; import { frontmatterPreview } from '../../controllers/nodes/frontmatterPreview.js'; +import { getDraftNodeStats } from '../../controllers/nodes/getDraftNodeStats.js'; +import { getPublishedNodes } from '../../controllers/nodes/getPublishedNodes.js'; +import { getPublishedNodeStats } from '../../controllers/nodes/getPublishedNodeStats.js'; import { show, draftUpdate, @@ -41,18 +46,13 @@ import { import { retrieveTitle } from '../../controllers/nodes/legacyManifestApi.js'; import { preparePublishPackage } from '../../controllers/nodes/preparePublishPackage.js'; import { prepublish } from '../../controllers/nodes/prepublish.js'; +import { searchNodes } from '../../controllers/nodes/searchNodes.js'; import { listSharedNodes } from '../../controllers/nodes/sharedNodes.js'; import { thumbnails } from '../../controllers/nodes/thumbnails.js'; import { versionDetails } from '../../controllers/nodes/versionDetails.js'; import { asyncHander, attachDoiSchema, attachUser, ensureUserIfPresent, validate } from '../../internal.js'; import { ensureNodeAccess, ensureWriteNodeAccess } from '../../middleware/authorisation.js'; import { ensureUser } from '../../middleware/permissions.js'; -import { getDraftNodeStats } from '../../controllers/nodes/getDraftNodeStats.js'; -import { getPublishedNodeStats } from '../../controllers/nodes/getPublishedNodeStats.js'; -import { checkIfPublishedNode } from '../../controllers/nodes/checkIfPublishedNode.js'; -import { checkNodeAccess } from '../../controllers/nodes/checkNodeAccess.js'; -import { searchNodes } from '../../controllers/nodes/searchNodes.js'; -import { getPublishedNodes } from '../../controllers/nodes/getPublishedNodes.js'; const router = Router(); From bdac22196c0e99823e598ab7af64ba727c857b4a Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Wed, 26 Jun 2024 10:35:35 +0000 Subject: [PATCH 227/278] pino seutp in isolated-media --- desci-media-isolated/package-lock.json | 229 +++++++++++++++++++++++ desci-media-isolated/package.json | 1 + desci-media-isolated/src/utils/logger.ts | 138 ++++++++++++++ 3 files changed, 368 insertions(+) create mode 100644 desci-media-isolated/src/utils/logger.ts diff --git a/desci-media-isolated/package-lock.json b/desci-media-isolated/package-lock.json index 1c31948d..d854697e 100644 --- a/desci-media-isolated/package-lock.json +++ b/desci-media-isolated/package-lock.json @@ -18,6 +18,7 @@ "pdf-lib": "^1.17.1", "pdf2pic": "^3.1.1", "pdflib-fontkit": "^1.8.11", + "pino": "^9.2.0", "tsx": "^4.7.1" }, "devDependencies": { @@ -742,6 +743,17 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -883,6 +895,14 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/axios": { "version": "1.6.7", "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", @@ -899,6 +919,25 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -953,6 +992,29 @@ "node": ">=8" } }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -1518,6 +1580,22 @@ "node": ">= 0.6" } }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, "node_modules/express": { "version": "4.18.2", "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", @@ -1593,6 +1671,14 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-redact": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz", + "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==", + "engines": { + "node": ">=6" + } + }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", @@ -2022,6 +2108,25 @@ "node": ">=0.10.0" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -2420,6 +2525,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/on-exit-leak-free": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -2605,6 +2718,64 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pino": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-9.2.0.tgz", + "integrity": "sha512-g3/hpwfujK5a4oVbaefoJxezLzsDgLcNJeITvC6yrfwYeT9la+edCK42j5QpEQSQCZgTKapXvnQIdgZwvRaZug==", + "dependencies": { + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.1.1", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^1.2.0", + "pino-std-serializers": "^7.0.0", + "process-warning": "^3.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^4.0.1", + "thread-stream": "^3.0.0" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/pino-abstract-transport": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz", + "integrity": "sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==", + "dependencies": { + "readable-stream": "^4.0.0", + "split2": "^4.0.0" + } + }, + "node_modules/pino-abstract-transport/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/pino-abstract-transport/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/pino-std-serializers": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz", + "integrity": "sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==" + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -2614,11 +2785,24 @@ "node": ">= 0.8.0" } }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, + "node_modules/process-warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz", + "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==" + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -2684,6 +2868,11 @@ } ] }, + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==" + }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -2737,6 +2926,14 @@ "node": ">=8.10.0" } }, + "node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "engines": { + "node": ">= 12.13.0" + } + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -2835,6 +3032,14 @@ } ] }, + "node_modules/safe-stable-stringify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", + "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", + "engines": { + "node": ">=10" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -2965,6 +3170,14 @@ "node": ">=8" } }, + "node_modules/sonic-boom": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.0.1.tgz", + "integrity": "sha512-hTSD/6JMLyT4r9zeof6UtuBDpjJ9sO08/nmS5djaA9eozT9oOlNdpXSnzcgj4FTqpk3nkLrs61l4gip9r1HCrQ==", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -2984,6 +3197,14 @@ "source-map": "^0.6.0" } }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "engines": { + "node": ">= 10.x" + } + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -3073,6 +3294,14 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/thread-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.1.0.tgz", + "integrity": "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==", + "dependencies": { + "real-require": "^0.2.0" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", diff --git a/desci-media-isolated/package.json b/desci-media-isolated/package.json index a82ec4b8..8430e3c5 100644 --- a/desci-media-isolated/package.json +++ b/desci-media-isolated/package.json @@ -22,6 +22,7 @@ "pdf-lib": "^1.17.1", "pdf2pic": "^3.1.1", "pdflib-fontkit": "^1.8.11", + "pino": "^9.2.0", "tsx": "^4.7.1" }, "devDependencies": { diff --git a/desci-media-isolated/src/utils/logger.ts b/desci-media-isolated/src/utils/logger.ts new file mode 100644 index 00000000..213fb295 --- /dev/null +++ b/desci-media-isolated/src/utils/logger.ts @@ -0,0 +1,138 @@ +import { AsyncLocalStorage } from 'async_hooks'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +import { pino } from 'pino'; +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +export const als = new AsyncLocalStorage(); + +const logLevel = process.env.PINO_LOG_LEVEL || 'trace'; + +const devTransport = { + target: 'pino-pretty', + level: logLevel, + options: { + colorize: true, + }, +}; + +console.log('[Media Isolated - DIR NAME]::', __dirname, __filename, logLevel); + +const fileTransport = { + target: 'pino/file', + options: { destination: `${__dirname}/../log/server.log` }, + level: 'trace', +}; + +export const logger = pino({ + level: logLevel, + serializers: { + files: omitBuffer, + }, + hooks: { + logMethod: function (inputArgs, method) { + try { + //get caller + const stack = new Error().stack?.split('\n'); + // find first line that is not from this file + + let callerFilePath; + try { + const intermediate = stack?.filter( + (a) => a.includes('file:///') && !(a.includes('/dist/logger.') || a.includes('/src/logger.')), + )[0]; + + if (intermediate) { + callerFilePath = intermediate + .split('(')[1] + .split(')')[0] + .replace('file:///app/desci-server/src/', '') + .replace('file:///app/dist/', ''); + } + } catch (err) { + // callerFilePath = '-unknown-'; + } + + let target = typeof inputArgs[0] == 'string' ? 1 : 0; + let newInputArgs = [...inputArgs]; + + if (!newInputArgs[target]) { + newInputArgs[target] = {}; + } else if (typeof newInputArgs[target] !== 'object') { + const rawValue: any = {}; + rawValue['stringLogs'] = inputArgs; + + rawValue['error'] = + 'this means your pino log statement is incorrectly formatted, check the order of the arguments'; + target = 0; + newInputArgs[target] = { rawValue }; + newInputArgs = [newInputArgs[0], inputArgs[0]]; + } + + newInputArgs[target]['caller'] = callerFilePath; + + newInputArgs[target]['userAuth'] = (als.getStore() as any)?.userAuth; + + const traceId = (als.getStore() as any)?.traceId; + if (traceId) { + newInputArgs[target]['traceId'] = traceId; + + const timingArray = (als.getStore() as any)?.timing; + if (timingArray) { + newInputArgs[target]['traceIndex'] = timingArray.length; + newInputArgs[target]['traceDelta'] = Date.now() - timingArray[timingArray.length - 1]; + } + (als.getStore() as any)?.timing.push(Date.now()); + } + + return method.apply(this, [...newInputArgs] as any); + } catch (err) { + // logger.error({ err }, 'error in logMethod hook'); + return method.apply(this, inputArgs); + } + }, + }, + transport: + process.env.NODE_ENV === 'production' + ? undefined + : { + targets: [devTransport, fileTransport], + }, + redact: { + paths: [ + 'req.headers.cookie', + 'req.headers.authorization', + 'user.email', + '*.user.email', + 'user.name', + '*.user.name', + 'user.website', + '*.user.website', + 'user.googleScholarUrl', + '*.user.googleScholarUrl', + 'user.walletAddress', + '*.user.walletAddress', + 'user.siweNonce', + '*.user.siweNonce', + 'user.orcid', + '*.user.orcid', + 'authorization', + '*.authorization', + '*.Authorization', + 'Authorization', + ], + }, +}); + +function omitBuffer(array: any[]) { + return array.map((obj) => { + const { buffer, ...rest } = obj; + return rest; + }); +} + +process.on('uncaughtException', (err) => { + logger.fatal(err, 'uncaught exception'); +}); From 3f12a559bbdbc8f8bb64e82b73e53263617655a5 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Wed, 26 Jun 2024 13:39:50 +0200 Subject: [PATCH 228/278] fix: null coallasing exception --- desci-server/src/controllers/nodes/doi.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desci-server/src/controllers/nodes/doi.ts b/desci-server/src/controllers/nodes/doi.ts index 4470acfa..65c6b982 100644 --- a/desci-server/src/controllers/nodes/doi.ts +++ b/desci-server/src/controllers/nodes/doi.ts @@ -85,7 +85,7 @@ export const automateManuscriptDoi = async (req: RequestWithNode, res: Response, // pull metadata from AM service metadata = await metadataClient.getResourceMetadata({ cid: component.payload.cid, - doi: doi || component.payload.doi[0], + doi: doi || component.payload?.doi?.[0], }); // todo: pull metadata from crossrefClient#getDoiMetadata From 90c0817d0f9decec9e4219020cb263b9bd8a47b3 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Wed, 26 Jun 2024 12:19:38 +0000 Subject: [PATCH 229/278] replace vanilla logging in media-isolated with pino --- desci-media-isolated/src/index.ts | 7 ++++--- .../src/middleware/errorHandler.ts | 5 ++++- desci-media-isolated/src/services/ipfs.ts | 9 +++++--- desci-media-isolated/src/services/pdf.ts | 21 +++++++++++-------- .../src/services/thumbnails.ts | 11 ++++++---- 5 files changed, 33 insertions(+), 20 deletions(-) diff --git a/desci-media-isolated/src/index.ts b/desci-media-isolated/src/index.ts index 280ad218..8ba60051 100644 --- a/desci-media-isolated/src/index.ts +++ b/desci-media-isolated/src/index.ts @@ -3,11 +3,12 @@ import express from 'express'; import helmet from 'helmet'; import { errorHandler } from './middleware/errorHandler.js'; import routes from './routes/index.js'; +import { logger as parentLogger } from './utils/logger.js'; -// dotenv.config(); +const logger = parentLogger.child({ module: 'Media Isolated Express Config' }); const app = express(); -console.log('process.env.PORT:', process.env.PORT); +logger.info(`process.env.PORT: ${process.env.PORT}`); const PORT = process.env.PORT || 7771; app.use(helmet()); @@ -23,5 +24,5 @@ app.use('/', routes); app.use(errorHandler); app.listen(PORT, () => { - console.log(`[Media Server Isolated]Server is listening on port: ${PORT}`); + logger.info(`[Media Server Isolated]Server is listening on port: ${PORT}`); }); diff --git a/desci-media-isolated/src/middleware/errorHandler.ts b/desci-media-isolated/src/middleware/errorHandler.ts index e755da4f..a17bee6f 100644 --- a/desci-media-isolated/src/middleware/errorHandler.ts +++ b/desci-media-isolated/src/middleware/errorHandler.ts @@ -1,8 +1,11 @@ import type { Request, Response, NextFunction } from 'express'; import { BaseError } from '../utils/customErrors.js'; +import { logger as parentLogger } from '../utils/logger.js'; + +const logger = parentLogger.child({ module: 'Error Handling Middleware' }); export const errorHandler = (err: Error, req: Request, res: Response, next: NextFunction) => { - console.error(err.stack); + logger.warn({ errorStack: err.stack }, 'Error caught in error handler middleware'); let statusCode = 500; if (err instanceof BaseError && typeof err.statusCode === 'number') { diff --git a/desci-media-isolated/src/services/ipfs.ts b/desci-media-isolated/src/services/ipfs.ts index f0fb9d95..7409ea55 100644 --- a/desci-media-isolated/src/services/ipfs.ts +++ b/desci-media-isolated/src/services/ipfs.ts @@ -2,12 +2,15 @@ import axios from 'axios'; import fs from 'fs'; import { pipeline } from 'stream/promises'; import { IpfsConfigurationError, IpfsFetchError } from '../utils/customErrors.js'; +import { logger as parentLogger } from '../utils/logger.js'; const IPFS_GATEWAY = process.env.IPFS_GATEWAY; +const logger = parentLogger.child({ module: 'IPFS Service' }); + export class IpfsService { static async saveFile(cid: string, outputPath: string) { if (!IPFS_GATEWAY) { - console.log('IPFS_GATEWAY:', process.env.IPFS_GATEWAY); + logger.info({ IPFS_GATEWAY: process.env.IPFS_GATEWAY }, 'IPFS_GATEWAY'); throw new IpfsConfigurationError('process.env.IPFS_GATEWAY is not defined in environment variables'); } const url = `${IPFS_GATEWAY}/${cid}`; @@ -22,9 +25,9 @@ export class IpfsService { await pipeline(response.data, fs.createWriteStream(outputPath)); - console.log(`File downloaded and saved to ${outputPath}`); + logger.info(`File downloaded and saved to ${outputPath}`); } catch (error) { - console.error('Error downloading or saving the file:', error); + logger.error({ error }, 'Error downloading or saving the file'); throw new IpfsFetchError(`Error downloading or saving the file: ${cid}`); } } diff --git a/desci-media-isolated/src/services/pdf.ts b/desci-media-isolated/src/services/pdf.ts index d17d74ce..b48b668d 100644 --- a/desci-media-isolated/src/services/pdf.ts +++ b/desci-media-isolated/src/services/pdf.ts @@ -16,11 +16,14 @@ import { type PdfImageObject, } from '../types/pdf.js'; import fontkit from 'pdflib-fontkit'; +import { logger as parentLogger } from '../utils/logger.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const BASE_TEMP_DIR = path.resolve(__dirname, '../..', TEMP_DIR); +const logger = parentLogger.child({ module: 'PDF Manipulation Service' }); + export class PdfManipulationService { static async addPdfCover({ taskId, @@ -235,10 +238,10 @@ export class PdfManipulationService { const pdfBytesMod = await pdfDoc.save(); await fsp.writeFile(outputFullPath, pdfBytesMod); - console.log('Cover page generated successfully:', outputFullPath); + logger.info('Cover page generated successfully:', outputFullPath); return outputPdfFileName; } catch (e) { - console.error(e); + logger.error({ e }, 'Failed generating cover page for PDF'); throw new UnhandledError( `Failed generating cover page for file with cid: ${cid}, with temp file path: ${tempFilePath}`, ); @@ -247,13 +250,13 @@ export class PdfManipulationService { try { await fs.unlink(tempFilePath, (err) => { if (err) { - console.error(err, `Failed to cleanup temporary file: ${tempFilePath}`); + logger.error({ err }, `Failed to cleanup temporary file: ${tempFilePath}`); return; } - console.log(`Temporary file ${tempFilePath} deleted successfully.`); + logger.info(`Temporary file ${tempFilePath} deleted successfully.`); }); } catch (cleanupError) { - console.error(`Failed to delete temporary file ${tempFilePath}:`, cleanupError); + logger.error({ cleanupError, tempFilePath }, `Failed to delete temporary file ${tempFilePath}`); } } } @@ -524,18 +527,18 @@ export class PdfManipulationService { previewPaths.push(previewPath); } - console.log('Previews generated successfully:', previewPaths); + logger.info({ previewPaths }, 'Previews generated successfully'); return previewPaths; } catch (e) { - console.error(e); + logger.error({ e }, 'Failed generating previews for PDF'); throw new UnhandledError(`Failed generating previews for file with pdfCid: ${pdfCid}`); } finally { // The initially saved file is removed, however the generated previews remain. Further cleanup can be done for the generated previews. try { await fs.promises.unlink(tempFilePath); - console.log(`Temporary file ${tempFilePath} deleted successfully.`); + logger.trace(`Temporary file ${tempFilePath} deleted successfully.`); } catch (cleanupError) { - console.error(`Failed to delete temporary file ${tempFilePath}:`, cleanupError); + logger.error({ cleanupError, tempFilePath }, `Failed to delete temporary file ${tempFilePath}`); } } } diff --git a/desci-media-isolated/src/services/thumbnails.ts b/desci-media-isolated/src/services/thumbnails.ts index 8303a979..563fca03 100644 --- a/desci-media-isolated/src/services/thumbnails.ts +++ b/desci-media-isolated/src/services/thumbnails.ts @@ -5,6 +5,9 @@ import { BadRequestError, UnhandledError } from '../utils/customErrors.js'; import path from 'path'; import fs from 'fs'; import { fileURLToPath } from 'url'; +import { logger as parentLogger } from '../utils/logger.js'; + +const logger = parentLogger.child({ module: 'Thumbnail Generation Service' }); const THUMBNAIL_DIMENSIONS = { height: 300, @@ -42,19 +45,19 @@ export class ThumbnailsService { try { await generateAsync(tempFilePath, exportPath, { ...THUMBNAIL_DIMENSIONS, height: heightPx }); - console.log('Thumbnail generated successfully:', exportPath); + logger.info({ exportPath }, `Thumbnail generated successfully: ${exportPath}`); return thumbnailPath; } catch (e) { - console.error(e); + logger.error({ e }, `Failed generating thumbnail for file: ${identifier}`); throw new UnhandledError(`Failed generating thumbnail for file: ${identifier}`); } finally { // Only delete the temp file if it's not the original uploaded file if (!tempFilePath.includes(THUMBNAIL_FILES_DIR)) { try { await fs.promises.unlink(tempFilePath); - console.log(`Temporary file ${tempFilePath} deleted successfully.`); + logger.trace(`Temporary file ${tempFilePath} deleted successfully.`); } catch (cleanupError) { - console.error(`Failed to delete temporary file ${tempFilePath}:`, cleanupError); + logger.error({ cleanupError, tempFilePath }, `Failed to delete temporary file ${tempFilePath}`); } } } From 4b01594b817c44433cba9d4c985d742ca89fb4e9 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Wed, 26 Jun 2024 12:28:07 +0000 Subject: [PATCH 230/278] add additional prepub pdf gen logging --- desci-media-isolated/src/services/pdf.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/desci-media-isolated/src/services/pdf.ts b/desci-media-isolated/src/services/pdf.ts index b48b668d..0dffc5f9 100644 --- a/desci-media-isolated/src/services/pdf.ts +++ b/desci-media-isolated/src/services/pdf.ts @@ -43,12 +43,16 @@ export class PdfManipulationService { const outputPdfFileName = this.getPdfPath(PDF_JOB_TYPE.ADD_COVER, cid); const outputFullPath = path.join(BASE_TEMP_DIR, PDF_OUTPUT_DIR, outputPdfFileName); // debugger; + logger.trace({ cid, tempFilePath }, 'Saving PDF from IPFS onto disk for processing'); await IpfsService.saveFile(cid, tempFilePath); + // debugger; try { + logger.trace({ taskId }, 'Loading PDF for processing'); // Proccess the pdf file to add the cover page const pdfBytes = await readFileToBuffer(tempFilePath); const pdfDoc = await PDFDocument.load(pdfBytes); + logger.trace({ taskId }, 'PDF Doc Loaded'); /** * Load Fonts @@ -235,10 +239,12 @@ export class PdfManipulationService { font: interRegularFont, }); } + logger.trace({ taskId }, 'Saving PDF with cover page added'); + const pdfBytesMod = await pdfDoc.save(); await fsp.writeFile(outputFullPath, pdfBytesMod); - logger.info('Cover page generated successfully:', outputFullPath); + logger.info({ taskId, outputFullPath }, 'Cover page generated successfully'); return outputPdfFileName; } catch (e) { logger.error({ e }, 'Failed generating cover page for PDF'); @@ -248,6 +254,7 @@ export class PdfManipulationService { } finally { // The initially saved file is removed, however the generated pdf remains. Further cleanup can be done for the generated pdf result. try { + logger.trace({ taskId }, 'Cleaning up original PDF'); await fs.unlink(tempFilePath, (err) => { if (err) { logger.error({ err }, `Failed to cleanup temporary file: ${tempFilePath}`); From a2b35d72a9ad0621d58565337a8f959790029afe Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Wed, 26 Jun 2024 13:24:38 +0000 Subject: [PATCH 231/278] fix prod issue causing generations to fail, saving dir wasnt inialized in prod script --- desci-media-isolated/scripts/containerInitProd.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desci-media-isolated/scripts/containerInitProd.sh b/desci-media-isolated/scripts/containerInitProd.sh index d5711244..e1abf4c7 100755 --- a/desci-media-isolated/scripts/containerInitProd.sh +++ b/desci-media-isolated/scripts/containerInitProd.sh @@ -1,7 +1,7 @@ #!/bin/bash # Ensure temp directories exist -mkdir -p /usr/src/app/.temp/files /usr/src/app/.temp/thumbnails +mkdir -p /usr/src/app/.temp/files /usr/src/app/.temp/thumbnails /usr/src/app/.temp/files/pdf /usr/src/app/.temp/pdf # Execute the main container command exec "$@" From 1a7efcde2420bd4595d98bc1464f83171f94caa7 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Wed, 26 Jun 2024 13:52:30 +0000 Subject: [PATCH 232/278] add cleanup to isolated media controllers for generated files after theyre transmitted --- .../src/controllers/pdf/createCover.ts | 29 +++++++++++++++++++ .../src/controllers/pdf/preview.ts | 18 ++++++++++++ .../src/controllers/thumbnails/create.ts | 16 ++++++++++ 3 files changed, 63 insertions(+) diff --git a/desci-media-isolated/src/controllers/pdf/createCover.ts b/desci-media-isolated/src/controllers/pdf/createCover.ts index d366c6fc..7ac842b3 100644 --- a/desci-media-isolated/src/controllers/pdf/createCover.ts +++ b/desci-media-isolated/src/controllers/pdf/createCover.ts @@ -5,6 +5,7 @@ import fs from 'fs'; import { PDF_OUTPUT_DIR, TEMP_DIR } from '../../config/index.js'; import { BadRequestError, NotFoundError } from '../../utils/customErrors.js'; import { PdfManipulationService } from '../../services/pdf.js'; +import { logger as parentLogger } from '../../utils/logger.js'; export type GeneratePdfCoverRequestBody = { cid: string; @@ -36,6 +37,23 @@ export const generatePdfCover = async ( ) => { const { cid, doi, dpid, title, codeAvailableDpid, dataAvailableDpid, license, publishDate, authors } = req.body; const { header = true, headerAllPages = false, authorLimit } = req.query; + const logger = parentLogger.child({ + module: 'GeneratePdfCover Controller', + cid, + doi, + dpid, + title, + codeAvailableDpid, + dataAvailableDpid, + license, + publishDate, + authors, + header, + headerAllPages, + authorLimit, + }); + logger.trace('Generating prepub cover'); + try { if (!cid) throw new BadRequestError('Missing cid in request body'); if (!dpid) throw new BadRequestError('Missing dpid in request body'); @@ -69,6 +87,17 @@ export const generatePdfCover = async ( const readStream = fs.createReadStream(fullPdfPath); readStream.pipe(res); + + readStream.on('end', () => { + // Cleanup the generated PDF file + fs.unlink(fullPdfPath, (unlinkErr) => { + if (unlinkErr) { + logger.error({ unlinkErr }, `Failed to delete generated cover file: ${fullPdfPath}`); + } else { + logger.info(`Successfully cleaned up generated cover file: ${fullPdfPath}`); + } + }); + }); }); return res.status(200); diff --git a/desci-media-isolated/src/controllers/pdf/preview.ts b/desci-media-isolated/src/controllers/pdf/preview.ts index c076e5db..79cf4488 100644 --- a/desci-media-isolated/src/controllers/pdf/preview.ts +++ b/desci-media-isolated/src/controllers/pdf/preview.ts @@ -5,6 +5,7 @@ import fs from 'fs/promises'; import { TEMP_DIR, THUMBNAIL_OUTPUT_DIR } from '../../config/index.js'; import { BadRequestError, NotFoundError } from '../../utils/customErrors.js'; import { PdfManipulationService } from '../../services/pdf.js'; +import { logger as parentLogger } from '../../utils/logger.js'; export type GeneratePreviewRequestBody = { cid: string; @@ -21,6 +22,10 @@ export const generatePreview = async ( ) => { const { cid, pages } = req.body; const { height = 1000 } = req.query; + const logger = parentLogger.child({ + module: 'generatePreview Controller', + pdfCid: cid, + }); if (!cid) throw new BadRequestError('Missing cid in request body'); if (!pages) throw new BadRequestError('Missing pages number array in request body'); @@ -42,6 +47,19 @@ export const generatePreview = async ( res.setHeader('Content-Type', 'application/json'); res.status(200).json(previewBuffers); + + res.on('finish', async () => { + // Cleanup generated previews after they're sent + try { + for (const previewPath of previewPaths) { + const fullPreviewPath = path.join(BASE_TEMP_DIR, THUMBNAIL_OUTPUT_DIR, previewPath); + await fs.unlink(fullPreviewPath); + logger.info(`Successfully deleted preview file: ${fullPreviewPath}`); + } + } catch (error) { + logger.error({ error }, 'Error during cleanup:'); + } + }); } catch (err: any) { return res.status(500).json({ message: err.message }); } diff --git a/desci-media-isolated/src/controllers/thumbnails/create.ts b/desci-media-isolated/src/controllers/thumbnails/create.ts index f289fa34..2952cd00 100644 --- a/desci-media-isolated/src/controllers/thumbnails/create.ts +++ b/desci-media-isolated/src/controllers/thumbnails/create.ts @@ -5,6 +5,7 @@ import { fileURLToPath } from 'url'; import fs from 'fs'; import { TEMP_DIR, THUMBNAIL_OUTPUT_DIR } from '../../config/index.js'; import { BadRequestError, NotFoundError } from '../../utils/customErrors.js'; +import { logger as parentLogger } from '../../utils/logger.js'; export type GenerateThumbnailRequestBody = { cid?: string; @@ -27,6 +28,11 @@ export const generateThumbnail = async (req: GenerateThumbnailRequest, res: Resp const { cid } = req.body; const height = parseInt(req.query.height || '300'); + const logger = parentLogger.child({ + module: 'generateThumbnail Controller', + cid, + }); + try { let thumbnailPath: string; @@ -48,6 +54,16 @@ export const generateThumbnail = async (req: GenerateThumbnailRequest, res: Resp res.setHeader('Content-Type', 'image/png'); const readStream = fs.createReadStream(fullThumbnailPath); readStream.pipe(res); + readStream.on('end', () => { + // Cleanup the generated PDF file + fs.unlink(fullThumbnailPath, (unlinkErr) => { + if (unlinkErr) { + logger.error({ unlinkErr }, `Failed to delete generated thumbnail file: ${fullThumbnailPath}`); + } else { + logger.info(`Successfully cleaned up generated thumbnail file: ${fullThumbnailPath}`); + } + }); + }); }); } catch (err: any) { return res.status(500).json({ message: err.message }); From fdab3431ae504d2bea4af79c9fff3241628bccd7 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Wed, 26 Jun 2024 14:44:14 +0000 Subject: [PATCH 233/278] fix perm issue in prod deployment --- desci-media-isolated/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/desci-media-isolated/Dockerfile b/desci-media-isolated/Dockerfile index faba2f8d..d6442e2f 100644 --- a/desci-media-isolated/Dockerfile +++ b/desci-media-isolated/Dockerfile @@ -42,7 +42,8 @@ ENV NODE_ENV production # 'node' user is created by the node image, prevent perm issues, run with reduced privs RUN mkdir -p /usr/src/app/dist && chown node:node /usr/src/app/dist USER node -COPY --chown=node:node ./src/ ./src/ +COPY --chown=node:node ./src/ ./src/ +COPY --chown=node:node ./public/ ./public/ USER root RUN chown -R node:node /usr/src/app USER node From c225b790cdf25141cb4d15a7b151b6578b94ba86 Mon Sep 17 00:00:00 2001 From: m0ar Date: Wed, 26 Jun 2024 21:02:18 +0200 Subject: [PATCH 234/278] Fixes so staging uses production environments --- desci-server/src/controllers/nodes/createDpid.ts | 4 ++-- nodes-lib/package.json | 2 +- nodes-lib/src/config/chain.ts | 4 ++-- nodes-lib/src/config/index.ts | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/desci-server/src/controllers/nodes/createDpid.ts b/desci-server/src/controllers/nodes/createDpid.ts index f119bcfa..53a07888 100644 --- a/desci-server/src/controllers/nodes/createDpid.ts +++ b/desci-server/src/controllers/nodes/createDpid.ts @@ -47,11 +47,11 @@ if (apiServerUrl.includes('localhost') || apiServerUrl.includes('host.docker.int aliasRegistryAddress = contracts.localDpidAliasInfo.proxies.at(0).address; ceramicApiUrl = CERAMIC_API_URLS.local; optimismRpcUrl = OPTIMISM_RPC_URLS.local; -} else if (apiServerUrl.includes('dev') || apiServerUrl.includes('staging')) { +} else if (apiServerUrl.includes('dev')) { aliasRegistryAddress = contracts.devDpidAliasInfo.proxies.at(0).address; ceramicApiUrl = CERAMIC_API_URLS.dev; optimismRpcUrl = OPTIMISM_RPC_URLS.opSepolia; -} else if (process.env.NODE_ENV === 'production') { +} else if (process.env.NODE_ENV === 'production' || apiServerUrl.includes('staging')) { aliasRegistryAddress = contracts.prodDpidAliasInfo.proxies.at(0).address; ceramicApiUrl = CERAMIC_API_URLS.prod; optimismRpcUrl = OPTIMISM_RPC_URLS.opSepolia; diff --git a/nodes-lib/package.json b/nodes-lib/package.json index 897891b9..ef439c9c 100644 --- a/nodes-lib/package.json +++ b/nodes-lib/package.json @@ -1,6 +1,6 @@ { "name": "@desci-labs/nodes-lib", - "version": "0.0.7", + "version": "0.0.8", "homepage": "https://github.com/desci-labs/nodes#readme", "description": "Stand-alone client library for interacting with desci-server", "repository": { diff --git a/nodes-lib/src/config/chain.ts b/nodes-lib/src/config/chain.ts index 01e6bfb8..0599f549 100644 --- a/nodes-lib/src/config/chain.ts +++ b/nodes-lib/src/config/chain.ts @@ -109,12 +109,12 @@ export const CHAIN_CONFIGS = { chainId: "11155420", rpcUrl: "https://reverse-proxy-staging.desci.com/rpc_opt_sepolia", dpidAliasRegistryConnector: signerOrProvider => tc.DpidAliasRegistry__factory.connect( - contracts.devDpidAliasInfo.proxies[0].address, + contracts.prodDpidAliasInfo.proxies[0].address, // also uses prod contracts signerOrProvider, ), }, prod: { - chainId: "10", + chainId: "11155420", rpcUrl: "https://reverse-proxy-prod.desci.com/rpc_opt_sepolia", dpidAliasRegistryConnector: signerOrProvider => tc.DpidAliasRegistry__factory.connect( contracts.prodDpidAliasInfo.proxies[0].address, diff --git a/nodes-lib/src/config/index.ts b/nodes-lib/src/config/index.ts index 39146759..bd737cde 100644 --- a/nodes-lib/src/config/index.ts +++ b/nodes-lib/src/config/index.ts @@ -33,9 +33,9 @@ export const NODESLIB_CONFIGS = { staging: { apiUrl: "https://nodes-api-staging.desci.com", apiKey: undefined, - ceramicNodeUrl: "https://ceramic-dev.desci.com", - legacyChainConfig: LEGACY_CHAIN_CONFIGS.dev, // also using the dev contracts - chainConfig: CHAIN_CONFIGS.dev, // also using dev contracts + ceramicNodeUrl: "https://ceramic-prod.desci.com", + legacyChainConfig: LEGACY_CHAIN_CONFIGS.prod, // also using the prod contracts + chainConfig: CHAIN_CONFIGS.prod, // also using prod contracts }, prod: { apiUrl: "https://nodes-api.desci.com", From dc10982823a416a3b0870d0e328b7ae27a05dde6 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Wed, 26 Jun 2024 21:15:01 +0000 Subject: [PATCH 235/278] add demo defaults to email template --- desci-server/src/services/PublishServices.ts | 2 +- desci-server/src/templates/emails/NodeUpdated.tsx | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/desci-server/src/services/PublishServices.ts b/desci-server/src/services/PublishServices.ts index 2cf3e0f0..5fccf41b 100644 --- a/desci-server/src/services/PublishServices.ts +++ b/desci-server/src/services/PublishServices.ts @@ -63,7 +63,7 @@ export class PublishServices { const emailMsg = { to: contributor.email, from: 'no-reply@desci.com', - subject: `[nodes.desci.com] DPID ${dpid} has been updated`, + subject: `[nodes.desci.com] DPID ${dpid || '(DEMO)'} has been updated`, text: `${nodeOwner.name} has published an updated version (${versionPublished}) of their research object titled "${node.title}" that you have contributed to.`, html: emailHtml, }; diff --git a/desci-server/src/templates/emails/NodeUpdated.tsx b/desci-server/src/templates/emails/NodeUpdated.tsx index bf6d0d41..236f7d4c 100644 --- a/desci-server/src/templates/emails/NodeUpdated.tsx +++ b/desci-server/src/templates/emails/NodeUpdated.tsx @@ -24,6 +24,8 @@ export const NodeUpdated = ({ }: NodeUpdatedEmailProps) => { if (nodeUuid?.endsWith('.') || nodeUuid?.endsWith('=')) nodeUuid = nodeUuid.slice(0, -1); nodeOwner = nodeOwner || 'The node owner'; + nodeDpid = nodeDpid || '(DEMO)'; + versionUpdate = versionUpdate || '1'; // For demo case const nodeUrl = `${DAPP_URL}/dpid/${nodeDpid}/${versionUpdate}`; const manuscriptUrl = `${process.env.IPFS_RESOLVER_OVERRIDE}/${manuscriptCid}`; return ( From d24ae5979f560865a01a5469ea0f94ad400ee408 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Thu, 27 Jun 2024 08:00:20 +0200 Subject: [PATCH 236/278] set up all possible cross callback route handlers for testing --- desci-server/src/controllers/doi/mint.ts | 7 ++++++- desci-server/src/core/ApiError.ts | 1 + desci-server/src/core/doi/error.ts | 9 ++++++++- desci-server/src/routes/index.ts | 14 ++++++++++++++ desci-server/src/routes/v1/crossref.ts | 21 +++++++++++++++++---- desci-server/src/routes/v1/index.ts | 9 +++++++++ desci-server/src/services/Doi.ts | 15 ++++++++++++--- 7 files changed, 67 insertions(+), 9 deletions(-) diff --git a/desci-server/src/controllers/doi/mint.ts b/desci-server/src/controllers/doi/mint.ts index 137c9da2..6fe8c5b8 100644 --- a/desci-server/src/controllers/doi/mint.ts +++ b/desci-server/src/controllers/doi/mint.ts @@ -44,18 +44,23 @@ export const handleCrossrefNotificationCallback = async ( _next: NextFunction, ) => { const submission = await doiService.getPendingSubmission(req.payload.externalId); - + logger.info({ submission }, 'SUBMISSION'); if (!submission) { logger.error({ payload: req.payload }, 'Crossref Notifiication: pending submission not found'); return; } + logger.info({ submission }, 'SUBMISSION FOUND'); await doiService.updateSubmission({ id: submission.id }, { notification: req.payload }); + logger.info('SUBMISSION UPDATED'); new SuccessMessageResponse(); // check retrieve url to get submission result const response = await crossRefClient.retrieveSubmission(req.payload.retrieveUrl); + + // TODO: email authors about the submission status + await doiService.updateSubmission( { id: submission.id }, { status: response.success ? DoiStatus.SUCCESS : response.failure ? DoiStatus.FAILED : DoiStatus.PENDING }, diff --git a/desci-server/src/core/ApiError.ts b/desci-server/src/core/ApiError.ts index c5379097..06ce2af0 100644 --- a/desci-server/src/core/ApiError.ts +++ b/desci-server/src/core/ApiError.ts @@ -67,6 +67,7 @@ export abstract class ApiError extends Error { case DoiErrorType.NO_MANUSCRIPT: case DoiErrorType.INCOMPLETE_ATTESTATIONS: case DoiErrorType.DUPLICATE_MINT: + case DoiErrorType.FORBIDDEN: return new BadRequestResponse(err.message, err).send(res); default: return new InternalErrorResponse(err.message).send(res); diff --git a/desci-server/src/core/doi/error.ts b/desci-server/src/core/doi/error.ts index ef8b1830..a898b723 100644 --- a/desci-server/src/core/doi/error.ts +++ b/desci-server/src/core/doi/error.ts @@ -2,8 +2,9 @@ export enum DoiErrorType { DUPLICATE_MINT = 'DuplicateDoiError', NO_MANUSCRIPT = 'NoManuscriptError', BAD_METADATA = 'InvalidManifestError', - INCOMPLETE_ATTESTATIONS = 'ForbiddenError', + INCOMPLETE_ATTESTATIONS = 'MissingAttestationsError', REGISTRATION_ERROR = 'RegistrationError', + FORBIDDEN = 'ForbiddenError', } export class DoiError extends Error { @@ -46,3 +47,9 @@ export class MintError extends DoiError { super(DoiErrorType.DUPLICATE_MINT, message); } } + +export class ForbiddenMintError extends DoiError { + constructor(message = 'Research object not valid') { + super(DoiErrorType.FORBIDDEN, message); + } +} diff --git a/desci-server/src/routes/index.ts b/desci-server/src/routes/index.ts index 4fd6d121..a767183e 100755 --- a/desci-server/src/routes/index.ts +++ b/desci-server/src/routes/index.ts @@ -1,15 +1,29 @@ import { Router } from 'express'; import { resolve } from '../controllers/raw/resolve.js'; +import { asyncHandler, handleCrossrefNotificationCallback } from '../internal.js'; import page404 from './pages/404.js'; import pageRoot from './pages/root.js'; +import { ensureCrossrefNotifier, identifyEndpoint } from './v1/crossref.js'; import v1 from './v1/index.js'; const router = Router(); router.use(`/v1`, v1); +// potential notification fallback catch +router.get( + '/crossref/callback', + [identifyEndpoint('/crossref/callback'), ensureCrossrefNotifier], + asyncHandler(handleCrossrefNotificationCallback), +); +router.get( + '/crossref/callback/v1/crossref/callback', + [identifyEndpoint('/crossref/callback/v1/crossref/callback'), ensureCrossrefNotifier], + asyncHandler(handleCrossrefNotificationCallback), +); + router.get('/:query*', resolve); router.use(pageRoot); diff --git a/desci-server/src/routes/v1/crossref.ts b/desci-server/src/routes/v1/crossref.ts index c3f31c4a..2739ef66 100644 --- a/desci-server/src/routes/v1/crossref.ts +++ b/desci-server/src/routes/v1/crossref.ts @@ -5,18 +5,26 @@ import { RequestWithCrossRefPayload, asyncHandler, handleCrossrefNotificationCallback, - logger, + logger as parentLogger, } from '../../internal.js'; +const logger = parentLogger.child({ module: 'CROSSREF NOTIFICATION' }); // assert required env are available if (!process.env.CROSSREF_NOTIFY_CALLBACK_PATH) throw Error('Env `CROSSREF_NOTIFY_CALLBACK_PATH` not set.'); if (!process.env.CROSSREF_NOTIFY_ENDPOINT) throw Error('Env `CROSSREF_NOTIFY_ENDPOINT` not set.'); const notifierCallbackUrl = process.env.CROSSREF_NOTIFY_CALLBACK_PATH; +const notifierEndpoint = process.env.CROSSREF_NOTIFY_ENDPOINT; const router = Router(); -const ensureCrossrefNotifier = (req: Request, _res: Response, next: NextFunction) => { +export const identifyEndpoint = (endpoint: string) => (req: Request, _res: Response, next: NextFunction) => { + logger.info({ endpoint }, 'identifyEndpoint'); + next(); +}; + +export const ensureCrossrefNotifier = (req: Request, _res: Response, next: NextFunction) => { + logger.info({ headers: req.headers }, 'CALLBACK MIDDLEWARE'); // parse the follwing headers and attach it to the request's context; // CROSSREF-NOTIFY-ENDPOINT // CROSSREF-EXTERNAL-ID @@ -34,9 +42,10 @@ const ensureCrossrefNotifier = (req: Request, _res: Response, next: NextFunction retrieveUrlExpirationDate: req.headers['CROSSREF-RETRIEVE-URL-EXPIRATION-DATE'] as string, }; - logger.info({ payload, headers: req.headers }, 'CROSSREF NOTIFICATION'); + logger.info({ payload, headers: req.headers, body: req.body }, 'payload'); // verify notification endpoint if (payload.notifyEndpoint !== process.env.CROSSREF_NOTIFY_ENDPOINT) { + logger.info({ payloadEndpoint: payload.notifyEndpoint, endpoint: notifierEndpoint }, 'INVALID ENDPOINT'); return; } @@ -45,6 +54,10 @@ const ensureCrossrefNotifier = (req: Request, _res: Response, next: NextFunction next(); }; -router.post(notifierCallbackUrl, [ensureCrossrefNotifier], asyncHandler(handleCrossrefNotificationCallback)); +router.post( + notifierCallbackUrl, + [identifyEndpoint(notifierCallbackUrl), ensureCrossrefNotifier], + asyncHandler(handleCrossrefNotificationCallback), +); export default router; diff --git a/desci-server/src/routes/v1/index.ts b/desci-server/src/routes/v1/index.ts index e624a07f..84bb974c 100755 --- a/desci-server/src/routes/v1/index.ts +++ b/desci-server/src/routes/v1/index.ts @@ -3,6 +3,7 @@ import { generateNonce } from 'siwe'; import { prisma } from '../../client.js'; import { queryResearchFields } from '../../controllers/data/index.js'; +import { handleCrossrefNotificationCallback } from '../../controllers/doi/mint.js'; import { queryRor } from '../../controllers/proxy/index.js'; import { ipfsReadGatewayProxy } from '../../controllers/proxy/ipfsReadGateway.js'; import { nft } from '../../controllers/raw/nft.js'; @@ -13,6 +14,7 @@ import admin from './admin.js'; import attestations from './attestations/index.js'; import auth from './auth.js'; import communities from './communities/index.js'; +import { ensureCrossrefNotifier, identifyEndpoint } from './crossref.js'; import data from './data.js'; import doi from './doi.js'; import log from './log.js'; @@ -63,4 +65,11 @@ router.get('/researchFields', [ensureUser], queryResearchFields); router.get('/ror', [ensureUser], queryRor); router.get('/ipfs/:cid', ipfsReadGatewayProxy); +// potential notification fallback catch +router.get( + '/crossref/callback', + [identifyEndpoint('/v1/crossref/callback'), ensureCrossrefNotifier], + asyncHandler(handleCrossrefNotificationCallback), +); + export default router; diff --git a/desci-server/src/services/Doi.ts b/desci-server/src/services/Doi.ts index 91ec1ba7..f954ee80 100644 --- a/desci-server/src/services/Doi.ts +++ b/desci-server/src/services/Doi.ts @@ -1,8 +1,14 @@ import { PdfComponent, ResearchObjectComponentType, ResearchObjectV1 } from '@desci-labs/desci-models'; -import { DoiStatus, DoiSubmissionQueue, Prisma, PrismaClient } from '@prisma/client'; +import { DoiStatus, Prisma, PrismaClient } from '@prisma/client'; import { v4 } from 'uuid'; -import { DuplicateMintError, BadManifestError, AttestationsError, MintError } from '../core/doi/error.js'; +import { + DuplicateMintError, + BadManifestError, + AttestationsError, + MintError, + ForbiddenMintError, +} from '../core/doi/error.js'; import { logger } from '../logger.js'; import { IndexedResearchObject, getIndexedResearchObjects } from '../theGraph.js'; import { asyncMap, ensureUuidEndsWithDot, hexToCid } from '../utils.js'; @@ -84,7 +90,10 @@ export class DoiService { // retrieve node manifest/metadata const { researchObjects } = await getIndexedResearchObjects([uuid]); const researchObject = researchObjects[0] as IndexedResearchObject; - const manifestCid = hexToCid(researchObject.recentCid); + const manifestCid = hexToCid(researchObject?.recentCid); + + if (!manifestCid) throw new ForbiddenMintError('Node not published yet!'); + const latestManifest = await getManifestByCid(manifestCid); researchObject.versions.reverse(); From 297857d4985ae881bbed64cc8b2761345ce1517c Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Thu, 27 Jun 2024 08:33:50 +0200 Subject: [PATCH 237/278] add dummy test env vars --- .env.test | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.env.test b/.env.test index e12b735c..3584d2d5 100644 --- a/.env.test +++ b/.env.test @@ -87,5 +87,9 @@ CROSSREF_LOGIN= CROSSREF_PASSWORD= # Cross ref notification callback envs -CROSSREF_NOTIFY_ENDPOINT= -CROSSREF_NOTIFY_CALLBACK_PATH= \ No newline at end of file +CROSSREF_NOTIFY_ENDPOINT=endpoint +CROSSREF_NOTIFY_CALLBACK_PATH=/callback + +# Automated metadata +AUTOMATED_METADATA_API= +AUTOMATED_METADATA_API_KEY= \ No newline at end of file From 8c89ef3423c015fa4f9ef94b9f6ed26714943b71 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Thu, 27 Jun 2024 08:47:44 +0200 Subject: [PATCH 238/278] rerun test --- .env.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.test b/.env.test index 3584d2d5..be2b5851 100644 --- a/.env.test +++ b/.env.test @@ -88,7 +88,7 @@ CROSSREF_PASSWORD= # Cross ref notification callback envs CROSSREF_NOTIFY_ENDPOINT=endpoint -CROSSREF_NOTIFY_CALLBACK_PATH=/callback +CROSSREF_NOTIFY_CALLBACK_PATH=/callback/endpoint # Automated metadata AUTOMATED_METADATA_API= From bb1b8ef49109d051f8be717f211e17c0b7b06cec Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Thu, 27 Jun 2024 14:42:43 +0200 Subject: [PATCH 239/278] crossref notification test --- desci-server/src/controllers/doi/mint.ts | 8 +++++--- desci-server/src/routes/index.ts | 4 ++-- desci-server/src/routes/v1/crossref.ts | 16 +++++++++------- desci-server/src/routes/v1/index.ts | 2 +- desci-server/src/services/Doi.ts | 2 +- desci-server/src/services/crossRef/client.ts | 4 ++-- 6 files changed, 20 insertions(+), 16 deletions(-) diff --git a/desci-server/src/controllers/doi/mint.ts b/desci-server/src/controllers/doi/mint.ts index 6fe8c5b8..1401f1bb 100644 --- a/desci-server/src/controllers/doi/mint.ts +++ b/desci-server/src/controllers/doi/mint.ts @@ -5,6 +5,7 @@ import _ from 'lodash'; import { MintError } from '../../core/doi/error.js'; import { BadRequestError, + NotFoundError, SuccessMessageResponse, SuccessResponse, crossRefClient, @@ -40,21 +41,22 @@ export interface RequestWithCrossRefPayload extends Request { export const handleCrossrefNotificationCallback = async ( req: RequestWithCrossRefPayload, - _res: Response, + res: Response, _next: NextFunction, ) => { const submission = await doiService.getPendingSubmission(req.payload.externalId); logger.info({ submission }, 'SUBMISSION'); + if (!submission) { logger.error({ payload: req.payload }, 'Crossref Notifiication: pending submission not found'); - return; + throw new NotFoundError('submission not found'); } logger.info({ submission }, 'SUBMISSION FOUND'); await doiService.updateSubmission({ id: submission.id }, { notification: req.payload }); logger.info('SUBMISSION UPDATED'); - new SuccessMessageResponse(); + new SuccessMessageResponse().send(res); // check retrieve url to get submission result const response = await crossRefClient.retrieveSubmission(req.payload.retrieveUrl); diff --git a/desci-server/src/routes/index.ts b/desci-server/src/routes/index.ts index a767183e..d4fb60f3 100755 --- a/desci-server/src/routes/index.ts +++ b/desci-server/src/routes/index.ts @@ -13,12 +13,12 @@ const router = Router(); router.use(`/v1`, v1); // potential notification fallback catch -router.get( +router.post( '/crossref/callback', [identifyEndpoint('/crossref/callback'), ensureCrossrefNotifier], asyncHandler(handleCrossrefNotificationCallback), ); -router.get( +router.post( '/crossref/callback/v1/crossref/callback', [identifyEndpoint('/crossref/callback/v1/crossref/callback'), ensureCrossrefNotifier], asyncHandler(handleCrossrefNotificationCallback), diff --git a/desci-server/src/routes/v1/crossref.ts b/desci-server/src/routes/v1/crossref.ts index 2739ef66..ebe91f4f 100644 --- a/desci-server/src/routes/v1/crossref.ts +++ b/desci-server/src/routes/v1/crossref.ts @@ -2,6 +2,8 @@ import { NextFunction, Request, Response, Router } from 'express'; import { + AuthFailureError, + BadRequestError, RequestWithCrossRefPayload, asyncHandler, handleCrossrefNotificationCallback, @@ -34,19 +36,19 @@ export const ensureCrossrefNotifier = (req: Request, _res: Response, next: NextF // CROSSREF-RETRIEVE-URL-EXPIRATION-DATE const payload = { - notifyEndpoint: req.headers['CROSSREF-NOTIFY-ENDPOINT'] as string, - externalId: req.headers[' CROSSREF-EXTERNAL-ID'] as string, - internalId: req.headers['CROSSREF-INTERNAL-ID'] as string, - retrieveUrl: req.headers['CROSSREF-RETRIEVE-URL'] as string, - serviceDate: req.headers['CROSSREF-SERVICE-DATE'] as string, - retrieveUrlExpirationDate: req.headers['CROSSREF-RETRIEVE-URL-EXPIRATION-DATE'] as string, + notifyEndpoint: req.headers['crossref-notify-endpoint'] as string, + externalId: req.headers['crossref-external-id'] as string, + internalId: req.headers['crossref-internal-id'] as string, + retrieveUrl: req.headers['crossref-retrieve-url'] as string, + serviceDate: req.headers['crossref-service-date'] as string, + retrieveUrlExpirationDate: req.headers['crossref-retrieve-url-expiration-date'] as string, }; logger.info({ payload, headers: req.headers, body: req.body }, 'payload'); // verify notification endpoint if (payload.notifyEndpoint !== process.env.CROSSREF_NOTIFY_ENDPOINT) { logger.info({ payloadEndpoint: payload.notifyEndpoint, endpoint: notifierEndpoint }, 'INVALID ENDPOINT'); - return; + throw new AuthFailureError(); } (req as RequestWithCrossRefPayload).payload = payload; diff --git a/desci-server/src/routes/v1/index.ts b/desci-server/src/routes/v1/index.ts index 84bb974c..6fd4a4b0 100755 --- a/desci-server/src/routes/v1/index.ts +++ b/desci-server/src/routes/v1/index.ts @@ -66,7 +66,7 @@ router.get('/ror', [ensureUser], queryRor); router.get('/ipfs/:cid', ipfsReadGatewayProxy); // potential notification fallback catch -router.get( +router.post( '/crossref/callback', [identifyEndpoint('/v1/crossref/callback'), ensureCrossrefNotifier], asyncHandler(handleCrossrefNotificationCallback), diff --git a/desci-server/src/services/Doi.ts b/desci-server/src/services/Doi.ts index 1266ec1d..ed08af0d 100644 --- a/desci-server/src/services/Doi.ts +++ b/desci-server/src/services/Doi.ts @@ -184,7 +184,7 @@ export class DoiService { include: { DoiSubmission: { where: { status: DoiStatus.PENDING } } }, }); - return pending.DoiSubmission.length > 0 ? true : false; + return pending?.DoiSubmission && pending.DoiSubmission.length > 0 ? true : false; } async getPendingSubmission(batchId: string) { diff --git a/desci-server/src/services/crossRef/client.ts b/desci-server/src/services/crossRef/client.ts index 69928fcf..9279f3dd 100644 --- a/desci-server/src/services/crossRef/client.ts +++ b/desci-server/src/services/crossRef/client.ts @@ -304,7 +304,7 @@ class CrossRefClient { logger.info(response, 'CROSSREF NOTIFICATION: retrieveSubmission'); // return interprete the response from the api to determine if the // submission status has either `success | pending | failed` - return { success: true, pending: true, failure: true }; + return { success: response?.completed !== null, pending: false, failure: true }; } } @@ -320,7 +320,7 @@ type NotificationResult = { notifyPayloadExpiration: string; internalTrackingId: string; externalTrackingId: string; - recordCreated: string; + recordCreated: string | null; recordUpdated: string | null; }; From f59fc7e230187775a046891fffc57188551cd323 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Thu, 27 Jun 2024 15:27:20 +0200 Subject: [PATCH 240/278] grobid support --- desci-server/kubernetes/grobid_dev.yaml | 107 ++++++++++++++++++++++++ docker-compose.dev.yml | 12 +++ 2 files changed, 119 insertions(+) create mode 100644 desci-server/kubernetes/grobid_dev.yaml diff --git a/desci-server/kubernetes/grobid_dev.yaml b/desci-server/kubernetes/grobid_dev.yaml new file mode 100644 index 00000000..949163d6 --- /dev/null +++ b/desci-server/kubernetes/grobid_dev.yaml @@ -0,0 +1,107 @@ +apiVersion: v1 +kind: Service +metadata: + name: grobid-dev +spec: + selector: + App: GrobidDev + ports: + - port: 80 + targetPort: 8070 + type: LoadBalancer +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: grobid-dev + labels: + App: GrobidDev +spec: + replicas: 2 + revisionHistoryLimit: 8 + selector: + matchLabels: + App: GrobidDev + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + type: RollingUpdate + template: + metadata: + # annotations: + # vault.hashicorp.com/agent-inject: 'true' + # vault.hashicorp.com/agent-inject-status: 'update' + # vault.hashicorp.com/role: app-vault-reader + # vault.hashicorp.com/agent-inject-secret-config: secrets/desci-server/staging/db + # vault.hashicorp.com/agent-inject-template-config: | + # {{- with secret "secrets/automating-metadata/dev" -}} + # export OPENAI_API_KEY={{ .Data.OPENAI_API_KEY }} + # export crmailto={{ .Data.crmailto }} + # export pyalexemail={{ .Data.pyalexemail }} + # export AM_API_KEY={{ .Data.AM_API_KEY }} + # export IPFS_GATEWAY_URL={{ .Data.IPFS_GATEWAY_URL }} + + # echo "dbset"; + # {{- end -}} + labels: + App: GrobidDev + spec: + containers: + - image: lfoppiano/grobid:0.8.0 + name: grobid-dev + ports: + - containerPort: 8070 + name: server-api + env: + - name: JAVA_OPTS + value: "-Xmx2G -Xms2G" + resources: + limits: + cpu: '1.0' + memory: 5Gi + requests: + cpu: '0.8' + memory: 5Gi + # restart pod after failureThreshold*periodSeconds total seconds + livenessProbe: + httpGet: + path: /api/isalive + port: server-api + failureThreshold: 80 + periodSeconds: 3 + # temporarily stop sending traffic to pod after failureThreshold*periodSeconds total seconds + readinessProbe: + httpGet: + path: /api/isalive + port: server-api + failureThreshold: 3 + periodSeconds: 1 + # wait for pod to start for failureThreshold*periodSeconds total seconds + startupProbe: + httpGet: + path: /api/isalive + port: server-api + failureThreshold: 200 + periodSeconds: 1 + # serviceAccountName: 'vault-auth' +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: grobid-dev-ingress + annotations: + nginx.ingress.kubernetes.io/rewrite-target: / + nginx.ingress.kubernetes.io/proxy-body-size: "100m" # Allow file uploads up to 100MB +spec: + rules: + - host: grobid-dev.desci.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: grobid-dev + port: + number: 80 diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 0daceff5..e3825305 100755 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -211,6 +211,18 @@ services: - "9777:9777" # debugger - "7771:7771" # Uncomment if you want to test the media server from the host machine + grobid: + image: lfoppiano/grobid:0.8.0 + container_name: grobid + ports: + - "8070:8070" + environment: + - JAVA_OPTS=-Xmx2G -Xms2G + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8070/api/isalive"] + interval: 30s + timeout: 10s + retries: 5 # desci_nodes_backend_test: # container_name: 'be_test_boilerplate' From de30dd1f7f22e83a542d811c36b7b82753792d08 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Fri, 28 Jun 2024 06:46:25 +0200 Subject: [PATCH 241/278] remove notifycallback url from env --- .env.example | 3 +-- .env.test | 1 - desci-server/kubernetes/deployment_dev.yaml | 1 - desci-server/kubernetes/deployment_prod.yaml | 1 - desci-server/kubernetes/deployment_staging.yaml | 1 - desci-server/src/routes/v1/crossref.ts | 6 ++---- desci-server/src/types/ProcessEnv.d.ts | 1 - 7 files changed, 3 insertions(+), 11 deletions(-) diff --git a/.env.example b/.env.example index 2e31ac56..46f787fb 100755 --- a/.env.example +++ b/.env.example @@ -138,5 +138,4 @@ CROSSREF_LOGIN= CROSSREF_PASSWORD= # Cross ref notification callback envs -CROSSREF_NOTIFY_ENDPOINT= -CROSSREF_NOTIFY_CALLBACK_PATH= \ No newline at end of file +CROSSREF_NOTIFY_ENDPOINT= \ No newline at end of file diff --git a/.env.test b/.env.test index be2b5851..2139f026 100644 --- a/.env.test +++ b/.env.test @@ -88,7 +88,6 @@ CROSSREF_PASSWORD= # Cross ref notification callback envs CROSSREF_NOTIFY_ENDPOINT=endpoint -CROSSREF_NOTIFY_CALLBACK_PATH=/callback/endpoint # Automated metadata AUTOMATED_METADATA_API= diff --git a/desci-server/kubernetes/deployment_dev.yaml b/desci-server/kubernetes/deployment_dev.yaml index 9f17ff66..adfb7a73 100644 --- a/desci-server/kubernetes/deployment_dev.yaml +++ b/desci-server/kubernetes/deployment_dev.yaml @@ -90,7 +90,6 @@ spec: export CROSSREF_METADATA_API={{ .Data.CROSSREF_METADATA_API }} export CROSSREF_ADMIN_API={{ .Data.CROSSREF_ADMIN_API }} export CROSSREF_NOTIFY_ENDPOINT={{ .Data.CROSSREF_NOTIFY_ENDPOINT }} - export CROSSREF_NOTIFY_CALLBACK_PATH={{ .Data.CROSSREF_NOTIFY_CALLBACK_PATH }} export DEBUG_TEST=0; echo "appfinish"; {{- end -}} diff --git a/desci-server/kubernetes/deployment_prod.yaml b/desci-server/kubernetes/deployment_prod.yaml index bb4cd93e..5d368a64 100755 --- a/desci-server/kubernetes/deployment_prod.yaml +++ b/desci-server/kubernetes/deployment_prod.yaml @@ -90,7 +90,6 @@ spec: export CROSSREF_METADATA_API={{ .Data.CROSSREF_METADATA_API }} export CROSSREF_ADMIN_API={{ .Data.CROSSREF_ADMIN_API }} export CROSSREF_NOTIFY_ENDPOINT={{ .Data.CROSSREF_NOTIFY_ENDPOINT }} - export CROSSREF_NOTIFY_CALLBACK_PATH={{ .Data.CROSSREF_NOTIFY_CALLBACK_PATH }} export IGNORE_LINE=0; export DEBUG_TEST=0; echo "appfinish"; diff --git a/desci-server/kubernetes/deployment_staging.yaml b/desci-server/kubernetes/deployment_staging.yaml index e760a709..bf4d0f0a 100644 --- a/desci-server/kubernetes/deployment_staging.yaml +++ b/desci-server/kubernetes/deployment_staging.yaml @@ -102,7 +102,6 @@ spec: export CROSSREF_METADATA_API={{ .Data.CROSSREF_METADATA_API }} export CROSSREF_ADMIN_API={{ .Data.CROSSREF_ADMIN_API }} export CROSSREF_NOTIFY_ENDPOINT={{ .Data.CROSSREF_NOTIFY_ENDPOINT }} - export CROSSREF_NOTIFY_CALLBACK_PATH={{ .Data.CROSSREF_NOTIFY_CALLBACK_PATH }} export DEBUG_TEST=0; echo "appfinish"; {{- end -}} diff --git a/desci-server/src/routes/v1/crossref.ts b/desci-server/src/routes/v1/crossref.ts index ebe91f4f..e9518c80 100644 --- a/desci-server/src/routes/v1/crossref.ts +++ b/desci-server/src/routes/v1/crossref.ts @@ -12,10 +12,8 @@ import { const logger = parentLogger.child({ module: 'CROSSREF NOTIFICATION' }); // assert required env are available -if (!process.env.CROSSREF_NOTIFY_CALLBACK_PATH) throw Error('Env `CROSSREF_NOTIFY_CALLBACK_PATH` not set.'); if (!process.env.CROSSREF_NOTIFY_ENDPOINT) throw Error('Env `CROSSREF_NOTIFY_ENDPOINT` not set.'); -const notifierCallbackUrl = process.env.CROSSREF_NOTIFY_CALLBACK_PATH; const notifierEndpoint = process.env.CROSSREF_NOTIFY_ENDPOINT; const router = Router(); @@ -57,8 +55,8 @@ export const ensureCrossrefNotifier = (req: Request, _res: Response, next: NextF }; router.post( - notifierCallbackUrl, - [identifyEndpoint(notifierCallbackUrl), ensureCrossrefNotifier], + '/crossref/callback', + [identifyEndpoint('/crossref/callback'), ensureCrossrefNotifier], asyncHandler(handleCrossrefNotificationCallback), ); diff --git a/desci-server/src/types/ProcessEnv.d.ts b/desci-server/src/types/ProcessEnv.d.ts index 658b8f56..b29536c2 100755 --- a/desci-server/src/types/ProcessEnv.d.ts +++ b/desci-server/src/types/ProcessEnv.d.ts @@ -19,6 +19,5 @@ declare namespace NodeJS { CROSSREF_LOGIN: string; CROSSREF_PASSWORD: string; CROSSREF_NOTIFY_ENDPOINT: string; - CROSSREF_NOTIFY_CALLBACK_PATH: string; } } From cff0e189a371fca457b9f3f0be49e374ecaadc0d Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Fri, 28 Jun 2024 06:55:04 +0200 Subject: [PATCH 242/278] remove crossref api url from env --- .env.example | 2 -- .env.test | 1 - desci-server/kubernetes/deployment_dev.yaml | 1 - desci-server/kubernetes/deployment_prod.yaml | 1 - desci-server/kubernetes/deployment_staging.yaml | 1 - desci-server/src/services/crossRef/client.ts | 11 ++--------- desci-server/src/services/index.ts | 6 +----- desci-server/src/types/ProcessEnv.d.ts | 1 - 8 files changed, 3 insertions(+), 21 deletions(-) diff --git a/.env.example b/.env.example index 46f787fb..e857987c 100755 --- a/.env.example +++ b/.env.example @@ -129,10 +129,8 @@ DOI_PREFIX=10.62891 CROSSREF_DOI_URL=https://doi.org # Cross ref api -CROSSREF_API=https://api.crossref.org CROSSREF_METADATA_API=https://test.crossref.org/servlet/deposit CROSSREF_ADMIN_API=https://test.crossref.org -CROSSREF_API_KEY= CROSSREF_EMAIL= CROSSREF_LOGIN= CROSSREF_PASSWORD= diff --git a/.env.test b/.env.test index 2139f026..a983b852 100644 --- a/.env.test +++ b/.env.test @@ -78,7 +78,6 @@ DOI_PREFIX=10.62891 CROSSREF_DOI_URL=https://doi.org # Cross ref api -CROSSREF_API=https://api.crossref.org CROSSREF_METADATA_API=https://test.crossref.org/servlet/deposit CROSSREF_ADMIN_API=https://test.crossref.org CROSSREF_API_KEY= diff --git a/desci-server/kubernetes/deployment_dev.yaml b/desci-server/kubernetes/deployment_dev.yaml index adfb7a73..cc11c17e 100644 --- a/desci-server/kubernetes/deployment_dev.yaml +++ b/desci-server/kubernetes/deployment_dev.yaml @@ -81,7 +81,6 @@ spec: export ETHEREUM_RPC_URL={{ .Data.ETHEREUM_RPC_URL }} export GOOGLE_CLIENT_ID={{ .Data.GOOGLE_CLIENT_ID }} export DOI_PREFIX={{ .Data.DOI_PREFIX }} - export CROSSREF_API={{ .Data.CROSSREF_API }} export CROSSREF_API_KEY={{ .Data.CROSSREF_API_KEY }} export CROSSREF_EMAIL={{ .Data.CROSSREF_EMAIL }} export CROSSREF_DOI_URL={{ .Data.CROSSREF_DOI_URL }} diff --git a/desci-server/kubernetes/deployment_prod.yaml b/desci-server/kubernetes/deployment_prod.yaml index 5d368a64..785799e1 100755 --- a/desci-server/kubernetes/deployment_prod.yaml +++ b/desci-server/kubernetes/deployment_prod.yaml @@ -81,7 +81,6 @@ spec: export ETHEREUM_RPC_URL={{ .Data.ETHEREUM_RPC_URL }} export GOOGLE_CLIENT_ID={{ .Data.GOOGLE_CLIENT_ID }} export DOI_PREFIX={{ .Data.DOI_PREFIX }} - export CROSSREF_API={{ .Data.CROSSREF_API }} export CROSSREF_API_KEY={{ .Data.CROSSREF_API_KEY }} export CROSSREF_EMAIL={{ .Data.CROSSREF_EMAIL }} export CROSSREF_DOI_URL={{ .Data.CROSSREF_DOI_URL }} diff --git a/desci-server/kubernetes/deployment_staging.yaml b/desci-server/kubernetes/deployment_staging.yaml index bf4d0f0a..710eba17 100644 --- a/desci-server/kubernetes/deployment_staging.yaml +++ b/desci-server/kubernetes/deployment_staging.yaml @@ -93,7 +93,6 @@ spec: export ETHEREUM_RPC_URL={{ .Data.ETHEREUM_RPC_URL }} export GOOGLE_CLIENT_ID={{ .Data.GOOGLE_CLIENT_ID }} export DOI_PREFIX={{ .Data.DOI_PREFIX }} - export CROSSREF_API={{ .Data.CROSSREF_API }} export CROSSREF_API_KEY={{ .Data.CROSSREF_API_KEY }} export CROSSREF_EMAIL={{ .Data.CROSSREF_EMAIL }} export CROSSREF_DOI_URL={{ .Data.CROSSREF_DOI_URL }} diff --git a/desci-server/src/services/crossRef/client.ts b/desci-server/src/services/crossRef/client.ts index 9279f3dd..cd3d839c 100644 --- a/desci-server/src/services/crossRef/client.ts +++ b/desci-server/src/services/crossRef/client.ts @@ -98,19 +98,12 @@ type PublicationDate = { * Initialize constructor with CrossRef Api url https://api.crossref.org, Api token and a polite Mail */ class CrossRefClient { - baseurl: string; + baseurl = 'https://api.crossref.org'; constructor( - baseUrl: string, private _plusToken?: string, private _mailto?: string, - ) { - if (!baseUrl) { - logger.error('Pass Cross ref api as argument to CrossRefClient'); - throw Error('Pass Cross ref api as argument to CrossRefClient'); - } - this.baseurl = baseUrl; - } + ) {} /** * Returns a list of all works (journal articles, diff --git a/desci-server/src/services/index.ts b/desci-server/src/services/index.ts index 28aceb35..635b05e7 100644 --- a/desci-server/src/services/index.ts +++ b/desci-server/src/services/index.ts @@ -4,8 +4,4 @@ import CrossRefClient from './crossRef/client.js'; import { DoiService } from './Doi.js'; export const doiService = new DoiService(prisma); -export const crossRefClient = new CrossRefClient( - process.env.CROSSREF_API, - '', // process.env.CROSSREF_API_KEY, - process.env.CROSSREF_EMAIL, -); +export const crossRefClient = new CrossRefClient('', process.env.CROSSREF_EMAIL); diff --git a/desci-server/src/types/ProcessEnv.d.ts b/desci-server/src/types/ProcessEnv.d.ts index b29536c2..e3bf2cee 100755 --- a/desci-server/src/types/ProcessEnv.d.ts +++ b/desci-server/src/types/ProcessEnv.d.ts @@ -10,7 +10,6 @@ declare namespace NodeJS { JWT_SECRET: string; JWT_EXPIRATION: string; MAX_LOCK_TIME: string; - CROSSREF_API: string; CROSSREF_EMAIL: string; CROSSREF_DOI_URL: string; CROSSREF_API_KEY: string; From c5cf86dd2f8b7245236893d9a0fd546e43d8c8aa Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Fri, 28 Jun 2024 08:04:31 +0200 Subject: [PATCH 243/278] add metadata env to exmaple --- .env.example | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.env.example b/.env.example index e857987c..eecb25c4 100755 --- a/.env.example +++ b/.env.example @@ -136,4 +136,8 @@ CROSSREF_LOGIN= CROSSREF_PASSWORD= # Cross ref notification callback envs -CROSSREF_NOTIFY_ENDPOINT= \ No newline at end of file +CROSSREF_NOTIFY_ENDPOINT= + +# automated metadata +AUTOMATED_METADATA_API=http://host.docker.internal:5005 +AUTOMATED_METADATA_API_KEY= \ No newline at end of file From 4afde2a0ba0190b7479a874bd8d7162ae700551b Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Fri, 28 Jun 2024 11:15:05 +0200 Subject: [PATCH 244/278] updates for env vars --- desci-server/kubernetes/deployment_dev.yaml | 1 - desci-server/kubernetes/deployment_prod.yaml | 1 - desci-server/kubernetes/deployment_staging.yaml | 1 - desci-server/src/routes/v1/crossref.ts | 7 +++++-- desci-server/src/types/ProcessEnv.d.ts | 1 - 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/desci-server/kubernetes/deployment_dev.yaml b/desci-server/kubernetes/deployment_dev.yaml index cc11c17e..7771f947 100644 --- a/desci-server/kubernetes/deployment_dev.yaml +++ b/desci-server/kubernetes/deployment_dev.yaml @@ -81,7 +81,6 @@ spec: export ETHEREUM_RPC_URL={{ .Data.ETHEREUM_RPC_URL }} export GOOGLE_CLIENT_ID={{ .Data.GOOGLE_CLIENT_ID }} export DOI_PREFIX={{ .Data.DOI_PREFIX }} - export CROSSREF_API_KEY={{ .Data.CROSSREF_API_KEY }} export CROSSREF_EMAIL={{ .Data.CROSSREF_EMAIL }} export CROSSREF_DOI_URL={{ .Data.CROSSREF_DOI_URL }} export CROSSREF_LOGIN={{ .Data.CROSSREF_LOGIN }} diff --git a/desci-server/kubernetes/deployment_prod.yaml b/desci-server/kubernetes/deployment_prod.yaml index 785799e1..175c30fa 100755 --- a/desci-server/kubernetes/deployment_prod.yaml +++ b/desci-server/kubernetes/deployment_prod.yaml @@ -81,7 +81,6 @@ spec: export ETHEREUM_RPC_URL={{ .Data.ETHEREUM_RPC_URL }} export GOOGLE_CLIENT_ID={{ .Data.GOOGLE_CLIENT_ID }} export DOI_PREFIX={{ .Data.DOI_PREFIX }} - export CROSSREF_API_KEY={{ .Data.CROSSREF_API_KEY }} export CROSSREF_EMAIL={{ .Data.CROSSREF_EMAIL }} export CROSSREF_DOI_URL={{ .Data.CROSSREF_DOI_URL }} export CROSSREF_LOGIN={{ .Data.CROSSREF_LOGIN }} diff --git a/desci-server/kubernetes/deployment_staging.yaml b/desci-server/kubernetes/deployment_staging.yaml index 710eba17..7b7ec5a0 100644 --- a/desci-server/kubernetes/deployment_staging.yaml +++ b/desci-server/kubernetes/deployment_staging.yaml @@ -93,7 +93,6 @@ spec: export ETHEREUM_RPC_URL={{ .Data.ETHEREUM_RPC_URL }} export GOOGLE_CLIENT_ID={{ .Data.GOOGLE_CLIENT_ID }} export DOI_PREFIX={{ .Data.DOI_PREFIX }} - export CROSSREF_API_KEY={{ .Data.CROSSREF_API_KEY }} export CROSSREF_EMAIL={{ .Data.CROSSREF_EMAIL }} export CROSSREF_DOI_URL={{ .Data.CROSSREF_DOI_URL }} export CROSSREF_LOGIN={{ .Data.CROSSREF_LOGIN }} diff --git a/desci-server/src/routes/v1/crossref.ts b/desci-server/src/routes/v1/crossref.ts index e9518c80..c06f70f6 100644 --- a/desci-server/src/routes/v1/crossref.ts +++ b/desci-server/src/routes/v1/crossref.ts @@ -11,10 +11,13 @@ import { } from '../../internal.js'; const logger = parentLogger.child({ module: 'CROSSREF NOTIFICATION' }); +const DEFAULT_CROSSREF_ENDPOINT = '/callback/crossref'; // assert required env are available -if (!process.env.CROSSREF_NOTIFY_ENDPOINT) throw Error('Env `CROSSREF_NOTIFY_ENDPOINT` not set.'); +if (!process.env.CROSSREF_NOTIFY_ENDPOINT) { + logger.warn({ using: DEFAULT_CROSSREF_ENDPOINT }, 'Env `CROSSREF_NOTIFY_ENDPOINT` not set.'); +} -const notifierEndpoint = process.env.CROSSREF_NOTIFY_ENDPOINT; +const notifierEndpoint = process.env.CROSSREF_NOTIFY_ENDPOINT || DEFAULT_CROSSREF_ENDPOINT; const router = Router(); diff --git a/desci-server/src/types/ProcessEnv.d.ts b/desci-server/src/types/ProcessEnv.d.ts index e3bf2cee..7d9b73cb 100755 --- a/desci-server/src/types/ProcessEnv.d.ts +++ b/desci-server/src/types/ProcessEnv.d.ts @@ -12,7 +12,6 @@ declare namespace NodeJS { MAX_LOCK_TIME: string; CROSSREF_EMAIL: string; CROSSREF_DOI_URL: string; - CROSSREF_API_KEY: string; CROSSREF_METADATA_API: string; ORCID_API_DOMAIN: string; CROSSREF_LOGIN: string; From bb333baaf57ca718de815d47870ebe5257354622 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Fri, 28 Jun 2024 11:18:35 +0200 Subject: [PATCH 245/278] crossref env update --- .env.example | 2 +- desci-server/src/routes/v1/crossref.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index eecb25c4..98ee86e3 100755 --- a/.env.example +++ b/.env.example @@ -136,7 +136,7 @@ CROSSREF_LOGIN= CROSSREF_PASSWORD= # Cross ref notification callback envs -CROSSREF_NOTIFY_ENDPOINT= +CROSSREF_NOTIFY_ENDPOINT=endpoint # automated metadata AUTOMATED_METADATA_API=http://host.docker.internal:5005 diff --git a/desci-server/src/routes/v1/crossref.ts b/desci-server/src/routes/v1/crossref.ts index c06f70f6..fd62d557 100644 --- a/desci-server/src/routes/v1/crossref.ts +++ b/desci-server/src/routes/v1/crossref.ts @@ -11,7 +11,7 @@ import { } from '../../internal.js'; const logger = parentLogger.child({ module: 'CROSSREF NOTIFICATION' }); -const DEFAULT_CROSSREF_ENDPOINT = '/callback/crossref'; +const DEFAULT_CROSSREF_ENDPOINT = 'endpoint'; // assert required env are available if (!process.env.CROSSREF_NOTIFY_ENDPOINT) { logger.warn({ using: DEFAULT_CROSSREF_ENDPOINT }, 'Env `CROSSREF_NOTIFY_ENDPOINT` not set.'); From 97261791b1faf823f70f48e10d03234edab6d529 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Fri, 28 Jun 2024 12:14:48 +0200 Subject: [PATCH 246/278] replace orcid work api with open alex --- desci-server/src/controllers/nodes/doi.ts | 129 ++++++++++++++++------ 1 file changed, 97 insertions(+), 32 deletions(-) diff --git a/desci-server/src/controllers/nodes/doi.ts b/desci-server/src/controllers/nodes/doi.ts index 65c6b982..eba5d5ff 100644 --- a/desci-server/src/controllers/nodes/doi.ts +++ b/desci-server/src/controllers/nodes/doi.ts @@ -33,6 +33,50 @@ export const attachDoiSchema = z.object({ }), }); +export interface OpenAlexWork { + id: string; + title: string; + doi: string; + open_access: { + is_oa: boolean; + oa_status: string; + oa_url: string; + }; + best_oa_location: { + is_oa: boolean; + pdf_url: string; + }; + authorships: Array<{ + author_position: string; + author: { + id: string; + display_name: string; + orcid: string; + }; + institutions: Array<{ + id: string; + display_name: string; + ror: string; + country_code: string; + type: string; + lineage: string[]; + }>; + countries: string[]; + is_corresponding: boolean; + raw_author_name: string; + raw_affiliation_strings: string[]; + affiliations: Array<{ + raw_affiliation_string: string; + institution_ids: string[]; + }>; + }>; + keywords: Array<{ + id: string; + display_name: string; + score: number; + }>; +} + export const automateManuscriptDoi = async (req: RequestWithNode, res: Response, _next: NextFunction) => { const { uuid, path, prepublication } = req.body; @@ -53,48 +97,52 @@ export const automateManuscriptDoi = async (req: RequestWithNode, res: Response, const component = latestManifest.components[componentIndex] as PdfComponent; - // if (component.payload.doi) throw new ForbiddenError(`${component.subtype || component.type} already has a DOI`); - - const queryTitle = - component.payload.path.split('/').pop().replace(/\.pdf/g, '') || - component.name.replace(/\.pdf/g, '') || - component.payload.title; - - const works = await crossRefClient.listWorks({ - queryTitle, - rows: 5, - select: [WorkSelectOptions.DOI, WorkSelectOptions.TITLE, WorkSelectOptions.AUTHOR], - }); - - logger.info({ works }, 'Works Response'); - - const matchFound = works?.data?.message?.items.find((item) => - item.title.some((t) => t.toLowerCase() === queryTitle.toLowerCase()), - ); - - logger.info({ matchFound, queryTitle }, 'DOI Response'); - let doi: string; let metadata: MetadataResponse; - if (works.ok && matchFound) { - doi = matchFound.DOI; - metadata = transformWorkToMetadata(matchFound); + // if doi is present, pull from openalex + if (component.payload?.doi) { + doi = component.payload.doi[0]; + try { + const result = await fetch( + `https://api.openalex.org/works/doi:${doi}?select=id,title,doi,authorships,keywords,open_access,best_oa_location`, + { + headers: { + Accept: '*/*', + 'content-type': 'application/json', + }, + }, + ); + logger.info({ status: result.status, message: result.statusText }, 'OPEN ALEX QUERY'); + const work = (await result.json()) as OpenAlexWork; + logger.info({ openAlexWork: work }, 'OPEN ALEX QUERY'); + metadata = transformOpenAlexWorkToMetadata(work); + } catch (err) { + logger.error({ err }, 'ERROR: OPEN ALEX WORK QUERY'); + } } - // pull metadata from AM service - metadata = await metadataClient.getResourceMetadata({ - cid: component.payload.cid, - doi: doi || component.payload?.doi?.[0], - }); + if (!metadata) { + // pull metadata from AM service + metadata = await metadataClient.getResourceMetadata({ + cid: component.payload.cid, + doi: doi || component.payload?.doi?.[0], + }); + } // todo: pull metadata from crossrefClient#getDoiMetadata // const doiMetadata = await crossRefClient.getDoiMetadata(''); + logger.info({ metadata }, 'METADATA'); if (!metadata) throw new NotFoundError('DOI not found!'); const actions: ManifestActions[] = []; + if (!doi) { + // fallback to metadata.doi if component payload has no doi + doi = metadata?.doi; + } + if (doi) { actions.push({ type: 'Update Component', @@ -102,14 +150,19 @@ export const automateManuscriptDoi = async (req: RequestWithNode, res: Response, ...component, payload: { ...component.payload, - doi: component.payload?.doi ? component.payload.doi.concat([doi]) : [doi], - } as PdfComponentPayload, + doi: component.payload?.doi ? component.payload.doi : [doi], + ...(metadata?.keywords && { + keywords: component.payload?.keywords + ? component?.payload.keywords.concat(metadata.keywords) + : metadata.keywords, + }), + } as PdfComponentPayload & CommonComponentPayload, }, componentIndex, }); } - if (metadata?.abstract.trim()) { + if (metadata?.abstract?.trim()) { actions.push({ type: 'Update Description', description: metadata.abstract.trim(), @@ -149,6 +202,18 @@ export const automateManuscriptDoi = async (req: RequestWithNode, res: Response, new SuccessResponse(true).send(res); }; +const transformOpenAlexWorkToMetadata = (work: OpenAlexWork): MetadataResponse => { + const authors = work.authorships.map((author) => ({ + orcid: author.author?.orcid ? getOrcidFromURL(author.author.orcid) : null, + name: author.author.display_name, + affiliations: author?.institutions.map((org) => ({ name: org.display_name, id: org?.ror || '' })) ?? [], + })); + + const keywords = work?.keywords.map((entry) => entry.display_name) ?? []; + + return { title: work.title, doi: work.doi, authors, pdfUrl: '', keywords }; +}; + const transformWorkToMetadata = (work: Work): MetadataResponse => { const title = work.title[0]; const authors = work.author.map((author) => ({ From 67b9224f3c235d96ca537ebe72725910402450dd Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Fri, 28 Jun 2024 12:44:00 +0200 Subject: [PATCH 247/278] preview logging --- desci-media-isolated/kubernetes/deployment_dev.yaml | 8 ++++---- desci-media-isolated/src/controllers/pdf/preview.ts | 9 ++++++++- desci-server/scripts/be-node-dev.sh | 2 ++ 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/desci-media-isolated/kubernetes/deployment_dev.yaml b/desci-media-isolated/kubernetes/deployment_dev.yaml index 812ea016..36b1611e 100644 --- a/desci-media-isolated/kubernetes/deployment_dev.yaml +++ b/desci-media-isolated/kubernetes/deployment_dev.yaml @@ -48,9 +48,9 @@ spec: value: 'https://ipfs.desci.com/ipfs' resources: limits: - cpu: '0.5' - memory: 2Gi + cpu: '1' + memory: 4Gi requests: - cpu: 250m - memory: 1Gi + cpu: '1' + memory: 2Gi serviceAccountName: 'default' diff --git a/desci-media-isolated/src/controllers/pdf/preview.ts b/desci-media-isolated/src/controllers/pdf/preview.ts index 79cf4488..6788bfea 100644 --- a/desci-media-isolated/src/controllers/pdf/preview.ts +++ b/desci-media-isolated/src/controllers/pdf/preview.ts @@ -32,21 +32,27 @@ export const generatePreview = async ( try { // debugger; + console.log('start preview', cid); const previewPaths = await PdfManipulationService.generatePdfPreviews(cid, `${cid}.pdf`, pages, height); + console.log('done preview', cid); const previewBuffers: Buffer[] = []; for (const previewPath of previewPaths) { const fullPreviewPath = path.join(BASE_TEMP_DIR, THUMBNAIL_OUTPUT_DIR, previewPath); + console.log({ fullPreviewPath }); try { + console.log('star read', fullPreviewPath); const previewBuffer = await fs.readFile(fullPreviewPath); + console.log('done read', fullPreviewPath); previewBuffers.push(previewBuffer); } catch (err) { + console.error(err); throw new NotFoundError(`Preview not found for file with cid: ${cid}, path: ${previewPath}`); } } + console.log({ done: previewBuffers }); res.setHeader('Content-Type', 'application/json'); - res.status(200).json(previewBuffers); res.on('finish', async () => { // Cleanup generated previews after they're sent @@ -60,6 +66,7 @@ export const generatePreview = async ( logger.error({ error }, 'Error during cleanup:'); } }); + return res.status(200).json(previewBuffers); } catch (err: any) { return res.status(500).json({ message: err.message }); } diff --git a/desci-server/scripts/be-node-dev.sh b/desci-server/scripts/be-node-dev.sh index 6d84bbd5..62be4a8b 100755 --- a/desci-server/scripts/be-node-dev.sh +++ b/desci-server/scripts/be-node-dev.sh @@ -15,6 +15,8 @@ cd desci-server yarn run migrate npx prisma db seed +npm run script:seed-social-data + # import required images from ipfs to local chmod +x ./scripts/import-ipfs-content.sh ./scripts/import-ipfs-content.sh From c2a080759e25f7d9f83aabde3074a0fd43cec2ea Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Fri, 28 Jun 2024 12:47:59 +0200 Subject: [PATCH 248/278] fix: add missing optional doi field to interface --- desci-server/src/services/AutomatedMetadata.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/desci-server/src/services/AutomatedMetadata.ts b/desci-server/src/services/AutomatedMetadata.ts index 01da7c26..4ff40a8b 100644 --- a/desci-server/src/services/AutomatedMetadata.ts +++ b/desci-server/src/services/AutomatedMetadata.ts @@ -61,6 +61,7 @@ export type MetadataResponse = { title: string; pdfUrl: string | null; keywords: string[]; + doi?: string; }; /** From be67218352bd0db24a14ff828ab93c516dc9f637 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Fri, 28 Jun 2024 13:00:51 +0200 Subject: [PATCH 249/278] logging --- .../src/controllers/nodes/frontmatterPreview.ts | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/desci-server/src/controllers/nodes/frontmatterPreview.ts b/desci-server/src/controllers/nodes/frontmatterPreview.ts index 1898fed4..bc68957e 100644 --- a/desci-server/src/controllers/nodes/frontmatterPreview.ts +++ b/desci-server/src/controllers/nodes/frontmatterPreview.ts @@ -25,7 +25,9 @@ type FrontmatterPreviewErrorResponse = { error: string; status?: number; }; - +const logger = parentLogger.child({ + module: 'NODES::FrontmatterPreview', +}); /** * Generates previews for the frontmatter and first content page of a PDF * @param req.params.contentPageOnly will only generate the first content page preview (Used before frontmatter is generated) @@ -34,16 +36,12 @@ export const frontmatterPreview = async ( req: Request, res: Response, ) => { + logger.trace({ fn: 'Retrieving frontmatter previews', ...req.body, ...req.params }); const user = (req as any).user; const { uuid, pdfCid } = req.body; const { contentPageOnly } = req.params; - const logger = parentLogger.child({ - module: 'NODES::FrontmatterPreview', - uuid, - contentPageOnly, - userId: user?.id, - }); - logger.trace({ fn: 'Retrieving frontmatter previews' }); + + logger.trace({ fn: 'Retrieving frontmatter previews', uuid, contentPageOnly, userId: user?.id }); if (!uuid) return res.status(400).json({ ok: false, error: 'UUID is required.' }); if (!pdfCid) return res.status(400).json({ ok: false, error: 'pdfCid is required.' }); From 578e051368c78d28ff2f6e80bb77250f217550fa Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Fri, 28 Jun 2024 13:15:11 +0200 Subject: [PATCH 250/278] delete caching for previews for now --- desci-server/src/services/PublishPackage.ts | 28 ++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/desci-server/src/services/PublishPackage.ts b/desci-server/src/services/PublishPackage.ts index 4a14f005..b607dfb1 100644 --- a/desci-server/src/services/PublishPackage.ts +++ b/desci-server/src/services/PublishPackage.ts @@ -154,20 +154,20 @@ class PublishPackageService { } // Save it to the database - const existingPreviews = await prisma.pdfPreviews.findFirst({ - where: { pdfCid, nodeUuid }, - }); - - if (existingPreviews) { - await prisma.pdfPreviews.update({ - where: { id: existingPreviews.id }, - data: { previewMap }, - }); - } else { - await prisma.pdfPreviews.create({ - data: { nodeUuid: ensureUuidEndsWithDot(nodeUuid), pdfCid, previewMap }, - }); - } + // const existingPreviews = await prisma.pdfPreviews.findFirst({ + // where: { pdfCid, nodeUuid }, + // }); + + // if (existingPreviews) { + // await prisma.pdfPreviews.update({ + // where: { id: existingPreviews.id }, + // data: { previewMap }, + // }); + // } else { + // await prisma.pdfPreviews.create({ + // data: { nodeUuid: ensureUuidEndsWithDot(nodeUuid), pdfCid, previewMap }, + // }); + // } // LATER: Add data ref return previewMap; From a0bf259f5a3cb857f3eb34a7e7531ff37f57aecb Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Fri, 28 Jun 2024 11:22:54 +0000 Subject: [PATCH 251/278] fixes email, pino-pretty on media sever added --- desci-media-isolated/package-lock.json | 230 +++++++++++++++++- desci-media-isolated/package.json | 1 + .../nodes/contributions/prepubEmail.ts | 4 +- .../controllers/nodes/frontmatterPreview.ts | 2 +- 4 files changed, 231 insertions(+), 6 deletions(-) diff --git a/desci-media-isolated/package-lock.json b/desci-media-isolated/package-lock.json index d854697e..6c5118c3 100644 --- a/desci-media-isolated/package-lock.json +++ b/desci-media-isolated/package-lock.json @@ -19,6 +19,7 @@ "pdf2pic": "^3.1.1", "pdflib-fontkit": "^1.8.11", "pino": "^9.2.0", + "pino-pretty": "^7.0.0", "tsx": "^4.7.1" }, "devDependencies": { @@ -866,6 +867,84 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "node_modules/args": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/args/-/args-5.0.3.tgz", + "integrity": "sha512-h6k/zfFgusnv3i5TU08KQkVKuCPBtL/PWQbWkHUxvJrZ2nAyeaUupneemcrgn1xmqxPQsPIzwkUhOpoqPDRZuA==", + "dependencies": { + "camelcase": "5.0.0", + "chalk": "2.4.2", + "leven": "2.1.0", + "mri": "1.1.4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/args/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/args/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/args/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/args/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/args/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/args/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/args/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -1066,6 +1145,14 @@ "node": ">=6" } }, + "node_modules/camelcase": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", + "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", + "engines": { + "node": ">=6" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -1124,6 +1211,11 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/colorette": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", + "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==" + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -1212,6 +1304,14 @@ "node": ">= 8" } }, + "node_modules/dateformat": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", + "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", + "engines": { + "node": "*" + } + }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -1322,6 +1422,14 @@ "node": ">= 0.8" } }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, "node_modules/es-define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", @@ -1679,6 +1787,11 @@ "node": ">=6" } }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" + }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", @@ -2257,6 +2370,14 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, + "node_modules/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "engines": { + "node": ">=10" + } + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -2296,6 +2417,14 @@ "json-buffer": "3.0.1" } }, + "node_modules/leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -2453,6 +2582,14 @@ "node": ">=10" } }, + "node_modules/mri": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.4.tgz", + "integrity": "sha512-6y7IjGPm8AzlvoUrwAaw1tLnUBudaS3752vcd8JtrpGGQn+rXIe63LFVHm/YMwtqAuh+LJPCFdlLYPWM1nYn6w==", + "engines": { + "node": ">=4" + } + }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -2548,7 +2685,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "dependencies": { "wrappy": "1" } @@ -2771,6 +2907,76 @@ "safe-buffer": "~5.2.0" } }, + "node_modules/pino-pretty": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-7.0.0.tgz", + "integrity": "sha512-lU5RpkfssYJxRI/veMGsUu7RqTUD/NDb2r+U4VIx7Dyo5vA3MbbbGMUOhAM4e02IAYXuTAa/PH56s8shstP9BA==", + "dependencies": { + "args": "^5.0.1", + "colorette": "^1.3.0", + "dateformat": "^4.5.1", + "fast-safe-stringify": "^2.0.7", + "joycon": "^3.0.0", + "pino-abstract-transport": "^0.2.0", + "pump": "^3.0.0", + "readable-stream": "^3.6.0", + "rfdc": "^1.3.0", + "secure-json-parse": "^2.4.0", + "sonic-boom": "^2.2.0", + "strip-json-comments": "^3.1.1" + }, + "bin": { + "pino-pretty": "bin.js" + } + }, + "node_modules/pino-pretty/node_modules/pino-abstract-transport": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-0.2.0.tgz", + "integrity": "sha512-40sX7xrzDXsrUYr65brL0+bLm6rpZ+wCujDeeBmmZ/y5RVcPdVQsmz0bBe8NtTpELgmzmKwRRPVj1lvKjgFVHw==", + "dependencies": { + "split2": "^3.2.2" + } + }, + "node_modules/pino-pretty/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pino-pretty/node_modules/sonic-boom": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-2.8.0.tgz", + "integrity": "sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, + "node_modules/pino-pretty/node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/pino-pretty/node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/pino-std-serializers": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz", @@ -2825,6 +3031,15 @@ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -2978,6 +3193,11 @@ "node": ">=0.10.0" } }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==" + }, "node_modules/rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -3045,6 +3265,11 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/secure-json-parse": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", + "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==" + }, "node_modules/semver": { "version": "7.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", @@ -3576,8 +3801,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/xtend": { "version": "4.0.2", diff --git a/desci-media-isolated/package.json b/desci-media-isolated/package.json index 8430e3c5..acf66909 100644 --- a/desci-media-isolated/package.json +++ b/desci-media-isolated/package.json @@ -23,6 +23,7 @@ "pdf2pic": "^3.1.1", "pdflib-fontkit": "^1.8.11", "pino": "^9.2.0", + "pino-pretty": "^7.0.0", "tsx": "^4.7.1" }, "devDependencies": { diff --git a/desci-server/src/controllers/nodes/contributions/prepubEmail.ts b/desci-server/src/controllers/nodes/contributions/prepubEmail.ts index a39524f5..1caaad09 100644 --- a/desci-server/src/controllers/nodes/contributions/prepubEmail.ts +++ b/desci-server/src/controllers/nodes/contributions/prepubEmail.ts @@ -63,9 +63,9 @@ export const emailPublishPackage = async ( }); if (!node) return res.status(404).json({ ok: false, error: 'Node not found' }); - + // debugger; // const distPdfEntry = await prisma.distributionPdfs.findFirst({ - where: { distPdfCid: prepubDistPdfCid, nodeUuid: node.uuid }, + where: { distPdfCid: prepubDistPdfCid, nodeUuid: ensureUuidEndsWithDot(node.uuid) }, }); if (!distPdfEntry) return res.status(404).json({ ok: false, error: 'Distribution PDF not found' }); diff --git a/desci-server/src/controllers/nodes/frontmatterPreview.ts b/desci-server/src/controllers/nodes/frontmatterPreview.ts index 1898fed4..3f125c3e 100644 --- a/desci-server/src/controllers/nodes/frontmatterPreview.ts +++ b/desci-server/src/controllers/nodes/frontmatterPreview.ts @@ -44,7 +44,7 @@ export const frontmatterPreview = async ( userId: user?.id, }); logger.trace({ fn: 'Retrieving frontmatter previews' }); - + // debugger; if (!uuid) return res.status(400).json({ ok: false, error: 'UUID is required.' }); if (!pdfCid) return res.status(400).json({ ok: false, error: 'pdfCid is required.' }); From 1b1ed31e0debce2e714a0c08580382fddb283d12 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Fri, 28 Jun 2024 13:30:21 +0200 Subject: [PATCH 252/278] increase cpu limit --- desci-media-isolated/kubernetes/deployment_dev.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desci-media-isolated/kubernetes/deployment_dev.yaml b/desci-media-isolated/kubernetes/deployment_dev.yaml index 36b1611e..cf2b6ae0 100644 --- a/desci-media-isolated/kubernetes/deployment_dev.yaml +++ b/desci-media-isolated/kubernetes/deployment_dev.yaml @@ -48,7 +48,7 @@ spec: value: 'https://ipfs.desci.com/ipfs' resources: limits: - cpu: '1' + cpu: '4' memory: 4Gi requests: cpu: '1' From bdcfd76c35328d2bbabb1aa5a596ff9b0e241ec0 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Fri, 28 Jun 2024 13:40:49 +0200 Subject: [PATCH 253/278] remove bug --- desci-server/src/controllers/nodes/frontmatterPreview.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desci-server/src/controllers/nodes/frontmatterPreview.ts b/desci-server/src/controllers/nodes/frontmatterPreview.ts index f8bf13ee..bc68957e 100644 --- a/desci-server/src/controllers/nodes/frontmatterPreview.ts +++ b/desci-server/src/controllers/nodes/frontmatterPreview.ts @@ -48,7 +48,7 @@ export const frontmatterPreview = async ( if (user) { // Check if user owns node, if requesting previews - const node = await prisma.node.findFirst({\ + const node = await prisma.node.findFirst({ where: { ownerId: user.id, uuid: ensureUuidEndsWithDot(uuid), From 9799f481afdb4180e0841651634b044f775d3d1f Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Fri, 28 Jun 2024 13:50:38 +0200 Subject: [PATCH 254/278] k8s --- desci-server/kubernetes/deployment_dev.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/desci-server/kubernetes/deployment_dev.yaml b/desci-server/kubernetes/deployment_dev.yaml index b1fae99d..11066899 100644 --- a/desci-server/kubernetes/deployment_dev.yaml +++ b/desci-server/kubernetes/deployment_dev.yaml @@ -84,6 +84,8 @@ spec: export CROSSREF_API={{ .Data.CROSSREF_API }} export CROSSREF_API_KEY={{ .Data.CROSSREF_API_KEY }} export CROSSREF_EMAIL={{ .Data.CROSSREF_EMAIL }} + export AUTOMATED_METADATA_API={{ .Data.AUTOMATED_METADATA_API }} + export AUTOMATED_METADATA_API_KEY={{ .Data.AUTOMATED_METADATA_API_KEY }} export DEBUG_TEST=0; echo "appfinish"; {{- end -}} From 884a151859c80cb32b476cf97f7bc4d6a7d773a0 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Fri, 28 Jun 2024 13:50:38 +0200 Subject: [PATCH 255/278] setup envs --- desci-server/kubernetes/deployment_prod.yaml | 2 ++ desci-server/kubernetes/deployment_staging.yaml | 2 ++ desci-server/src/services/index.ts | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/desci-server/kubernetes/deployment_prod.yaml b/desci-server/kubernetes/deployment_prod.yaml index 855eabbe..e877e7f1 100755 --- a/desci-server/kubernetes/deployment_prod.yaml +++ b/desci-server/kubernetes/deployment_prod.yaml @@ -84,6 +84,8 @@ spec: export CROSSREF_API={{ .Data.CROSSREF_API }} export CROSSREF_API_KEY={{ .Data.CROSSREF_API_KEY }} export CROSSREF_EMAIL={{ .Data.CROSSREF_EMAIL }} + export AUTOMATED_METADATA_API={{ .Data.AUTOMATED_METADATA_API }} + export AUTOMATED_METADATA_API_KEY={{ .Data.AUTOMATED_METADATA_API_KEY }} export IGNORE_LINE=0; export DEBUG_TEST=0; echo "appfinish"; diff --git a/desci-server/kubernetes/deployment_staging.yaml b/desci-server/kubernetes/deployment_staging.yaml index b85b93ed..a0df1b69 100644 --- a/desci-server/kubernetes/deployment_staging.yaml +++ b/desci-server/kubernetes/deployment_staging.yaml @@ -96,6 +96,8 @@ spec: export CROSSREF_API={{ .Data.CROSSREF_API }} export CROSSREF_API_KEY={{ .Data.CROSSREF_API_KEY }} export CROSSREF_EMAIL={{ .Data.CROSSREF_EMAIL }} + export AUTOMATED_METADATA_API={{ .Data.AUTOMATED_METADATA_API }} + export AUTOMATED_METADATA_API_KEY={{ .Data.AUTOMATED_METADATA_API_KEY }} export DEBUG_TEST=0; echo "appfinish"; {{- end -}} diff --git a/desci-server/src/services/index.ts b/desci-server/src/services/index.ts index 946e7029..ceb05a37 100644 --- a/desci-server/src/services/index.ts +++ b/desci-server/src/services/index.ts @@ -12,5 +12,5 @@ export const crossRefClient = new CrossRefClient( ); export const metadataClient = new AutomatedMetadataClient( process.env.AUTOMATED_METADATA_API || 'http://host.docker.internal:5005', // remove this after env have been added to CI - process.env.AUTOMATED_METADATA_API_KEY, + process.env.AUTOMATED_METADATA_API_KEY || '', ); From 0b62b7435633cc770cda9907eb15f19765021dcf Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Fri, 28 Jun 2024 14:04:57 +0200 Subject: [PATCH 256/278] hack --- .../src/controllers/nodes/contributions/prepubEmail.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/desci-server/src/controllers/nodes/contributions/prepubEmail.ts b/desci-server/src/controllers/nodes/contributions/prepubEmail.ts index 1caaad09..74494849 100644 --- a/desci-server/src/controllers/nodes/contributions/prepubEmail.ts +++ b/desci-server/src/controllers/nodes/contributions/prepubEmail.ts @@ -64,10 +64,10 @@ export const emailPublishPackage = async ( if (!node) return res.status(404).json({ ok: false, error: 'Node not found' }); // debugger; // - const distPdfEntry = await prisma.distributionPdfs.findFirst({ - where: { distPdfCid: prepubDistPdfCid, nodeUuid: ensureUuidEndsWithDot(node.uuid) }, - }); - if (!distPdfEntry) return res.status(404).json({ ok: false, error: 'Distribution PDF not found' }); + // const distPdfEntry = await prisma.distributionPdfs.findFirst({ + // where: { distPdfCid: prepubDistPdfCid, nodeUuid: ensureUuidEndsWithDot(node.uuid) }, + // }); + // if (!distPdfEntry) return res.status(404).json({ ok: false, error: 'Distribution PDF not found' }); // Fire off email await publishServices.sendVersionUpdateEmailToAllContributors({ From 2f65e1f4b1c78427a39a4e3a41fbbcbff5ea3060 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Fri, 28 Jun 2024 15:42:02 +0200 Subject: [PATCH 257/278] fix env for automated metadata --- desci-server/kubernetes/deployment_dev.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/desci-server/kubernetes/deployment_dev.yaml b/desci-server/kubernetes/deployment_dev.yaml index 11066899..d28bc7b1 100644 --- a/desci-server/kubernetes/deployment_dev.yaml +++ b/desci-server/kubernetes/deployment_dev.yaml @@ -82,10 +82,9 @@ spec: export GOOGLE_CLIENT_ID={{ .Data.GOOGLE_CLIENT_ID }} export DOI_PREFIX={{ .Data.DOI_PREFIX }} export CROSSREF_API={{ .Data.CROSSREF_API }} - export CROSSREF_API_KEY={{ .Data.CROSSREF_API_KEY }} export CROSSREF_EMAIL={{ .Data.CROSSREF_EMAIL }} - export AUTOMATED_METADATA_API={{ .Data.AUTOMATED_METADATA_API }} - export AUTOMATED_METADATA_API_KEY={{ .Data.AUTOMATED_METADATA_API_KEY }} + export AUTOMATED_METADATA_API="{{ .Data.AUTOMATED_METADATA_API }}" + export AUTOMATED_METADATA_API_KEY="{{ .Data.AUTOMATED_METADATA_API_KEY }}" export DEBUG_TEST=0; echo "appfinish"; {{- end -}} From 427d1f7fe058687ec9e094f9a499c7fb72a01fc1 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Fri, 28 Jun 2024 15:49:30 +0200 Subject: [PATCH 258/278] automated metadata log --- desci-server/src/controllers/nodes/doi.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/desci-server/src/controllers/nodes/doi.ts b/desci-server/src/controllers/nodes/doi.ts index eba5d5ff..554f48c4 100644 --- a/desci-server/src/controllers/nodes/doi.ts +++ b/desci-server/src/controllers/nodes/doi.ts @@ -93,7 +93,17 @@ export const automateManuscriptDoi = async (req: RequestWithNode, res: Response, component.type === ResearchObjectComponentType.PDF && (component.payload as CommonComponentPayload).path === path, ); - if (componentIndex === -1) throw new BadRequestError('Component to attach DOI not a valid pdf'); + if (componentIndex === -1) { + logger.error( + { + path, + componentIndex, + components: latestManifest.components, + }, + 'Component to attach DOI not a valid pdf', + ); + throw new BadRequestError('Component to attach DOI not a valid pdf'); + } const component = latestManifest.components[componentIndex] as PdfComponent; From df3f887c58793a646d3d36549bb184862dd068e6 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Fri, 28 Jun 2024 17:53:32 +0200 Subject: [PATCH 259/278] more logging --- desci-server/src/controllers/nodes/doi.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/desci-server/src/controllers/nodes/doi.ts b/desci-server/src/controllers/nodes/doi.ts index 554f48c4..56682984 100644 --- a/desci-server/src/controllers/nodes/doi.ts +++ b/desci-server/src/controllers/nodes/doi.ts @@ -99,6 +99,7 @@ export const automateManuscriptDoi = async (req: RequestWithNode, res: Response, path, componentIndex, components: latestManifest.components, + latestManifest, }, 'Component to attach DOI not a valid pdf', ); From bd98677a882554e247ae4dde50ff881ed80dee44 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Fri, 28 Jun 2024 18:23:59 +0200 Subject: [PATCH 260/278] cid url --- desci-server/src/services/AutomatedMetadata.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desci-server/src/services/AutomatedMetadata.ts b/desci-server/src/services/AutomatedMetadata.ts index 4ff40a8b..17894fea 100644 --- a/desci-server/src/services/AutomatedMetadata.ts +++ b/desci-server/src/services/AutomatedMetadata.ts @@ -92,7 +92,7 @@ export class AutomatedMetadataClient { const body: { pdf: string; doi?: string } | { doi: string; pdf?: string } = { pdf: '' }; if (query.cid) { - body.pdf = query.cid; + body.pdf = `https://ipfs.desci.com/ipfs/${query.cid}`; } if (query.doi) { From 237b93d984840f6fa8a71c9acb4341d8655dc8a1 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Mon, 1 Jul 2024 10:54:47 +0200 Subject: [PATCH 261/278] parallel dev builds --- dockerDev.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dockerDev.sh b/dockerDev.sh index 7913c991..c130b3d5 100755 --- a/dockerDev.sh +++ b/dockerDev.sh @@ -72,6 +72,7 @@ COMPOSE_HTTP_TIMEOUT=320 docker-compose \ --file docker-compose.yml \ --file docker-compose.dev.yml \ --file docker-compose.repo.yml \ + --parallel=4 \ $ADDITIONAL_FLAGS \ --compatibility \ up \ From 3c0a190dceb2b5f29f34f7005921e590c3af0800 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Mon, 1 Jul 2024 11:05:45 +0200 Subject: [PATCH 262/278] update DOI registration workflow --- desci-server/src/services/Doi.ts | 7 ++++--- desci-server/src/services/crossRef/client.ts | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/desci-server/src/services/Doi.ts b/desci-server/src/services/Doi.ts index ed08af0d..23a7ccb0 100644 --- a/desci-server/src/services/Doi.ts +++ b/desci-server/src/services/Doi.ts @@ -48,10 +48,10 @@ export class DoiService { let claims = await attestationService.getProtectedNodeClaims(manifest.dpid.id); claims = claims.filter((claim) => claim.verifications > 0); - const hasClaimedRequiredAttestations = doiAttestations.every((attestation) => + const hasClaimedRequiredAttestation = doiAttestations.some((attestation) => claims.find((claim) => claim.attestationId === attestation.id), ); - if (!hasClaimedRequiredAttestations) throw new AttestationsError(); + if (!hasClaimedRequiredAttestation) throw new AttestationsError(); } async extractManuscriptDoi(manuscripts: PdfComponent[]) { @@ -111,7 +111,8 @@ export class DoiService { logger.info(manuscripts, 'MANUSCRIPTS'); if (manuscripts.length > 0) { - const existingDois = await this.extractManuscriptDoi(manuscripts); + const existingDois = manuscripts.filter((doc) => doc.payload?.doi && doc.payload.doi.length > 0); + // await this.extractManuscriptDoi(manuscripts); logger.info(existingDois, 'Existing DOI'); // does manuscript(s) already have a DOI diff --git a/desci-server/src/services/crossRef/client.ts b/desci-server/src/services/crossRef/client.ts index 7fc7a18d..03e39cc8 100644 --- a/desci-server/src/services/crossRef/client.ts +++ b/desci-server/src/services/crossRef/client.ts @@ -296,7 +296,7 @@ class CrossRefClient { logger.info(url, 'url params'); const request = new Request(url, config); try { - const response = await fetch(request); + const response = await global.fetch(request); if (!response.ok) return null; const body = await response.text(); logger.info(body, 'XML RESPONSE'); From 24a52ba96ffe222916c9d22135b218c72107c268 Mon Sep 17 00:00:00 2001 From: shadrach-tayo Date: Mon, 1 Jul 2024 14:47:21 +0200 Subject: [PATCH 263/278] feat: Extract paper abstract metadata from open alex abstract inverted index --- desci-server/src/controllers/nodes/doi.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/desci-server/src/controllers/nodes/doi.ts b/desci-server/src/controllers/nodes/doi.ts index 56682984..2f6cba16 100644 --- a/desci-server/src/controllers/nodes/doi.ts +++ b/desci-server/src/controllers/nodes/doi.ts @@ -75,6 +75,7 @@ export interface OpenAlexWork { display_name: string; score: number; }>; + abstract_inverted_index?: { [key: string]: number[] }; } export const automateManuscriptDoi = async (req: RequestWithNode, res: Response, _next: NextFunction) => { @@ -116,7 +117,7 @@ export const automateManuscriptDoi = async (req: RequestWithNode, res: Response, doi = component.payload.doi[0]; try { const result = await fetch( - `https://api.openalex.org/works/doi:${doi}?select=id,title,doi,authorships,keywords,open_access,best_oa_location`, + `https://api.openalex.org/works/doi:${doi}?select=id,title,doi,authorships,keywords,open_access,best_oa_location,abstract_inverted_index`, { headers: { Accept: '*/*', @@ -222,7 +223,17 @@ const transformOpenAlexWorkToMetadata = (work: OpenAlexWork): MetadataResponse = const keywords = work?.keywords.map((entry) => entry.display_name) ?? []; - return { title: work.title, doi: work.doi, authors, pdfUrl: '', keywords }; + const abstract = work?.abstract_inverted_index ? transformInvertedAbstractToText(work.abstract_inverted_index) : ''; + + return { title: work.title, doi: work.doi, authors, pdfUrl: '', keywords, abstract }; +}; + +const transformInvertedAbstractToText = (abstract: OpenAlexWork['abstract_inverted_index']) => { + const words = []; + Object.entries(abstract).map(([word, positions]) => { + positions.forEach((pos) => words.splice(pos, 0, word)); + }); + return words.filter(Boolean).join(' '); }; const transformWorkToMetadata = (work: Work): MetadataResponse => { From 92f864c879245c7599114ec2198649e5e36f0c56 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Tue, 2 Jul 2024 12:24:38 +0000 Subject: [PATCH 264/278] debugger delay bump --- desci-server/nodemon.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desci-server/nodemon.json b/desci-server/nodemon.json index c24de8fa..af589955 100644 --- a/desci-server/nodemon.json +++ b/desci-server/nodemon.json @@ -8,6 +8,6 @@ ], "verbose": true, "exec": "node -r ts-node/register --inspect=0.0.0.0:9228", - "delay": 300, + "delay": 750, "signal": "SIGTERM" } \ No newline at end of file From fd08d80ed066ff3c24c3cae6030e4a529d988370 Mon Sep 17 00:00:00 2001 From: kadami <86646883+kadamidev@users.noreply.github.com> Date: Tue, 2 Jul 2024 12:24:51 +0000 Subject: [PATCH 265/278] update copy for submission package email notif --- desci-server/src/services/PublishServices.ts | 9 +- .../templates/emails/SubmissionPackage.tsx | 108 ++++++++++++++++++ .../templates/emails/utils/emailRenderer.tsx | 3 + 3 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 desci-server/src/templates/emails/SubmissionPackage.tsx diff --git a/desci-server/src/services/PublishServices.ts b/desci-server/src/services/PublishServices.ts index 5fccf41b..7864bb8d 100644 --- a/desci-server/src/services/PublishServices.ts +++ b/desci-server/src/services/PublishServices.ts @@ -4,7 +4,7 @@ import sgMail from '@sendgrid/mail'; import { prisma } from '../client.js'; import { getNodeVersion, hexToCid } from '../internal.js'; import { logger as parentLogger } from '../logger.js'; -import { NodeUpdatedEmailHtml } from '../templates/emails/utils/emailRenderer.js'; +import { SubmissionPackageEmailHtml } from '../templates/emails/utils/emailRenderer.js'; import { getIndexedResearchObjects } from '../theGraph.js'; import { contributorService } from './Contributors.js'; @@ -51,7 +51,7 @@ export class PublishServices { } const emailPromises = contributors.map((contributor) => { - const emailHtml = NodeUpdatedEmailHtml({ + const emailHtml = SubmissionPackageEmailHtml({ nodeOwner: nodeOwner.name, nodeUuid: node.uuid, nodeTitle: node.title, @@ -63,11 +63,10 @@ export class PublishServices { const emailMsg = { to: contributor.email, from: 'no-reply@desci.com', - subject: `[nodes.desci.com] DPID ${dpid || '(DEMO)'} has been updated`, - text: `${nodeOwner.name} has published an updated version (${versionPublished}) of their research object titled "${node.title}" that you have contributed to.`, + subject: `[nodes.desci.com] Your submission package is ready`, + text: `${nodeOwner.name} has published their research object titled "${node.title}" that you have contributed to.`, html: emailHtml, }; - return { contributor, emailMsg }; }); diff --git a/desci-server/src/templates/emails/SubmissionPackage.tsx b/desci-server/src/templates/emails/SubmissionPackage.tsx new file mode 100644 index 00000000..ee0822ca --- /dev/null +++ b/desci-server/src/templates/emails/SubmissionPackage.tsx @@ -0,0 +1,108 @@ +import { Body, Container, Head, Heading, Html, Preview, Text, Button, Section } from '@react-email/components'; +import * as React from 'react'; + +import { PUBLIC_IPFS_PATH } from '../../config/index.js'; + +import MainLayout from './MainLayout.js'; + +export interface SubmissionPackageEmailProps { + nodeOwner: string; + nodeTitle: string; + nodeUuid: string; + nodeDpid: string; + versionUpdate: string; + manuscriptCid: string; +} + +const DAPP_URL = process.env.DAPP_URL || 'http://localhost:3000'; + +export const SubmissionPackage = ({ + nodeOwner, + nodeTitle, + nodeUuid, + nodeDpid, + versionUpdate, + manuscriptCid, +}: SubmissionPackageEmailProps) => { + if (nodeUuid?.endsWith('.') || nodeUuid?.endsWith('=')) nodeUuid = nodeUuid.slice(0, -1); + nodeOwner = nodeOwner || 'The node owner'; + nodeDpid = nodeDpid || '(DEMO)'; + versionUpdate = versionUpdate || '1'; // For demo case + const nodeUrl = `${DAPP_URL}/dpid/${nodeDpid}/${versionUpdate}`; + const manuscriptUrl = `${PUBLIC_IPFS_PATH}/${manuscriptCid}`; + return ( + + + + Your submission package is ready + + + + A submission package has been created for your node with DPID {nodeDpid} + + + {nodeOwner} has published their research object titled "{nodeTitle}" + that you have contributed to. + + +