diff --git a/near-social-ai-agent/.gitignore b/near-social-ai-agent/.gitignore new file mode 100644 index 0000000..62190d7 --- /dev/null +++ b/near-social-ai-agent/.gitignore @@ -0,0 +1,37 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts + +.env \ No newline at end of file diff --git a/near-social-ai-agent/README.md b/near-social-ai-agent/README.md new file mode 100644 index 0000000..319a0a7 --- /dev/null +++ b/near-social-ai-agent/README.md @@ -0,0 +1,85 @@ +# Near Social Node.js API for Bitte AI Plugin + +![Licenses](./public/images/near-social.png) + +## Introduction + +The Near Social Node.js API for the Bitte AI Plugin provides a comprehensive interface for users to interact with the Near Social platform. This API facilitates operations such as setting up user profiles and uploading posts, making it easier for users to engage with the Near Social community. With a focus on seamless integration and user experience, this API utilizes the power of AI to guide users through the process of managing their profiles and content. + +[![Demo](https://img.shields.io/badge/Demo-Visit%20Demo-brightgreen)](https://tinyurl.com/near-social-mintbase-ai-agent) +[![Deploy](https://img.shields.io/badge/Deploy-on%20Vercel-blue)](https://vercel.com/new/clone?repository-url=https://github.com/Teckas-Technologies/NearSocial-AI-Agent) + +**Tooling:** + +[![Use Case](https://img.shields.io/badge/Use%20Case-Make%20NearSocial%20Operations%20Easier-blue)](#) +[![Tools](https://img.shields.io/badge/Tools-near--api--js%2C%20big.js-blue)](#) +[![Framework](https://img.shields.io/badge/Framework-Node.js-blue)](#) + +**Author:** + +[![Author](https://img.shields.io/badge/Follow-Teckas%20Technologies-blue?style=social&logo=linkedin)](https://www.linkedin.com/company/teckas/) [![Organization](https://img.shields.io/badge/Teckas%20Technologies-blue)](https://teckastechnologies.com/) + +## Key Features + +- **Profile Management:** Users can set up their profiles on the Near Social platform by providing necessary details. +- **Post Creation:** Allows users to create posts with optional images, enhancing content sharing within the community. +- **Guided User Experience:** The AI assistant provides step-by-step guidance to ensure all information is collected accurately and effectively. + +## User Flow + +1. **Set Up Profile:** + - Users are prompted to provide the following profile details: + - `name` + - `about` + - `twitter` + - `github` + - `telegram` + - `website` + - `profileImage` + - `bannerImage` + - `tags` (e.g., rust, web, nft, engineer) + - Once details are collected, the API uploads the information to the `/api/profile` endpoint along with the user's account ID. + +2. **Create a Post:** + - Users can specify `content` for their post, with an option to upload an image. + - After preparing the content and optional image URL, the API uploads these details to the `/api/post` endpoint along with the user's account ID. + +3. **Receive Confirmation:** + - After successful uploads, the API provides URLs for signing the transactions, which users can use to finalize their profile setup and post creation. + +## Conclusion + +The Near Social Node.js API for the Bitte AI Plugin simplifies interactions with the Near Social platform, enhancing the user experience by leveraging AI technology for profile management and content creation. By providing a guided interface, this API ensures that users can easily navigate the process of establishing their online presence within the Near community. + +## Step By Step + +To get started with the Near Social AI Agent, follow these steps: + +1. **Clone repository** +```bash +git clone https://github.com/Teckas-Technologies/NearSocial-AI-Agent +cd NearSocial-AI-Agent +``` +2. **Install dependencies** +```bash +npm install +npm run start +``` + +## Usage + + In this template, we used the `near-api-js` for fetch the required information from the near social contract. + +## Contracts +```bash +const NEAR_SOCIAL_DB_CONTRACT_ID = 'social.near'; +``` + +## Deployment +Follow these steps to deploy the Near Social AI Agent on Vercel: +- Create an Account: Sign up for an account on Vercel. +- Connect GitHub: Connect your GitHub account with Vercel. +- Import Repository: Import the GitHub repository of the project. +- Add Environment Variables: While configuring the project, add the necessary environment variables. +- Deploy: Click the deploy button. +- Access Application: Once the deployment is complete, you can access your application. diff --git a/near-social-ai-agent/app.js b/near-social-ai-agent/app.js new file mode 100644 index 0000000..9b522b7 --- /dev/null +++ b/near-social-ai-agent/app.js @@ -0,0 +1,25 @@ +const express = require('express'); +const bodyParser = require('body-parser'); +const path = require('path'); +require('dotenv').config(); + +const app = express(); +app.use(bodyParser.json()); +app.use('public', express.static(path.join(__dirname, 'public'))); + +const profileRouter = require('./routes/profile'); +const postRouter = require('./routes/post'); +const followRouter = require('./routes/follow'); + +app.use('/api/profile', profileRouter); +app.use('/api/post', postRouter); +app.use('/api/follow', followRouter); +app.get("/", (req, res) => res.send("Express on Azure New")); +app.get('/.well-known/ai-plugin.json', (req, res) => { + res.setHeader('Content-Type', 'application/json'); + res.sendFile(path.join(__dirname, 'public/.well-known/ai-plugin.json')); +}); + +app.listen(8080, () => { + console.log("AI Agent Running on port : 8080") +}) \ No newline at end of file diff --git a/near-social-ai-agent/package-lock.json b/near-social-ai-agent/package-lock.json new file mode 100644 index 0000000..26a0688 --- /dev/null +++ b/near-social-ai-agent/package-lock.json @@ -0,0 +1,1769 @@ +{ + "name": "mintbase-ai-agent", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "mintbase-ai-agent", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "axios": "^1.7.7", + "big.js": "^6.2.2", + "dotenv": "^16.4.5", + "express": "^4.21.0", + "form-data": "^4.0.0", + "near-api-js": "^5.0.0", + "node-fetch": "^3.3.2" + }, + "devDependencies": { + "nodemon": "^3.1.4" + } + }, + "node_modules/@near-js/accounts": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@near-js/accounts/-/accounts-1.3.0.tgz", + "integrity": "sha512-syUgc7EanfN2sX2UJsmJIcZ6OuQ5Ilr/GoVSD8MVOV7B5dT1HZSkMuIBdu+pKfmBbG3EGUOoT8Txxs8Nx96gGA==", + "dependencies": { + "@near-js/crypto": "1.4.0", + "@near-js/providers": "1.0.0", + "@near-js/signers": "0.2.0", + "@near-js/transactions": "1.3.0", + "@near-js/types": "0.3.0", + "@near-js/utils": "1.0.0", + "@noble/hashes": "1.3.3", + "borsh": "1.0.0", + "depd": "2.0.0", + "is-my-json-valid": "^2.20.6", + "isomorphic-unfetch": "^3.1.0", + "lru_map": "0.4.1", + "near-abi": "0.1.1" + } + }, + "node_modules/@near-js/crypto": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@near-js/crypto/-/crypto-1.4.0.tgz", + "integrity": "sha512-2SYS7LyFz2/y8idqAyyS4jf3pn6zFg4tLbOq9OlB+MTZhvsnUcWW+HLznyBytp6dW8lAQ03E+Ew0bYfJSCIJJw==", + "dependencies": { + "@near-js/types": "0.3.0", + "@near-js/utils": "1.0.0", + "@noble/curves": "1.2.0", + "borsh": "1.0.0", + "randombytes": "2.1.0", + "secp256k1": "5.0.0" + } + }, + "node_modules/@near-js/keystores": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@near-js/keystores/-/keystores-0.2.0.tgz", + "integrity": "sha512-vZiyx9whLlA7/EDdkZGf//0AL2FWAUyGpVhWIHcbJZwQ7DNcjpkb0tRydFp8Yk4bb7kcYnoyksSeRx9kQUMyjA==", + "dependencies": { + "@near-js/crypto": "1.4.0", + "@near-js/types": "0.3.0" + } + }, + "node_modules/@near-js/keystores-browser": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@near-js/keystores-browser/-/keystores-browser-0.2.0.tgz", + "integrity": "sha512-vR6XY5ztAzXwNqEipfkwfG6M8PiNNgdDAdogTQBm0FKQUegMsxbMN6x4UyTd1v0oQAzuRmYGwTLmTxQyzH1FQA==", + "dependencies": { + "@near-js/crypto": "1.4.0", + "@near-js/keystores": "0.2.0" + } + }, + "node_modules/@near-js/keystores-node": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@near-js/keystores-node/-/keystores-node-0.1.0.tgz", + "integrity": "sha512-SOtwrXWwGRbYqqu6TOO3jcCDkzSw+UG+SWVh5VbeTgHIzqR1CI4r4qhyXuTWZPyewJPDogO1ggepQi9NhfkJmA==", + "dependencies": { + "@near-js/crypto": "1.4.0", + "@near-js/keystores": "0.2.0" + } + }, + "node_modules/@near-js/providers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@near-js/providers/-/providers-1.0.0.tgz", + "integrity": "sha512-1++g0tVuHQWewkdmom3Iz5BSVT+KHgG7TX5YHywecg4uGLGhaf5oX1EPCXf/CYnTV61FjaNGIrIMNgwbGzacpw==", + "dependencies": { + "@near-js/transactions": "1.3.0", + "@near-js/types": "0.3.0", + "@near-js/utils": "1.0.0", + "borsh": "1.0.0", + "exponential-backoff": "^3.1.1", + "isomorphic-unfetch": "^3.1.0" + }, + "optionalDependencies": { + "node-fetch": "2.6.7" + } + }, + "node_modules/@near-js/providers/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "optional": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/@near-js/signers": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@near-js/signers/-/signers-0.2.0.tgz", + "integrity": "sha512-plzTnjI7IodTtMwGe2m1bg1ZwGeHeKanJqVoXFypZj7gOuuqVOi+9vcHdSu7T2McnzRujPQbj31PmfDQ3O3YCw==", + "dependencies": { + "@near-js/crypto": "1.4.0", + "@near-js/keystores": "0.2.0", + "@noble/hashes": "1.3.3" + } + }, + "node_modules/@near-js/transactions": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@near-js/transactions/-/transactions-1.3.0.tgz", + "integrity": "sha512-M9DuFX009E5twEbPV9Fs67nNu8T8segE7yG57q02MmPMOQ7RDanHA2fKqARsltTZ26EEXb92x3lAKt7qFdCfCw==", + "dependencies": { + "@near-js/crypto": "1.4.0", + "@near-js/signers": "0.2.0", + "@near-js/types": "0.3.0", + "@near-js/utils": "1.0.0", + "@noble/hashes": "1.3.3", + "borsh": "1.0.0" + } + }, + "node_modules/@near-js/types": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@near-js/types/-/types-0.3.0.tgz", + "integrity": "sha512-IwayA5Wa4+hryo22AuAYIu5a/nOAheF/Bmz9kpuouX9L4he+Tc8xAt5NfE60zXG7tsukAw1QAaHE1kBzhmwtKw==" + }, + "node_modules/@near-js/utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@near-js/utils/-/utils-1.0.0.tgz", + "integrity": "sha512-4dd6fDgWZnG+0VSKPBA3czEQdi9UotepdwcEKLTbXepIL1FX2ZlQV6HVi7KYmrAVwv1ims11vGnWzJWKy46ULw==", + "dependencies": { + "@near-js/types": "0.3.0", + "bs58": "4.0.0", + "depd": "2.0.0", + "mustache": "4.0.0" + } + }, + "node_modules/@near-js/wallet-account": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@near-js/wallet-account/-/wallet-account-1.3.0.tgz", + "integrity": "sha512-5gqwLXZsGkDMnEIZU7HnJEFol7ICno7wCnwGXHl7VhjBzve5OfaRt/IQpQitogoAUlonpQYmOi2r5qu76nj1lw==", + "dependencies": { + "@near-js/accounts": "1.3.0", + "@near-js/crypto": "1.4.0", + "@near-js/keystores": "0.2.0", + "@near-js/providers": "1.0.0", + "@near-js/signers": "0.2.0", + "@near-js/transactions": "1.3.0", + "@near-js/types": "0.3.0", + "@near-js/utils": "1.0.0", + "borsh": "1.0.0" + } + }, + "node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "dependencies": { + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/curves/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/@noble/hashes": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", + "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + }, + "node_modules/accepts": { + "version": "1.3.8", + "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", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "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==" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/axios": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "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": "2.0.6", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-2.0.6.tgz", + "integrity": "sha512-UAmjxz9KbK+YIi66xej+pZVo/vxUOh49ubEvZW5egCbxhur05pBb+hwuireQwKO4nDpsNm64/jEei17LEpsr5g==", + "deprecated": "use 3.0.0 instead, safe-buffer has been merged and release for compatability", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": ">=4.5.0" + } + }, + "node_modules/big.js": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-6.2.2.tgz", + "integrity": "sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==", + "engines": { + "node": "*" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/bigjs" + } + }, + "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/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/body-parser": { + "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==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/borsh": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/borsh/-/borsh-1.0.0.tgz", + "integrity": "sha512-fSVWzzemnyfF89EPwlUNsrS5swF5CrtiN4e+h0/lLf4dz2he4L3ndM20PS9wj7ICSkXJe/TQUHdaPTq15b1mNQ==" + }, + "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/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, + "node_modules/bs58": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.0.tgz", + "integrity": "sha512-/jcGuUuSebyxwLLfKrbKnCJttxRf9PM51EnHTwmFKBxl4z1SGkoAhrfd6uZKE0dcjQTfm6XzTP8DPr1tzE4KIw==", + "dependencies": { + "base-x": "^2.0.1" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "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", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/elliptic": { + "version": "6.5.7", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.7.tgz", + "integrity": "sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==", + "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" + } + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", + "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==" + }, + "node_modules/express": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", + "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.6.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.10", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "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", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "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" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "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", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "dependencies": { + "is-property": "^1.0.2" + } + }, + "node_modules/generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha512-TuOwZWgJ2VAMEGJvAyPWvpqxSANF0LDpmyHauMjFYzaACvn+QTT/AZomvPCzVBV7yDN3OmwHQ5OvHaeLKre3JQ==", + "dependencies": { + "is-property": "^1.0.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "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", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "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", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "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-my-ip-valid": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.1.tgz", + "integrity": "sha512-jxc8cBcOWbNK2i2aTkCZP6i7wkHF1bqKFrwEHuN5Jtg5BSaZHUZQ/JTOJwoV41YvHnOaRyWWh72T/KvfNz9DJg==" + }, + "node_modules/is-my-json-valid": { + "version": "2.20.6", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.6.tgz", + "integrity": "sha512-1JQwulVNjx8UqkPE/bqDaxtH4PXCe/2VRh/y3p99heOV87HG4Id5/VfDswd+YiAfHcRTfDlWgISycnHuhZq1aw==", + "dependencies": { + "generate-function": "^2.0.0", + "generate-object-property": "^1.1.0", + "is-my-ip-valid": "^1.0.0", + "jsonpointer": "^5.0.0", + "xtend": "^4.0.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/is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==" + }, + "node_modules/isomorphic-unfetch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/isomorphic-unfetch/-/isomorphic-unfetch-3.1.0.tgz", + "integrity": "sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==", + "dependencies": { + "node-fetch": "^2.6.1", + "unfetch": "^4.2.0" + } + }, + "node_modules/isomorphic-unfetch/node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru_map": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.4.1.tgz", + "integrity": "sha512-I+lBvqMMFfqaV8CJCISjI3wbjmwVu/VyOoU7+qtu9d7ioW5klMgsTTiUOUp+DJvfTTzKXoPbyC6YfgkNcyPSOg==" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "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" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, + "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/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/mustache": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.0.0.tgz", + "integrity": "sha512-FJgjyX/IVkbXBXYUwH+OYwQKqWpFPLaLVESd70yHjSDunwzV2hZOoTBvPf4KLoxesUzzyfTH6F784Uqd7Wm5yA==", + "bin": { + "mustache": "bin/mustache" + }, + "engines": { + "npm": ">=1.4.0" + } + }, + "node_modules/near-abi": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/near-abi/-/near-abi-0.1.1.tgz", + "integrity": "sha512-RVDI8O+KVxRpC3KycJ1bpfVj9Zv+xvq9PlW1yIFl46GhrnLw83/72HqHGjGDjQ8DtltkcpSjY9X3YIGZ+1QyzQ==", + "dependencies": { + "@types/json-schema": "^7.0.11" + } + }, + "node_modules/near-api-js": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/near-api-js/-/near-api-js-5.0.0.tgz", + "integrity": "sha512-JQBWG2TGSNx4EJKFtsz2lhadFYtZofyJjwigIqlKjBXQluG5DepM5ZdPJSTZ3R526OoqOcGq7MeZMYlW+hn2nw==", + "dependencies": { + "@near-js/accounts": "1.3.0", + "@near-js/crypto": "1.4.0", + "@near-js/keystores": "0.2.0", + "@near-js/keystores-browser": "0.2.0", + "@near-js/keystores-node": "0.1.0", + "@near-js/providers": "1.0.0", + "@near-js/signers": "0.2.0", + "@near-js/transactions": "1.3.0", + "@near-js/types": "0.3.0", + "@near-js/utils": "1.0.0", + "@near-js/wallet-account": "1.3.0", + "@noble/curves": "1.2.0", + "borsh": "1.0.0", + "depd": "2.0.0", + "http-errors": "1.7.2", + "near-abi": "0.1.1", + "node-fetch": "2.6.7" + } + }, + "node_modules/near-api-js/node_modules/http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/near-api-js/node_modules/http-errors/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/near-api-js/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + }, + "node_modules/near-api-js/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/near-api-js/node_modules/setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "node_modules/near-api-js/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/near-api-js/node_modules/toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", + "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/nodemon": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.4.tgz", + "integrity": "sha512-wjPBbFhtpJwmIeY2yP7QF+UKzPfltVGtfce1g/bB15/8vCGZj8uxD62b/b9M9/WVgme0NZudpownKN+c0plXlQ==", + "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/nodemon/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==", + "dev": 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", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "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" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==" + }, + "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", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "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/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "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/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "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/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/secp256k1": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-5.0.0.tgz", + "integrity": "sha512-TKWX8xvoGHrxVdqbYeZM9w+izTF4b9z3NhSaDkdn81btvuh+ivbIMGT/zQvDtTFWhRlThpoz6LEYTr7n8A5GcA==", + "hasInstallScript": true, + "dependencies": { + "elliptic": "^6.5.4", + "node-addon-api": "^5.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "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", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/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/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "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/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", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "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", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "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/unfetch": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz", + "integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + } + } +} diff --git a/near-social-ai-agent/package.json b/near-social-ai-agent/package.json new file mode 100644 index 0000000..3e5c7f8 --- /dev/null +++ b/near-social-ai-agent/package.json @@ -0,0 +1,23 @@ +{ + "name": "mintbase-ai-agent", + "version": "1.0.0", + "description": "AI agent for bitte wallet operations become easier", + "main": "app.js", + "scripts": { + "start": "node app.js" + }, + "author": "Teckas Technologies", + "license": "ISC", + "dependencies": { + "axios": "^1.7.7", + "big.js": "^6.2.2", + "dotenv": "^16.4.5", + "express": "^4.21.0", + "form-data": "^4.0.0", + "near-api-js": "^5.0.0", + "node-fetch": "^3.3.2" + }, + "devDependencies": { + "nodemon": "^3.1.4" + } +} diff --git a/near-social-ai-agent/public/.well-known/ai-plugin.json b/near-social-ai-agent/public/.well-known/ai-plugin.json new file mode 100644 index 0000000..2a0fb07 --- /dev/null +++ b/near-social-ai-agent/public/.well-known/ai-plugin.json @@ -0,0 +1,238 @@ +{ + "openapi": "3.0.0", + "info": { + "title": "Profile Setting API Testnet", + "description": "API for interacting with API operations including set the user profile.", + "version": "1.0.0" + }, + "servers": [ + { + "url": "https://nearsocialaiagent-eudccfeugga5fbe0.eastus-01.azurewebsites.net" + } + ], + "x-mb": { + "account-Id": "golden_comet.near", + "assistant": { + "name": "Profile Setting Assistant Testnet", + "description": "Assistant for helping users to setup their profile on Near Social platform and upload a post on Near Social platform. You will guIde the user through collecting profile details and get a signing URL from the API response. Finally display the profileUrl to the user.", + "instructions": "You are an assistant for help users to set their profile on Near Social platform using uploadProfile tool, and also upload a post on Near Social platform using createPost tool. For setup profile: First, ask the user to provide a profile details for setting profile on Near Social platform. The profile details are name, about, twitter, github, telegram, website, profileImage, bannerImage, and tags (such as rust, web, nft, engineer). Once the profile details are collected, upload the collected details to the uploadProfile tool along with the accountId (the user's account Id). After getting the success API response, display the sign URL {_profileUrl} for the user to set their profile on near social platform. (replace {_profileUrl} with the profileUrl from the API response). GuIde the user throughout the process to ensure all information is provided correctly and the sign URL is generated successfully. Note: You will ensure the collected profile details are sent properly to the /api/profile endpoint along with the accountId of the user. For upload a post: First, ask the user to provIde a content for the post or ask the topic, which you need to generate content in 50 words. After content is ready, if user wants to upload post with image, collect the imageUrl (optional). Once content is ready, and imageUrl (optional) also ready, upload the content and imageUrl to createPost tool along with the accountId (the user's account Id). After getting the success API response, display the post URL {_postUrl} for the user to upload a post on near social platform. (replace {_postUrl} with the postUrl from the API response). GuIde the user throughout the process to ensure all information is provIded correctly and the post URL is generated successfully. Note: You will ensure the collected content details and imageUrl are sent properly to the /api/post endpoint along with the accountId of the user." + }, + "tools": [ + { + "type": "generate-image" + } + ] + }, + "paths": { + "/api/profile": { + "post": { + "summary": "Upload profile details", + "description": "Uploads collected profile details along with user's accountId", + "operationId": "uploadProfile", + "requestBody": { + "description": "Profile setup request body", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "accountId": { + "type": "string", + "description": "User's account Id." + }, + "name": { + "type": "string", + "description": "Name of the user." + }, + "about": { + "type": "string", + "description": "Brief description about the user." + }, + "twitter": { + "type": "string", + "description": "Twitter Id of the user." + }, + "github": { + "type": "string", + "description": "Github Id of the user." + }, + "telegram": { + "type": "string", + "description": "Telegram Id of the user." + }, + "website": { + "type": "string", + "description": "Personal website link of the user." + }, + "tags": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Tags relevant to the user." + }, + "profileImage": { + "type": "string", + "description": "The URL of the profile image." + }, + "bannerImage": { + "type": "string", + "description": "The URL of the banner image." + } + }, + "required": [ + "accountId", + "name", + "about", + "twitter", + "github", + "telegram", + "website", + "tags", + "profileImage", + "bannerImage" + ] + } + } + } + }, + "responses": { + "200": { + "description": "Profile data uploaded successfully.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "profileUrl": { + "type": "string", + "description": "URL for the user to sign the transaction." + } + } + } + } + } + } + } + }, + "get": { + "summary": "Get social profile by account ID", + "description": "Fetches a user's social profile by their account Id.", + "operationId": "getProfile", + "parameters": [ + { + "in": "query", + "name": "id", + "schema": { + "type": "string" + }, + "description": "The account Id to fetch a logged in user's profile." + } + ], + "responses": { + "200": { + "description": "Profile retrieved successfully.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "profile": { + "type": "object", + "description": "The social profile data of the user." + } + } + } + } + } + }, + "400": { + "description": "Account ID is missing.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string" + } + } + } + } + } + }, + "500": { + "description": "Internal Server Error.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/api/post": { + "post": { + "summary": "Create a post", + "description": "Allows users to post content with their accountId", + "operationId": "createPost", + "requestBody": { + "description": "Post request body", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "accountId": { + "type": "string", + "description": "User's account Id" + }, + "content": { + "type": "string", + "description": "Content of the post" + }, + "imageUrl": { + "type": "string", + "description": "The URL of the post image." + } + }, + "required": [ + "accountId", + "content" + ] + } + } + } + }, + "responses": { + "200": { + "description": "Post created successfully.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "postUrl": { + "type": "string", + "description": "URL for the user to sign the transaction for creating the post." + } + } + } + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/near-social-ai-agent/public/images/near-social.png b/near-social-ai-agent/public/images/near-social.png new file mode 100644 index 0000000..2d626b5 Binary files /dev/null and b/near-social-ai-agent/public/images/near-social.png differ diff --git a/near-social-ai-agent/routes/follow.js b/near-social-ai-agent/routes/follow.js new file mode 100644 index 0000000..63e52aa --- /dev/null +++ b/near-social-ai-agent/routes/follow.js @@ -0,0 +1,106 @@ +const express = require('express'); +const router = express.Router(); +const { format } = require('near-api-js').utils; +const { SOCIAL_DB_CONTRACT_ID } = require('../utils/constant'); +const { getAvailableStorage} = require('../utils/nearSocialUtils'); +const { StorageCostPerByte, estimateDataSize, calculateNearAmount } = require('../utils/utils'); +const Big = require('big.js'); + +const MinStorageBalance = StorageCostPerByte.mul(2000); +const InitialAccountStorageBalance = StorageCostPerByte.mul(500); +const ExtraStorageBalance = StorageCostPerByte.mul(500); +const StorageForPermission = StorageCostPerByte.mul(500); +const CustomStorage = StorageCostPerByte.mul(500); + +router.post("/", async (req, res) => { + try { + const body = req.body; + console.log("body >>", body); + + const { accountId, accountID, recipientId } = body; + const account = accountId || accountID; + if (!account || !recipientId) { + console.log("Missing accountId or recipientId"); + return res.status(400).json({ error: "Missing accountId or recipientId" }); + } + + const data = { + graph: { follow: { [recipientId] : "" } }, + index: { + graph: JSON.stringify({ + key: "follow", + value: { + type: "follow", + accountId: recipientId, + }, + }), + notify: JSON.stringify({ + key: recipientId, + value: { + type: "follow", + }, + }), + }, + }; + + const storage = await getAvailableStorage(account); + const availableBytes = Big(storage?.available_bytes || '0'); + + let currentData = {}; + + const expectedDataBalance = StorageCostPerByte?.mul( + estimateDataSize(data, currentData) + ) + .add(storage ? Big(0) : InitialAccountStorageBalance) + .add(true ? Big(0) : StorageForPermission) + .add(ExtraStorageBalance) + .add(CustomStorage); + + const totalSize = (expectedDataBalance?.toFixed() * 100000 / 10 ** 24).toFixed() + + let amount = 0; + if (totalSize > availableBytes) { + // Calculate NEAR amount if the total size exceeds the available storage + const extraSize = totalSize - availableBytes; + amount = calculateNearAmount(extraSize); + } + console.log(`amt:${amount},size:${totalSize},availBytes:${availableBytes},data:${JSON.stringify(data)},`); + + const contractId = SOCIAL_DB_CONTRACT_ID; + const method = 'set'; + const args = { + [account]: data, + }; + const gas = '300000000000000'; + const deposit = format.parseNearAmount(amount.toString()); + + const transactionData = [{ + receiverId: contractId, + actions: [{ + type: 'FunctionCall', + params: { + methodName: method, + args: args, + gas: gas, + deposit: deposit + } + }] + }]; + + const transactionsData = encodeURIComponent(JSON.stringify(transactionData)); + const callbackUrl = encodeURIComponent(`https://near.social/mob.near/widget/ProfilePage?accountId=${recipientId}`); + + console.log("Transaction Data: ", transactionData); + console.log("Callback URL: ", callbackUrl); + + const followUrl = `https://wallet.bitte.ai/sign-transaction?transactions_data=${transactionsData}&callback_url=${callbackUrl}`; + console.log("Post Url: ", decodeURIComponent(followUrl)); + res.json({ followUrl: followUrl }); + + } catch (error) { + console.error("Error >> ", error); + return res.status(500).json({ error: 'An error occurred while generating the post URL.' }); + } +}); + +module.exports = router; \ No newline at end of file diff --git a/near-social-ai-agent/routes/post.js b/near-social-ai-agent/routes/post.js new file mode 100644 index 0000000..aacb90d --- /dev/null +++ b/near-social-ai-agent/routes/post.js @@ -0,0 +1,120 @@ +const express = require('express'); +const router = express.Router(); +const { format } = require('near-api-js').utils; +const { uploadIPFS } = require('../utils/imageUtils'); +const { SOCIAL_DB_CONTRACT_ID } = require('../utils/constant'); +const { getAvailableStorage} = require('../utils/nearSocialUtils'); +const { StorageCostPerByte, estimateDataSize, calculateNearAmount } = require('../utils/utils'); +const Big = require('big.js'); + +const MinStorageBalance = StorageCostPerByte.mul(2000); +const InitialAccountStorageBalance = StorageCostPerByte.mul(500); +const ExtraStorageBalance = StorageCostPerByte.mul(500); +const StorageForPermission = StorageCostPerByte.mul(500); +const CustomStorage = StorageCostPerByte.mul(500); + +router.post("/", async (req, res) => { + try { + const body = req.body; + console.log("body >>", body); + + const { accountId, accountID, content, imageUrl } = body; + const account = accountId || accountID; + if (!account || !content) { + console.log("Missing accountId or content"); + return res.status(400).json({ error: "Missing accountId or content" }); + } + + let imageCid; + + // if (imageUrl) { + // imageCid = await uploadIPFS(imageUrl); + // } + + const postData = { + main: {} + }; + + // if (imageUrl) postData.main.image = { ipfs_cid: imageCid }; + if (content) { + postData.main.type = "md"; + postData.main.text = content; + } + + const data = { + [account]: { + post: { + main: JSON.stringify(postData.main) + }, + index: { + post: JSON.stringify({ + key: "main", + value: { + type: "md" + } + }) + } + }, + }; + + const storage = await getAvailableStorage(account); + const availableBytes = Big(storage?.available_bytes || '0'); + + let currentData = {}; + + const expectedDataBalance = StorageCostPerByte?.mul( + estimateDataSize(data, currentData) + ) + .add(storage ? Big(0) : InitialAccountStorageBalance) + .add(true ? Big(0) : StorageForPermission) + .add(ExtraStorageBalance) + .add(CustomStorage); + + const totalSize = (expectedDataBalance?.toFixed() * 100000 / 10 ** 24).toFixed() + + let amount = 0; + if (totalSize > availableBytes) { + // Calculate NEAR amount if the total size exceeds the available storage + const extraSize = totalSize - availableBytes; + amount = calculateNearAmount(extraSize); + } + console.log(`amt:${amount},size:${totalSize},availBytes:${availableBytes},data:${JSON.stringify(data)},`); + + const contractId = SOCIAL_DB_CONTRACT_ID; + const method = 'set'; + const args = { + data: data + }; + const gas = '300000000000000'; + const deposit = format.parseNearAmount(amount.toString()); + + const transactionData = [{ + receiverId: contractId, + actions: [{ + type: 'FunctionCall', + params: { + methodName: method, + args: args, + gas: gas, + deposit: deposit + } + }] + }]; + + const transactionsData = encodeURIComponent(JSON.stringify(transactionData)); + const callbackUrl = encodeURIComponent(`https://near.social/mob.near/widget/ProfilePage?accountId=${account}`); + + console.log("Transaction Data: ", transactionData); + console.log("Callback URL: ", callbackUrl); + + const postUrl = `https://wallet.bitte.ai/sign-transaction?transactions_data=${transactionsData}&callback_url=${callbackUrl}`; + console.log("Post Url: ", decodeURIComponent(postUrl)); + res.json({ postUrl: postUrl }); + + } catch (error) { + console.error("Error >> ", error); + return res.status(500).json({ error: 'An error occurred while generating the post URL.' }); + } +}); + +module.exports = router; \ No newline at end of file diff --git a/near-social-ai-agent/routes/profile.js b/near-social-ai-agent/routes/profile.js new file mode 100644 index 0000000..e166bc3 --- /dev/null +++ b/near-social-ai-agent/routes/profile.js @@ -0,0 +1,146 @@ +const express = require('express'); +const router = express.Router(); +const { format } = require('near-api-js').utils; +const { SOCIAL_DB_CONTRACT_ID } = require('../utils/constant'); +const { getSocialProfile, getAvailableStorage} = require('../utils/nearSocialUtils'); +const { estimateDataSize, convertToStringLeaves, StorageCostPerByte, bigMax, fetchCurrentData, removeDuplicates, calculateNearAmount } = require('../utils/utils'); +const Big = require('big.js'); + +const MinStorageBalance = StorageCostPerByte.mul(2000); +const InitialAccountStorageBalance = StorageCostPerByte.mul(500); +const ExtraStorageBalance = StorageCostPerByte.mul(500); +const StorageForPermission = StorageCostPerByte.mul(500); +const CustomStorage = StorageCostPerByte.mul(500); + +router.get("/", async (req, res) => { + try { + const accountId = req.query.id; + if (!accountId) { + return res.status(400).json({ error: 'Account Id not present!' }); + } + const profile = await getSocialProfile(accountId); + return res.status(200).json({ profile: profile }); + } catch (error) { + console.error("Error >> ", error); + return res.status(500).json({ error: 'Internal Server Error' }); + } +}); + +router.post("/", async (req, res) => { + try { + const body = req.body; + console.log("body >>", body); + + + const { accountId, accountID, name, about, profileImage, bannerImage, twitter, github, telegram, website, tags } = body; + + const account = accountId || accountID; + + if (!account || !name || !about || !tags || !profileImage || !bannerImage || !twitter || !github || !telegram || !website) { + console.log("Missing details"); + // return res.status(400).json({ error: 'Missing details' }); + } + + if (tags && !Array.isArray(tags)) { + console.log("Missing tag format"); + return res.status(400).json({ error: 'Tags should be an array' }); + } + + let formattedTags; + + if (tags && Array.isArray(tags)) { + formattedTags = tags.reduce((acc, tag) => { + acc[tag] = ""; + return acc; + }, {}); + } + + const profileData = {}; + if (name) profileData.name = name; + if (about) profileData.description = about; + if (profileImage) profileData.image = { url: profileImage }; + if (bannerImage) profileData.backgroundImage = { url: bannerImage }; + + const linktree = {}; + if (twitter) linktree.twitter = twitter; + if (github) linktree.github = github; + if (telegram) linktree.telegram = telegram; + if (website) linktree.website = website; + + if (Object.keys(linktree)?.length > 0) profileData.linktree = linktree; + if (tags?.length > 0) profileData.tags = formattedTags; + + const data = { + [account]: convertToStringLeaves({ + profile: profileData + }) + }; + + const storage = await getAvailableStorage(account); + const availableBytes = Big(storage?.available_bytes || '0'); + + let currentData = {}; + // if (availableBytes < 0) { + // console.log("Entered!!!!!") + // currentData = await fetchCurrentData(data); + // data = removeDuplicates(data, currentData); + // } + + const expectedDataBalance = StorageCostPerByte?.mul( + estimateDataSize(data, currentData) + ) + .add(storage ? Big(0) : InitialAccountStorageBalance) + .add(true ? Big(0) : StorageForPermission) + .add(ExtraStorageBalance) + .add(CustomStorage); + const depositNew = bigMax( + expectedDataBalance.sub(availableBytes?.mul(StorageCostPerByte)), + !storage ? MinStorageBalance : true ? Big(0) : Big(1) + ); + + const dataSize = (expectedDataBalance?.toFixed() * 100000 / 10 ** 24).toFixed() + + let amount = 0; + if (dataSize > availableBytes) { + const extraSize = dataSize - availableBytes; + console.log("Extra Size >> ", extraSize); + amount = calculateNearAmount(extraSize); + } + console.log(`amt:${amount},size:${dataSize},availBytes:${availableBytes},data:${JSON.stringify(data)},`); + + const contractId = SOCIAL_DB_CONTRACT_ID; + const method = 'set'; + const args = { data: data }; + const gas = '30000000000000'; + const deposit = format.parseNearAmount(amount.toString()); + + const transactionData = [{ + receiverId: contractId, + actions: [{ + type: 'FunctionCall', + params: { + methodName: method, + args: args, + gas: gas, + deposit: deposit + } + }] + }]; + + const transactionsData = encodeURIComponent(JSON.stringify(transactionData)); + const callbackUrl = encodeURIComponent(`https://near.social/mob.near/widget/ProfilePage?accountId=${account}`); + console.log("Transaction Data: ", transactionData); + console.log("Callback URL: ", callbackUrl); + + const signUrl = `https://wallet.bitte.ai/sign-transaction?transactions_data=${transactionsData}&callback_url=${callbackUrl}`; + console.log("Sign Url: ", decodeURIComponent(signUrl)); + + return res.status(200).json({ profileUrl: signUrl }); + + } catch (error) { + console.error("Error >> ", error); + return res.status(500).json({ error: 'Internal Server Error' }); + } +}); + +module.exports = router; \ No newline at end of file diff --git a/near-social-ai-agent/utils/constant.js b/near-social-ai-agent/utils/constant.js new file mode 100644 index 0000000..2844489 --- /dev/null +++ b/near-social-ai-agent/utils/constant.js @@ -0,0 +1,4 @@ +const SOCIAL_DB_CONTRACT_ID = "social.near"; +const networkId = "mainnet"; + +module.exports = { SOCIAL_DB_CONTRACT_ID, networkId } \ No newline at end of file diff --git a/near-social-ai-agent/utils/imageUtils.js b/near-social-ai-agent/utils/imageUtils.js new file mode 100644 index 0000000..0266f99 --- /dev/null +++ b/near-social-ai-agent/utils/imageUtils.js @@ -0,0 +1,95 @@ +// const fetch = require('node-fetch'); // Use node-fetch to make HTTP requests +const { Readable } = require('stream'); +const mime = require('mime-types'); +const axios = require('axios'); + +const uploadIPFS = async (fileUrl) => { + try { + // const file = await urlToFile(fileUrl, 'image.jpg'); + + const formData = new FormData(); + // formData.append('file', file); + + const res = await axios.post('https://ipfs.near.social/add', formData, { + headers: { + 'Content-Type': 'multipart/form-data', + Accept: "application/json", + }, + }); + + if (res.status === 200) { + const data = res.data; + console.log('File Upload Result:', data); + return data.cid; + } else { + throw new Error('Upload failed with status ' + res.status); + } + } catch (error) { + console.error('Error >>', error.message); + throw error; + } +}; + +// const urlToFile = async (fileUrl, fileName) => { +// try { +// const fetch = (await import('node-fetch')).default; +// // Fetch the file from the URL +// const response = await fetch(fileUrl); + +// if (!response.ok) { +// throw new Error(`Failed to fetch file. Status: ${response.status}`); +// } + +// // Get the content-type from the response headers +// const contentType = response.headers.get('content-type') || 'application/octet-stream'; + +// // Get the file extension from the MIME type +// const extension = mime.extension(contentType) || 'bin'; + +// // Read the response body as a buffer +// const buffer = await response.buffer(); + +// // Create a file-like object +// const file = { +// buffer, +// fileName: `${fileName}.jpg`, +// contentType, +// size: buffer.length, +// // Mimicking a File object +// stream: Readable.from(buffer), +// }; + +// console.log('File-like object created:', file); +// return file; +// } catch (error) { +// console.error('Error converting URL to file:', error.message); +// throw error; +// } +// }; + +// const urlToFile = async (fileUrl, fileName) => { +// try { +// const fetch = (await import('node-fetch')).default; +// const response = await fetch(fileUrl); + +// // Check if the request was successful +// if (!response.ok) { +// throw new Error(`Failed to fetch image: ${response.statusText}`); +// } + +// // Convert the response to a Blob +// const blob = await response.blob(); + +// // Create a File object from the Blob +// const file = new File([blob], fileName, { type: blob.type }); + +// console.log("File >> ", file) + +// return file; +// } catch (error) { +// console.error('Error converting URL to file:', error.message); +// throw error; +// } +// }; + +module.exports = { uploadIPFS }; diff --git a/near-social-ai-agent/utils/nearSocialUtils.js b/near-social-ai-agent/utils/nearSocialUtils.js new file mode 100644 index 0000000..6f4a726 --- /dev/null +++ b/near-social-ai-agent/utils/nearSocialUtils.js @@ -0,0 +1,137 @@ +const { providers, utils } = require('near-api-js'); +const { SOCIAL_DB_CONTRACT_ID, networkId } = require('./constant'); + +// Function to get profile details of the given accountId +const getSocialProfile = async (accountId) => { + const providerUrl = `https://rpc.${networkId}.near.org`; + const provider = new providers.JsonRpcProvider({ url: providerUrl }); + + try { + // Set the query arguments for fetching the social profile + const queryArgs = { + keys: [`${accountId}/profile/**`], + }; + + // Query the `get` method on the social DB contract + const res = await provider.query({ + request_type: 'call_function', + account_id: SOCIAL_DB_CONTRACT_ID, + method_name: 'get', + args_base64: Buffer.from(JSON.stringify(queryArgs)).toString('base64'), + finality: 'optimistic', + }); + + // Parse the result from the blockchain + const profileData = JSON.parse(Buffer.from(res.result).toString()); + + if (!profileData[accountId]) return; + + delete profileData[accountId].profile.image; + delete profileData[accountId].profile.backgroundImage; + + console.log("Profile >> ", profileData[accountId].profile); + return profileData[accountId].profile; + + } catch (error) { + console.error("Error fetching profile: ", error); + throw new Error(error?.message || "Failed to fetch profile."); + } +}; + +// Get the list of following accounts +const getFollowing = async (accountId) => { + const providerUrl = `https://rpc.${networkId}.near.org`; + const provider = new providers.JsonRpcProvider({ url: providerUrl }); + + try { + const queryArgs = { + keys: [`${accountId}/graph/follow/*`], + }; + + const res = await provider.query({ + request_type: 'call_function', + account_id: SOCIAL_DB_CONTRACT_ID, + method_name: 'get', + args_base64: Buffer.from(JSON.stringify(queryArgs)).toString('base64'), + finality: 'optimistic', + }); + + const response = JSON.parse(Buffer.from(res.result).toString()); + + if (!response || !response[accountId]?.graph?.follow) { + return { accounts: [], total: 0 }; + } + + const followingAccounts = Object.keys(response[accountId].graph.follow); + return { accounts: followingAccounts, total: followingAccounts.length }; + } catch (e) { + console.error('getFollowing:', e); + return { accounts: [], total: 0 }; + } +}; + +const getFollowers = async ({ accountId }) => { + const providerUrl = `https://rpc.${networkId}.near.org`; + const provider = new providers.JsonRpcProvider({ url: providerUrl }); + + try { + const queryArgs = { + keys: [`*/graph/follow/${accountId}`], + }; + + const res = await provider.query({ + request_type: 'call_function', + account_id: SOCIAL_DB_CONTRACT_ID, + method_name: 'get', + args_base64: Buffer.from(JSON.stringify(queryArgs)).toString('base64'), + finality: 'optimistic', + }); + + const response = JSON.parse(Buffer.from(res.result).toString()); + + if (!response) { + return { accounts: [], total: 0 }; + } + + const followerAccounts = Object.keys(response).filter((key) => { + return response[key]?.graph?.follow?.hasOwnProperty(accountId); + }); + + return { accounts: followerAccounts, total: followerAccounts.length }; + } catch (e) { + console.error('getFollowers:', e); + return { accounts: [], total: 0 }; + } +}; + +// Function to get available storage for a specific account +const getAvailableStorage = async (accountId, networkId = 'mainnet') => { + console.log("Account Id : ", accountId) + const providerUrl = `https://rpc.${networkId}.near.org`; + const provider = new providers.JsonRpcProvider({ url: providerUrl }); + + try { + // Query the 'storage_balance_of' method on the NEAR Social DB contract + const args = { account_id: accountId }; + const res = await provider.query({ + request_type: 'call_function', + account_id: SOCIAL_DB_CONTRACT_ID, + method_name: 'get_account_storage', + args_base64: Buffer.from(JSON.stringify(args)).toString('base64'), + finality: 'optimistic', + }); + + // Parse and calculate the available storage + const storage = JSON.parse(Buffer.from(res.result).toString()); + // // const availableStorage = BigInt(storage?.available) / BigInt(10 ** 19); + // const ratePerNear = 100000; + // const availableStorage = BigInt(storage?.available) * BigInt(ratePerNear) / BigInt(10 ** 24); + + return storage; // Return the available storage + } catch (error) { + console.error("Error fetching storage balance: ", error); + throw new Error(error?.message || "Failed to fetch NEAR storage balance."); + } +}; + +module.exports = { getSocialProfile, getFollowing, getFollowers, getAvailableStorage } \ No newline at end of file diff --git a/near-social-ai-agent/utils/utils.js b/near-social-ai-agent/utils/utils.js new file mode 100644 index 0000000..8afa038 --- /dev/null +++ b/near-social-ai-agent/utils/utils.js @@ -0,0 +1,117 @@ +const { providers, utils } = require('near-api-js'); +const Big = require('big.js'); + +const StorageCostPerByte = Big(10).pow(19); + +const convertToStringLeaves = (data) => { + return isObject(data) + ? Object.entries(data).reduce((obj, [key, value]) => { + obj[stringify(key)] = convertToStringLeaves(value); + return obj; + }, {}) + : stringify(data); +}; + +const extractKeys = (data, prefix = "") => + Object.entries(data) + .map(([key, value]) => + isObject(value) + ? extractKeys(value, `${prefix}${key}/`) + : `${prefix}${key}` + ) + .flat(); + +const fetchCurrentData = async (data, accountId = 'golden_comet.near', networkId = 'mainnet') => { + const keys = extractKeys(data); + const provider = new providers.JsonRpcProvider(`https://rpc.${networkId}.near.org`); + + try { + const args = { keys }; + + const res = await provider.query({ + request_type: 'call_function', + account_id: accountId, + method_name: 'get', + args_base64: Buffer.from(JSON.stringify(args)).toString('base64'), + finality: 'optimistic', + }); + + const result = JSON.parse(Buffer.from(res.result).toString()); + return result; + } catch (error) { + console.error("Error fetching data: ", error); + throw new Error(error?.message || "Failed to fetch data from contract."); + } +}; + +const removeDuplicates = (data, prevData) => { + const obj = Object.entries(data).reduce((obj, [key, value]) => { + const prevValue = isObject(prevData) ? prevData[key] : undefined; + if (isObject(value)) { + const newValue = isObject(prevValue) + ? removeDuplicates(value, prevValue) + : value; + if (newValue !== undefined) { + obj[key] = newValue; + } + } else if (value !== prevValue) { + obj[key] = value; + } + + return obj; + }, {}); + return Object.keys(obj).length ? obj : undefined; +}; + +const stringify = (s) => (isString(s) || s === null ? s : JSON.stringify(s)); + +const isArray = (a) => Array.isArray(a); + +const isObject = (o) => o === Object(o) && !isArray(o) && typeof o !== "function"; + +const isString = (s) => typeof s === "string"; + +const EstimatedKeyValueSize = 40 * 3 + 8 + 12; +const EstimatedNodeSize = 40 * 2 + 8 + 10; + +// Function to calculate the size of JSON data in bytes +const estimateDataSize = (data, prevData) => + isObject(data) + ? Object.entries(data).reduce( + (s, [key, value]) => { + const prevValue = isObject(prevData) ? prevData[key] : undefined; + return ( + s + + (prevValue !== undefined + ? estimateDataSize(value, prevValue) + : key.length * 2 + + estimateDataSize(value, undefined) + + EstimatedKeyValueSize) + ); + }, + isObject(prevData) ? 0 : EstimatedNodeSize + ) + : (data?.length || 8) - (isString(prevData) ? prevData.length : 0); + + +const bigMax = (a, b) => { + if (a && b) { + return a.gt(b) ? a : b; + } + return a || b; +}; + + +// Function for calculate the saving data size in bytes +const calculateTextSizeInBytes = (value) => { + const encoder = new TextEncoder(); + return encoder.encode(value).length; +} + +// Function to calculate the NEAR amount needed to cover storage costs +const calculateNearAmount = (totalSizeInBytes, ratePerNear = 100000) => { + const rate = ratePerNear; + return Number(totalSizeInBytes / rate); +}; + +module.exports = { estimateDataSize, StorageCostPerByte, bigMax, removeDuplicates, fetchCurrentData, calculateTextSizeInBytes, calculateNearAmount, convertToStringLeaves }; \ No newline at end of file diff --git a/near-social-ai-agent/vercel.json b/near-social-ai-agent/vercel.json new file mode 100644 index 0000000..6c9fb04 --- /dev/null +++ b/near-social-ai-agent/vercel.json @@ -0,0 +1,20 @@ +{ + "version": 2, + "builds": [ + { + "src": "app.js", + "use": "@vercel/node", + "config": { + "includeFiles": [ + "dist/**" + ] + } + } + ], + "routes": [ + { + "src": "/(.*)", + "dest": "app.js" + } + ] +} \ No newline at end of file