From 3962568da3f6732016f63dd2a37f4f4ea5dbabbf Mon Sep 17 00:00:00 2001 From: neeteshkaushik <36589237+neeteshkaushik@users.noreply.github.com> Date: Sun, 10 Nov 2024 14:40:49 +0530 Subject: [PATCH] completed all functionality --- .gitignore | 3 +- nodemon.json | 6 + package-lock.json | 787 ++++++++++++++++++++++++++++++++++++++++- package.json | 11 +- src/WebhookEvent.ts | 27 ++ src/address.ts | 93 ++++- src/config/database.ts | 14 + src/config/solana.ts | 7 + src/index.ts | 103 ++++-- src/mintTokens.ts | 113 +++++- src/util.ts | 25 ++ 11 files changed, 1142 insertions(+), 47 deletions(-) create mode 100644 nodemon.json create mode 100644 src/WebhookEvent.ts create mode 100644 src/config/database.ts create mode 100644 src/config/solana.ts create mode 100644 src/util.ts diff --git a/.gitignore b/.gitignore index 1dcef2d..8f00ef2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules -.env \ No newline at end of file +.env +dist \ No newline at end of file diff --git a/nodemon.json b/nodemon.json new file mode 100644 index 0000000..c2165ca --- /dev/null +++ b/nodemon.json @@ -0,0 +1,6 @@ +{ + "watch": ["src"], + "ext": ".ts", + "ignore": [], + "exec": "tsc && node ./dist/index.js" +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index c7d7c9f..82f47d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,11 +9,17 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "@solana/spl-token": "^0.4.9", "@solana/web3.js": "^1.95.4", "@types/express": "^5.0.0", + "bs58": "^6.0.0", "dotenv": "^16.4.5", "express": "^4.21.1", + "mongoose": "^8.8.1", "typescript": "^5.6.3" + }, + "devDependencies": { + "nodemon": "^3.1.7" } }, "node_modules/@babel/runtime": { @@ -28,6 +34,14 @@ "node": ">=6.9.0" } }, + "node_modules/@mongodb-js/saslprep": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.9.tgz", + "integrity": "sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw==", + "dependencies": { + "sparse-bitfield": "^3.0.3" + } + }, "node_modules/@noble/curves": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.6.0.tgz", @@ -67,6 +81,169 @@ "node": ">=5.10" } }, + "node_modules/@solana/buffer-layout-utils": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout-utils/-/buffer-layout-utils-0.2.0.tgz", + "integrity": "sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==", + "dependencies": { + "@solana/buffer-layout": "^4.0.0", + "@solana/web3.js": "^1.32.0", + "number-buffer": "^1.1.5", + "bignumber.js": "^9.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@solana/codecs": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs/-/codecs-2.0.0-rc.1.tgz", + "integrity": "sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/codecs-data-structures": "2.0.0-rc.1", + "@solana/codecs-numbers": "2.0.0-rc.1", + "@solana/codecs-strings": "2.0.0-rc.1", + "@solana/options": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/codecs-core": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs-core/-/codecs-core-2.0.0-rc.1.tgz", + "integrity": "sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==", + "dependencies": { + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/codecs-data-structures": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs-data-structures/-/codecs-data-structures-2.0.0-rc.1.tgz", + "integrity": "sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/codecs-numbers": "2.0.0-rc.1", + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/codecs-numbers": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs-numbers/-/codecs-numbers-2.0.0-rc.1.tgz", + "integrity": "sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/codecs-strings": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs-strings/-/codecs-strings-2.0.0-rc.1.tgz", + "integrity": "sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/codecs-numbers": "2.0.0-rc.1", + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "fastestsmallesttextencoderdecoder": "^1.0.22", + "typescript": ">=5" + } + }, + "node_modules/@solana/errors": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/errors/-/errors-2.0.0-rc.1.tgz", + "integrity": "sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==", + "dependencies": { + "chalk": "^5.3.0", + "commander": "^12.1.0" + }, + "bin": { + "errors": "bin/cli.mjs" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/errors/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "engines": { + "node": ">=18" + } + }, + "node_modules/@solana/options": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/options/-/options-2.0.0-rc.1.tgz", + "integrity": "sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/codecs-data-structures": "2.0.0-rc.1", + "@solana/codecs-numbers": "2.0.0-rc.1", + "@solana/codecs-strings": "2.0.0-rc.1", + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/spl-token": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.4.9.tgz", + "integrity": "sha512-g3wbj4F4gq82YQlwqhPB0gHFXfgsC6UmyGMxtSLf/BozT/oKd59465DbnlUK8L8EcimKMavxsVAMoLcEdeCicg==", + "dependencies": { + "@solana/buffer-layout": "^4.0.0", + "@solana/buffer-layout-utils": "^0.2.0", + "@solana/spl-token-group": "^0.0.7", + "@solana/spl-token-metadata": "^0.1.6", + "buffer": "^6.0.3" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@solana/web3.js": "^1.95.3" + } + }, + "node_modules/@solana/spl-token-group": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/@solana/spl-token-group/-/spl-token-group-0.0.7.tgz", + "integrity": "sha512-V1N/iX7Cr7H0uazWUT2uk27TMqlqedpXHRqqAbVO2gvmJyT0E0ummMEAVQeXZ05ZhQ/xF39DLSdBp90XebWEug==", + "dependencies": { + "@solana/codecs": "2.0.0-rc.1" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@solana/web3.js": "^1.95.3" + } + }, + "node_modules/@solana/spl-token-metadata": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@solana/spl-token-metadata/-/spl-token-metadata-0.1.6.tgz", + "integrity": "sha512-7sMt1rsm/zQOQcUWllQX9mD2O6KhSAtY1hFR2hfFwgqfFWzSY9E9GDvFVNYUI1F0iQKcm6HmePU9QbKRXTEBiA==", + "dependencies": { + "@solana/codecs": "2.0.0-rc.1" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@solana/web3.js": "^1.95.3" + } + }, "node_modules/@solana/web3.js": { "version": "1.95.4", "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.95.4.tgz", @@ -78,7 +255,7 @@ "@noble/hashes": "^1.4.0", "@solana/buffer-layout": "^4.0.1", "agentkeepalive": "^4.5.0", - "bigint-buffer": "^1.1.5", + "number-buffer": "^1.1.5", "bn.js": "^5.2.1", "borsh": "^0.7.0", "bs58": "^4.0.1", @@ -90,6 +267,22 @@ "superstruct": "^2.0.2" } }, + "node_modules/@solana/web3.js/node_modules/base-x": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.10.tgz", + "integrity": "sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/@solana/web3.js/node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dependencies": { + "base-x": "^3.0.2" + } + }, "node_modules/@swc/helpers": { "version": "0.5.13", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.13.tgz", @@ -199,6 +392,19 @@ "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", "license": "MIT" }, + "node_modules/@types/webidl-conversions": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" + }, + "node_modules/@types/whatwg-url": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz", + "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==", + "dependencies": { + "@types/webidl-conversions": "*" + } + }, "node_modules/@types/ws": { "version": "7.4.7", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", @@ -233,20 +439,35 @@ "node": ">= 8.0.0" } }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "license": "MIT" }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, "node_modules/base-x": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.10.tgz", - "integrity": "sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==", - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.0.1" - } + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-5.0.0.tgz", + "integrity": "sha512-sMW3VGSX1QWVFA6l8U62MLKz29rRfpTlYdCqLdpLo1/Yd4zZwSbnUaDfciIAowAqvq7YFnWq9hrhdg1KYgc1lQ==" }, "node_modules/base64-js": { "version": "1.5.1", @@ -268,9 +489,9 @@ ], "license": "MIT" }, - "node_modules/bigint-buffer": { + "node_modules/number-buffer": { "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bigint-buffer/-/bigint-buffer-1.1.5.tgz", + "resolved": "https://registry.npmjs.org/number-buffer/-/number-buffer-1.1.5.tgz", "integrity": "sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==", "hasInstallScript": true, "license": "Apache-2.0", @@ -281,6 +502,26 @@ "node": ">= 10.0.0" } }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/bindings": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", @@ -300,7 +541,6 @@ "version": "1.20.3", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", - "license": "MIT", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -331,15 +571,60 @@ "text-encoding-utf-8": "^1.0.2" } }, - "node_modules/bs58": { + "node_modules/borsh/node_modules/base-x": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.10.tgz", + "integrity": "sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/borsh/node_modules/bs58": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", - "license": "MIT", "dependencies": { "base-x": "^3.0.2" } }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/bs58": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-6.0.0.tgz", + "integrity": "sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==", + "dependencies": { + "base-x": "^5.0.0" + } + }, + "node_modules/bson": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.9.0.tgz", + "integrity": "sha512-X9hJeyeM0//Fus+0pc5dSUMhhrrmWwQUtdavaQeF3Ta6m69matZkGWV/MrBcnwUeLC8W9kwwc2hfkZgUuCX3Ig==", + "engines": { + "node": ">=16.20.1" + } + }, "node_modules/buffer": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", @@ -406,12 +691,53 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "license": "MIT" }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -651,12 +977,30 @@ "integrity": "sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==", "license": "MIT" }, + "node_modules/fastestsmallesttextencoderdecoder": { + "version": "1.0.22", + "resolved": "https://registry.npmjs.org/fastestsmallesttextencoderdecoder/-/fastestsmallesttextencoderdecoder-1.0.22.tgz", + "integrity": "sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==", + "peer": true + }, "node_modules/file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", "license": "MIT" }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/finalhandler": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", @@ -693,6 +1037,20 @@ "node": ">= 0.6" } }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -721,6 +1079,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -733,6 +1103,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/has-property-descriptors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", @@ -838,6 +1217,12 @@ ], "license": "BSD-3-Clause" }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -853,6 +1238,48 @@ "node": ">= 0.10" } }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/isomorphic-ws": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", @@ -919,6 +1346,14 @@ "node": "*" } }, + "node_modules/kareem": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz", + "integrity": "sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -928,6 +1363,11 @@ "node": ">= 0.6" } }, + "node_modules/memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" + }, "node_modules/merge-descriptors": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", @@ -979,6 +1419,159 @@ "node": ">= 0.6" } }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mongodb": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.10.0.tgz", + "integrity": "sha512-gP9vduuYWb9ZkDM546M+MP2qKVk5ZG2wPF63OvSRuUbqCR+11ZCAE1mOfllhlAG0wcoJY5yDL/rV3OmYEwXIzg==", + "dependencies": { + "@mongodb-js/saslprep": "^1.1.5", + "bson": "^6.7.0", + "mongodb-connection-string-url": "^3.0.0" + }, + "engines": { + "node": ">=16.20.1" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.188.0", + "@mongodb-js/zstd": "^1.1.0", + "gcp-metadata": "^5.2.0", + "kerberos": "^2.0.1", + "mongodb-client-encryption": ">=6.0.0 <7", + "snappy": "^7.2.2", + "socks": "^2.7.1" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "@mongodb-js/zstd": { + "optional": true + }, + "gcp-metadata": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + }, + "socks": { + "optional": true + } + } + }, + "node_modules/mongodb-connection-string-url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.1.tgz", + "integrity": "sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==", + "dependencies": { + "@types/whatwg-url": "^11.0.2", + "whatwg-url": "^13.0.0" + } + }, + "node_modules/mongodb-connection-string-url/node_modules/tr46": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", + "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "dependencies": { + "punycode": "^2.3.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/mongodb-connection-string-url/node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "engines": { + "node": ">=12" + } + }, + "node_modules/mongodb-connection-string-url/node_modules/whatwg-url": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", + "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", + "dependencies": { + "tr46": "^4.1.1", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/mongoose": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.8.1.tgz", + "integrity": "sha512-l7DgeY1szT98+EKU8GYnga5WnyatAu+kOQ2VlVX1Mxif6A0Umt0YkSiksCiyGxzx8SPhGe9a53ND1GD4yVDrPA==", + "dependencies": { + "bson": "^6.7.0", + "kareem": "2.6.3", + "mongodb": "~6.10.0", + "mpath": "0.9.0", + "mquery": "5.0.0", + "ms": "2.1.3", + "sift": "17.1.3" + }, + "engines": { + "node": ">=16.20.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mongoose" + } + }, + "node_modules/mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mquery": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", + "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", + "dependencies": { + "debug": "4.x" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/mquery/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -1026,6 +1619,60 @@ "node-gyp-build-test": "build-test.js" } }, + "node_modules/nodemon": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.7.tgz", + "integrity": "sha512-hLj7fuMow6f0lbB0cD14Lz2xNjwsyruH251Pk4t/yIitCFJbmY1myuLlHm/q06aST4jg6EgAh74PIBBrRqpVAQ==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", @@ -1065,6 +1712,18 @@ "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", "license": "MIT" }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -1078,6 +1737,20 @@ "node": ">= 0.10" } }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, "node_modules/qs": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", @@ -1117,6 +1790,18 @@ "node": ">= 0.8" } }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/regenerator-runtime": { "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", @@ -1202,6 +1887,18 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "license": "MIT" }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/send": { "version": "0.19.0", "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", @@ -1291,6 +1988,31 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/sift": { + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz", + "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==" + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "dependencies": { + "memory-pager": "^1.0.2" + } + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -1309,6 +2031,18 @@ "node": ">=14.0.0" } }, + "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==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/text-encoding-utf-8": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", @@ -1320,6 +2054,18 @@ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "license": "MIT" }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -1329,6 +2075,15 @@ "node": ">=0.6" } }, + "node_modules/touch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", + "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", + "dev": true, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -1367,6 +2122,12 @@ "node": ">=14.17" } }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", diff --git a/package.json b/package.json index f63f319..1b68299 100644 --- a/package.json +++ b/package.json @@ -3,17 +3,26 @@ "version": "1.0.0", "main": "index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "echo \"Error: no test specified\" && exit 1", + "dev": "nodemon", + "build": "tsc", + "start": "node dist/index.js" }, "keywords": [], "author": "", "license": "ISC", "description": "", "dependencies": { + "@solana/spl-token": "^0.4.9", "@solana/web3.js": "^1.95.4", "@types/express": "^5.0.0", + "bs58": "^6.0.0", "dotenv": "^16.4.5", "express": "^4.21.1", + "mongoose": "^8.8.1", "typescript": "^5.6.3" + }, + "devDependencies": { + "nodemon": "^3.1.7" } } diff --git a/src/WebhookEvent.ts b/src/WebhookEvent.ts new file mode 100644 index 0000000..3fbd118 --- /dev/null +++ b/src/WebhookEvent.ts @@ -0,0 +1,27 @@ +import mongoose from "mongoose"; + +export interface IWebhookEvent extends Document { + eventType: string; + rawData: any; + processed: boolean; + createdAt: Date; +} + +const webhookEventSchema = new mongoose.Schema({ + eventType: { + type: String, + required: true, + }, + rawData: { + type: Object, + required: true, + }, + processed: { + type: Boolean, + default: false, + } +}, { + timestamps: true, +}); + +export const WebhookEvent = mongoose.model("WebhookEvent", webhookEventSchema); \ No newline at end of file diff --git a/src/address.ts b/src/address.ts index 9739cfb..44d8da9 100644 --- a/src/address.ts +++ b/src/address.ts @@ -1,4 +1,91 @@ -export const PRIVATE_KEY = ""; -export const PUBLIC_KEY = ""; +import { PublicKey } from "@solana/web3.js"; + +export const PUBLIC_KEY = new PublicKey("CPkZyUB27wz923zkJVaUfxufCbGcXyuM9HEc43Z6wGvf"); + +export const ATA_ADDRESS = new PublicKey("8mSftUkCcRVL2ht2JvNRXMNo87Xk6tSMnokZvkT6ZfLH"); + +export const TOKEN_MINT_ADDRESS = new PublicKey("GRURykEQMekWogEF8gHoKEiHtVuafu4aS1UMkwWYAvi4"); + +export const HELIUS_DATA = { + "accountData": [ + { + "account": "FUv5jWF7VsYMBDup3cLPdVond4AVbA7kSE1GFRuYcK1N", + "nativeBalanceChange": -100015000, + "tokenBalanceChanges": [] + }, + { + "account": "CPkZyUB27wz923zkJVaUfxufCbGcXyuM9HEc43Z6wGvf", + "nativeBalanceChange": 100000000, + "tokenBalanceChanges": [] + }, + { + "account": "11111111111111111111111111111111", + "nativeBalanceChange": 0, + "tokenBalanceChanges": [] + }, + { + "account": "ComputeBudget111111111111111111111111111111", + "nativeBalanceChange": 0, + "tokenBalanceChanges": [] + } + ], + "description": "FUv5jWF7VsYMBDup3cLPdVond4AVbA7kSE1GFRuYcK1N transferred 0.1 SOL to CPkZyUB27wz923zkJVaUfxufCbGcXyuM9HEc43Z6wGvf.", + "events": {}, + "fee": 15000, + "feePayer": "FUv5jWF7VsYMBDup3cLPdVond4AVbA7kSE1GFRuYcK1N", + "instructions": [ + { + "accounts": [], + "data": "3DVGviTXKAPH", + "innerInstructions": [], + "programId": "ComputeBudget111111111111111111111111111111" + }, + { + "accounts": [], + "data": "LKoyXd", + "innerInstructions": [], + "programId": "ComputeBudget111111111111111111111111111111" + }, + { + "accounts": ["FUv5jWF7VsYMBDup3cLPdVond4AVbA7kSE1GFRuYcK1N", "CPkZyUB27wz923zkJVaUfxufCbGcXyuM9HEc43Z6wGvf"], + "data": "3Bxs411Dtc7pkFQj", + "innerInstructions": [], + "programId": "11111111111111111111111111111111" + } + ], + "nativeTransfers": [ + { + "amount": 1000000000, + "fromUserAccount": "FUv5jWF7VsYMBDup3cLPdVond4AVbA7kSE1GFRuYcK1N", + "toUserAccount": "CPkZyUB27wz923zkJVaUfxufCbGcXyuM9HEc43Z6wGvf" + } + ], + "signature": "QGAXXgZfA3PR1LCV3UdZtKkknkx1fqGfotuKG13agt4xSm5R5QAMWZGmDWDSKBLHFRPgRwNstF6QHGxpFYT7bZQ", + "slot": 338295968, + "source": "SYSTEM_PROGRAM", + "timestamp": 1730952341, + "tokenTransfers": [], + "transactionError": null, + "type": "TRANSFERi" +} +export const HELIUS_DATA_BURN ={ + "accountData":[{ + "account":"FUv5jWF7VsYMBDup3cLPdVond4AVbA7kSE1GFRuYcK1N", + "nativeBalanceChange":-14999, + "tokenBalanceChanges":[]}, + {"account":"8mSftUkCcRVL2ht2JvNRXMNo87Xk6tSMnokZvkT6ZfLH", + "nativeBalanceChange":0, + "tokenBalanceChanges":[{ + "mint":"GRURykEQMekWogEF8gHoKEiHtVuafu4aS1UMkwWYAvi4", + "rawTokenAmount":{"decimals":9,"tokenAmount":"500000000"}, + "tokenAccount":"8mSftUkCcRVL2ht2JvNRXMNo87Xk6tSMnokZvkT6ZfLH", + "userAccount":"CPkZyUB27wz923zkJVaUfxufCbGcXyuM9HEc43Z6wGvf"}]}, + {"account":"CoDdFra63FaL2Z6wjGAkrHaMVXSQCU43iPctZaGo6W8g", + "nativeBalanceChange":0, + "tokenBalanceChanges":[{ + "mint":"GRURykEQMekWogEF8gHoKEiHtVuafu4aS1UMkwWYAvi4", + "rawTokenAmount":{"decimals":9,"tokenAmount":"-500000000"}, + "tokenAccount":"CoDdFra63FaL2Z6wjGAkrHaMVXSQCU43iPctZaGo6W8g", + "userAccount":"FUv5jWF7VsYMBDup3cLPdVond4AVbA7kSE1GFRuYcK1N"}]}, + {"account":"ComputeBudget111111111111111111111111111111","nativeBalanceChange":0,"tokenBalanceChanges":[]},{"account":"GRURykEQMekWogEF8gHoKEiHtVuafu4aS1UMkwWYAvi4","nativeBalanceChange":0,"tokenBalanceChanges":[]},{"account":"TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb","nativeBalanceChange":0,"tokenBalanceChanges":[]}],"description":"","events":{},"fee":14999,"feePayer":"FUv5jWF7VsYMBDup3cLPdVond4AVbA7kSE1GFRuYcK1N","instructions":[{"accounts":[],"data":"3PXCWd4YE8jh","innerInstructions":[],"programId":"ComputeBudget111111111111111111111111111111"},{"accounts":[],"data":"JLEJN3","innerInstructions":[],"programId":"ComputeBudget111111111111111111111111111111"},{"accounts":["CoDdFra63FaL2Z6wjGAkrHaMVXSQCU43iPctZaGo6W8g","GRURykEQMekWogEF8gHoKEiHtVuafu4aS1UMkwWYAvi4","8mSftUkCcRVL2ht2JvNRXMNo87Xk6tSMnokZvkT6ZfLH","FUv5jWF7VsYMBDup3cLPdVond4AVbA7kSE1GFRuYcK1N","FUv5jWF7VsYMBDup3cLPdVond4AVbA7kSE1GFRuYcK1N"],"data":"g7Ez8CcPA4BjN","innerInstructions":[],"programId":"TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb"}],"nativeTransfers":[],"signature":"4FLShqPwCjLhyBcp9me6S1eQ4U6KYZmH5RPTUWtdBnCgtRFTtYGWvnnLBB4vvoNhe2Jk9MHciksv3iVnBBzTbd4z","slot":338384800,"source":"UNKNOWN","timestamp":1730986226,"tokenTransfers":[],"transactionError":null,"type":"UNKNOWN"} -export const TOKEN_MINT_ADDRESS = ""; \ No newline at end of file diff --git a/src/config/database.ts b/src/config/database.ts new file mode 100644 index 0000000..521f14b --- /dev/null +++ b/src/config/database.ts @@ -0,0 +1,14 @@ +import mongoose from "mongoose"; +import dotenv from "dotenv"; + +dotenv.config(); + +export const connectToDB = async () => { + try { + await mongoose.connect(process.env.MONGODB_URI as string); + console.log('Connected to MongoDB'); + } catch (error) { + console.log('Error connecting to MongoDB', error); + process.exit(1); + } +} \ No newline at end of file diff --git a/src/config/solana.ts b/src/config/solana.ts new file mode 100644 index 0000000..001bb42 --- /dev/null +++ b/src/config/solana.ts @@ -0,0 +1,7 @@ +import { Connection, Keypair } from "@solana/web3.js"; +import bs58 from "bs58"; +export const SOLANA_RPC_URL = "https://api.devnet.solana.com"; +export const connection = new Connection(SOLANA_RPC_URL); +export const payer = Keypair.fromSecretKey( + bs58.decode(process.env.SOLANA_PRIVATE_KEY!) + ); \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 641355f..f5bb237 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,27 +1,90 @@ -require('dotenv').config(); -import express from 'express'; -import { burnTokens, mintTokens, sendNativeTokens } from './mintTokens'; +require("dotenv").config(); +import express, { Request, Response } from "express"; +import { + burnTokensAndSendNativeTokens, + mintTokens, +} from "./mintTokens"; +import { HELIUS_DATA, PUBLIC_KEY, HELIUS_DATA_BURN } from "./address"; +import { PublicKey } from "@solana/web3.js"; +import { connectToDB } from "./config/database"; +import { WebhookEvent } from "./WebhookEvent"; -const app = express(); +const startServer = async () => { + const app = express(); + app.use(express.json()); + await connectToDB(); -app.post('/helius', async(req, res) => { - const fromAddress = req.body.fromAddress; - const toAddress = req.body.toAddress; - const amount = req.body.amount; - const type = "received_native_sol"; + app.post("/helius", async (req: Request, res: Response) => { + try { + const data = req.body?.[0]; + console.log({ eventType: data?.type }); + const webhookEvent = await WebhookEvent.create({ + eventType: data?.type, + rawData: data, + }); + processWebhook(data) + .then(() => { + webhookEvent.processed = true; + webhookEvent.save(); + console.log("Event Processed"); + }) + .catch((error) => { + console.log("failed to process event", error); + }); - if (type === "received_native_sol") { - await mintTokens(fromAddress, toAddress, amount); - } else { - // What could go wrong here? - await burnTokens(fromAddress, toAddress, amount); - await sendNativeTokens(fromAddress, toAddress, amount); + res.send("Event Captured"); + } catch (error) { + console.log(error); + res.status(500).send("Event Failed"); } + }); - res.send('Transaction successful'); -}); + const processWebhook = async (data: any) => { + try { + const type = "TRANSFER"; + let fromAddress = data?.nativeTransfers?.[0]?.fromUserAccount; + let toAddress = data?.nativeTransfers?.[0]?.toUserAccount; + let amount = data?.nativeTransfers?.[0]?.amount; -app.listen(3000, () => { - console.log('Server is running on port 3000'); -}); \ No newline at end of file + if (data?.type === type && toAddress === PUBLIC_KEY.toBase58()) { + fromAddress = data?.nativeTransfers?.[0]?.fromUserAccount; + amount = data?.nativeTransfers?.[0]?.amount; + await mintTokens(new PublicKey(fromAddress), Number(amount)); + } else { + let myAccountData = data?.accountData?.find( + (account: any) => + account.account === "8mSftUkCcRVL2ht2JvNRXMNo87Xk6tSMnokZvkT6ZfLH" + ); + console.log({ myAccountData }); + if (myAccountData) { + let senderAccount = data?.accountData?.find( + (account: any) => + account?.tokenBalanceChanges?.[0]?.rawTokenAmount?.tokenAmount === + "-" + + myAccountData?.tokenBalanceChanges?.[0]?.rawTokenAmount + ?.tokenAmount + ); + console.log(senderAccount); + if (senderAccount) { + let senderAddress = new PublicKey( + senderAccount.tokenBalanceChanges[0].userAccount + ); + let amount = Number( + myAccountData.tokenBalanceChanges[0].rawTokenAmount.tokenAmount + ); + await burnTokensAndSendNativeTokens(senderAddress, amount); + } + } + } + } catch (error) { + console.log(`Failed to process webhook:`, error); + } + }; + + app.listen(3000, () => { + console.log("Server is running on port 3000, hello"); + }); +}; + +startServer(); diff --git a/src/mintTokens.ts b/src/mintTokens.ts index 8e5a0eb..7bcf27b 100644 --- a/src/mintTokens.ts +++ b/src/mintTokens.ts @@ -1,12 +1,107 @@ +import { + createBurnInstruction, + getOrCreateAssociatedTokenAccount, + mintTo, + TOKEN_2022_PROGRAM_ID, +} from "@solana/spl-token"; +import { + PublicKey, + sendAndConfirmTransaction, + SystemProgram, + Transaction, +} from "@solana/web3.js"; +import { connection, payer } from "./config/solana"; +import { TOKEN_MINT_ADDRESS, PUBLIC_KEY, ATA_ADDRESS } from "./address"; +import { LstToSol, SolToLst } from "./util"; -export const mintTokens = async (fromAddress: string, toAddress: string, amount: number) => { - console.log("Minting tokens"); -} +const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); + + +const calculateAmountToMint = (amountInLamports: number) => { + console.log("Calculating amount to mint", amountInLamports); + const amountToMint = SolToLst(amountInLamports); + console.log("Amount to mint", amountToMint); + return amountToMint; +}; -export const burnTokens = async (fromAddress: string, toAddress: string, amount: number) => { - console.log("Burning tokens"); -} +const calculateNativeAmountToSend = (amountInLamports: number) => { + console.log("Calculating native amount to send", amountInLamports); + const amountToSend = LstToSol(amountInLamports); + console.log("Amount to send", amountToSend); + return amountToSend; +}; + +export const mintTokens = async ( + toAddress: PublicKey, + amountInLamports: number +) => { + try { + console.log("Minting tokens"); + const receiverAtaAddress = await getOrCreateAssociatedTokenAccount( + connection, + payer, + TOKEN_MINT_ADDRESS, + toAddress, + true, + "confirmed", + undefined, + TOKEN_2022_PROGRAM_ID + ); + let amountToMint = calculateAmountToMint(amountInLamports); + console.log("Amount to mint", amountToMint); + await mintTo( + connection, + payer, + TOKEN_MINT_ADDRESS, + receiverAtaAddress.address, + payer, + amountToMint, + [], + undefined, + TOKEN_2022_PROGRAM_ID + ); + console.log("Tokens minted"); + } catch (error) { + console.log("Error minting tokens", error); + throw new Error("Error minting tokens"); + } +}; -export const sendNativeTokens = async (fromAddress: string, toAddress: string, amount: number) => { - console.log("Sending native tokens"); -} \ No newline at end of file +export const burnTokensAndSendNativeTokens = async ( + userAddress: PublicKey, + amount: number +) => { + try { + // Combine burn and transfer in a single atomic transaction + console.log("Burning tokens and sending native tokens"); + await sleep(10000); + let amountOfNativeTokensToSend = calculateNativeAmountToSend(amount); + console.log("Amount of native tokens to send", amountOfNativeTokensToSend); + const transaction = new Transaction() + .add( + createBurnInstruction( + ATA_ADDRESS, + TOKEN_MINT_ADDRESS, + PUBLIC_KEY, + amount, + [], + TOKEN_2022_PROGRAM_ID + ) + ) + .add( + SystemProgram.transfer({ + fromPubkey: payer.publicKey, + toPubkey: userAddress, + lamports: amountOfNativeTokensToSend, + }) + ); + await sendAndConfirmTransaction(connection, transaction, [payer], { + skipPreflight: true, + commitment: "confirmed", + }); + console.log("Tokens burned and native tokens sent"); + } catch (error) { + console.log("Error burning tokens and sending native tokens", error); + throw new Error("Error burning tokens and sending native tokens"); + } +}; diff --git a/src/util.ts b/src/util.ts new file mode 100644 index 0000000..f332796 --- /dev/null +++ b/src/util.ts @@ -0,0 +1,25 @@ +function calculateConversionsWithMinuteRate() { + const growthRatePerMinute = 0.00019026 / 100; + const startTime = new Date('2024-11-09T10:16:17.891+00:00'); + const currentTime = new Date(); + + const elapsedMinutes = (currentTime.getTime() - startTime.getTime()) / (1000 * 60); + + + const growthFactor = Math.exp(growthRatePerMinute * elapsedMinutes); + + + function LstToSol(LstAmount: number) { + return Math.floor(LstAmount * growthFactor); + } + + function SolToLst(solAmount: number) { + return Math.floor(solAmount / growthFactor); + } + + return { LstToSol, SolToLst }; + } + + const { LstToSol, SolToLst } = calculateConversionsWithMinuteRate(); + + export { LstToSol, SolToLst }; \ No newline at end of file