diff --git a/package-lock.json b/package-lock.json index bb8d2a2..953144c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", "@mui/material": "^5.14.6", + "@nostr-dev-kit/ndk": "^2.0.3", "@nostrband/ndk": "^0.7.8", "@nostrband/nostr-tools": "^1.14.4", "@reduxjs/toolkit": "^1.9.7", @@ -18,7 +19,7 @@ "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "aphrodite": "^2.4.0", - "axios": "^1.4.0", + "axios": "^1.5.1", "bootstrap": "^5.2.3", "bs5-lightbox": "^1.8.3", "chart.js": "^3.9.1", @@ -4234,6 +4235,14 @@ "eslint-scope": "5.1.1" } }, + "node_modules/@noble/ciphers": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.2.0.tgz", + "integrity": "sha512-6YBxJDAapHSdd3bLDv6x2wRPwq4QFMUaB3HvljNBUTThDd12eSm7/3F+2lnfzx2jvM+S6Nsy0jEt9QbPqSwqRw==", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@noble/curves": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.0.0.tgz", @@ -4302,6 +4311,128 @@ "node": ">= 8" } }, + "node_modules/@nostr-dev-kit/ndk": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nostr-dev-kit/ndk/-/ndk-2.0.3.tgz", + "integrity": "sha512-rKIJBIU0dZHaXwj1TY18VSLYsoIe1aQ7TAxkH3WFx3lGTXCz+nlGh5bsyvgMBdbyb0iecdjsaKqBRpEWMzYC9g==", + "dependencies": { + "@noble/hashes": "^1.3.1", + "@noble/secp256k1": "^2.0.0", + "@scure/base": "^1.1.1", + "debug": "^4.3.4", + "eventemitter3": "^5.0.1", + "light-bolt11-decoder": "^3.0.0", + "node-fetch": "^3.3.1", + "nostr-tools": "^1.15.0", + "typescript-lru-cache": "^2.0.0", + "utf8-buffer": "^1.0.0", + "websocket-polyfill": "^0.0.3" + } + }, + "node_modules/@nostr-dev-kit/ndk/node_modules/@noble/curves": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz", + "integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==", + "dependencies": { + "@noble/hashes": "1.3.1" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nostr-dev-kit/ndk/node_modules/@noble/curves/node_modules/@noble/hashes": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", + "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nostr-dev-kit/ndk/node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nostr-dev-kit/ndk/node_modules/@scure/bip32": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.1.tgz", + "integrity": "sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==", + "dependencies": { + "@noble/curves": "~1.1.0", + "@noble/hashes": "~1.3.1", + "@scure/base": "~1.1.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nostr-dev-kit/ndk/node_modules/@scure/bip39": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz", + "integrity": "sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==", + "dependencies": { + "@noble/hashes": "~1.3.0", + "@scure/base": "~1.1.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nostr-dev-kit/ndk/node_modules/nostr-tools": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/nostr-tools/-/nostr-tools-1.17.0.tgz", + "integrity": "sha512-LZmR8GEWKZeElbFV5Xte75dOeE9EFUW/QLI1Ncn3JKn0kFddDKEfBbFN8Mu4TMs+L4HR/WTPha2l+PPuRnJcMw==", + "dependencies": { + "@noble/ciphers": "0.2.0", + "@noble/curves": "1.1.0", + "@noble/hashes": "1.3.1", + "@scure/base": "1.1.1", + "@scure/bip32": "1.3.1", + "@scure/bip39": "1.2.1" + }, + "peerDependencies": { + "typescript": ">=5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@nostr-dev-kit/ndk/node_modules/nostr-tools/node_modules/@noble/hashes": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", + "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nostr-dev-kit/ndk/node_modules/typescript": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "optional": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/@nostrband/ndk": { "version": "0.7.8", "resolved": "https://registry.npmjs.org/@nostrband/ndk/-/ndk-0.7.8.tgz", @@ -6318,9 +6449,9 @@ } }, "node_modules/axios": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", - "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.1.tgz", + "integrity": "sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==", "dependencies": { "follow-redirects": "^1.15.0", "form-data": "^4.0.0", @@ -19144,6 +19275,11 @@ "node": ">=4.2.0" } }, + "node_modules/typescript-lru-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/typescript-lru-cache/-/typescript-lru-cache-2.0.0.tgz", + "integrity": "sha512-Jp57Qyy8wXeMkdNuZiglE6v2Cypg13eDA1chHwDG6kq51X7gk4K7P7HaDdzZKCxkegXkVHNcPD0n5aW6OZH3aA==" + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -23302,6 +23438,11 @@ "eslint-scope": "5.1.1" } }, + "@noble/ciphers": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.2.0.tgz", + "integrity": "sha512-6YBxJDAapHSdd3bLDv6x2wRPwq4QFMUaB3HvljNBUTThDd12eSm7/3F+2lnfzx2jvM+S6Nsy0jEt9QbPqSwqRw==" + }, "@noble/curves": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.0.0.tgz", @@ -23343,6 +23484,92 @@ "fastq": "^1.6.0" } }, + "@nostr-dev-kit/ndk": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nostr-dev-kit/ndk/-/ndk-2.0.3.tgz", + "integrity": "sha512-rKIJBIU0dZHaXwj1TY18VSLYsoIe1aQ7TAxkH3WFx3lGTXCz+nlGh5bsyvgMBdbyb0iecdjsaKqBRpEWMzYC9g==", + "requires": { + "@noble/hashes": "^1.3.1", + "@noble/secp256k1": "^2.0.0", + "@scure/base": "^1.1.1", + "debug": "^4.3.4", + "eventemitter3": "^5.0.1", + "light-bolt11-decoder": "^3.0.0", + "node-fetch": "^3.3.1", + "nostr-tools": "^1.15.0", + "typescript-lru-cache": "^2.0.0", + "utf8-buffer": "^1.0.0", + "websocket-polyfill": "^0.0.3" + }, + "dependencies": { + "@noble/curves": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz", + "integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==", + "requires": { + "@noble/hashes": "1.3.1" + }, + "dependencies": { + "@noble/hashes": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", + "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==" + } + } + }, + "@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==" + }, + "@scure/bip32": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.1.tgz", + "integrity": "sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==", + "requires": { + "@noble/curves": "~1.1.0", + "@noble/hashes": "~1.3.1", + "@scure/base": "~1.1.0" + } + }, + "@scure/bip39": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz", + "integrity": "sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==", + "requires": { + "@noble/hashes": "~1.3.0", + "@scure/base": "~1.1.0" + } + }, + "nostr-tools": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/nostr-tools/-/nostr-tools-1.17.0.tgz", + "integrity": "sha512-LZmR8GEWKZeElbFV5Xte75dOeE9EFUW/QLI1Ncn3JKn0kFddDKEfBbFN8Mu4TMs+L4HR/WTPha2l+PPuRnJcMw==", + "requires": { + "@noble/ciphers": "0.2.0", + "@noble/curves": "1.1.0", + "@noble/hashes": "1.3.1", + "@scure/base": "1.1.1", + "@scure/bip32": "1.3.1", + "@scure/bip39": "1.2.1" + }, + "dependencies": { + "@noble/hashes": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", + "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==" + } + } + }, + "typescript": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "optional": true, + "peer": true + } + } + }, "@nostrband/ndk": { "version": "0.7.8", "resolved": "https://registry.npmjs.org/@nostrband/ndk/-/ndk-0.7.8.tgz", @@ -24841,9 +25068,9 @@ "integrity": "sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g==" }, "axios": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", - "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.1.tgz", + "integrity": "sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==", "requires": { "follow-redirects": "^1.15.0", "form-data": "^4.0.0", @@ -34188,6 +34415,11 @@ "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "peer": true }, + "typescript-lru-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/typescript-lru-cache/-/typescript-lru-cache-2.0.0.tgz", + "integrity": "sha512-Jp57Qyy8wXeMkdNuZiglE6v2Cypg13eDA1chHwDG6kq51X7gk4K7P7HaDdzZKCxkegXkVHNcPD0n5aW6OZH3aA==" + }, "unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", diff --git a/package.json b/package.json index 44d418c..98eecd7 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", "@mui/material": "^5.14.6", + "@nostr-dev-kit/ndk": "^2.0.3", "@nostrband/ndk": "^0.7.8", "@nostrband/nostr-tools": "^1.14.4", "@reduxjs/toolkit": "^1.9.7", @@ -12,7 +13,7 @@ "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "aphrodite": "^2.4.0", - "axios": "^1.4.0", + "axios": "^1.5.1", "bootstrap": "^5.2.3", "bs5-lightbox": "^1.8.3", "chart.js": "^3.9.1", diff --git a/server/botScript.js b/server/botScript.js new file mode 100644 index 0000000..dfdce80 --- /dev/null +++ b/server/botScript.js @@ -0,0 +1,80 @@ +const { + default: NDK, + default: NDKEvent, + NDKRelaySet, +} = require('@nostr-dev-kit/ndk'); + +const axios = require('axios').default; + +const BOT_PUBKEY = + 'd0b48e6a4a36bb75520ba384dd9401f2744e1b70ce94ff05dec9c267a7e96e2a'; +const KIND_TEST = 100030117; +const KIND_REAL = 30117; + +const ndk = new NDK({ + relays: [ + 'wss://relay.nostr.band/all', + 'wss://nos.lol', + 'wss://relay.damus.io', + 'wss://nostr.mutinywallet.com', + ], +}); + +async function publishRepo(repo) { + console.log(repo, 'REPO'); + const published_at = repo.created_at; + const content = { + description: repo.description.slice(0, 300), + license: repo.license?.key || 'none', + tags: repo.topics, + }; + + const ndkEvent = new NDKEvent(ndk); + ndkEvent.kind = KIND_TEST; + ndkEvent.pubkey = BOT_PUBKEY; + ndkEvent.tags = [ + ['d', `${repo.owner.login}/${repo.name}`], + ['published_at', published_at], + ]; + ndkEvent.content = JSON.stringify(content); + ndkEvent.created_at = Math.floor(Date.now() / 1000); + + const relaySet = NDKRelaySet.fromRelayUrls( + [ + 'wss://relay.nostr.band/all', + 'wss://nos.lol', + 'wss://relay.damus.io', + 'wss://nostr.mutinywallet.com', + ], + ndk + ); + + await ndkEvent.publish(relaySet); +} + +async function scanGithub() { + let page = 1; + const baseURL = + 'https://api.github.com/search/repositories?q=nostr&per_page=100&page='; + + while (true) { + try { + const response = await axios.get(baseURL + page); + if (!response.data.items.length) break; + + for (const repo of response.data.items) { + await publishRepo(repo); + await new Promise((resolve) => setTimeout(resolve, 2000)); + } + page++; + } catch (error) { + console.error('Error scanning GitHub:', error); + break; + } + } +} + +(async () => { + setInterval(scanGithub, 24 * 60 * 60 * 1000); + scanGithub(); +})();