init commit
This commit is contained in:
264
README.md
264
README.md
@@ -0,0 +1,264 @@
|
||||
# Cryptocurrency Exchange Platform
|
||||
|
||||
A comprehensive cryptocurrency exchange server built with Node.js, TypeScript, and Express. This platform supports trading of Bitcoin, Ethereum, and Tron cryptocurrencies with Iranian Rial (IRR) support.
|
||||
|
||||
## Features
|
||||
|
||||
- **Multi-Cryptocurrency Support**: Bitcoin (BTC), Ethereum (ETH), and Tron (TRX)
|
||||
- **User Authentication**: Email and phone verification, session management
|
||||
- **Wallet Management**: Secure wallet operations with support for multiple cryptocurrencies
|
||||
- **Trading System**: Buy/sell orders, offer management, and order matching
|
||||
- **Price Statistics**: Real-time and historical price data (hourly, daily, weekly, monthly, yearly)
|
||||
- **Real-time Updates**: WebSocket integration via Socket.io for live updates
|
||||
- **Admin Panel**: Administrative tools for managing the exchange
|
||||
- **Support Tickets**: Integrated ticketing system for customer support
|
||||
- **Automated Backups**: Daily database backups
|
||||
- **Rate Limiting**: Brute force protection and rate limiting
|
||||
|
||||
## Tech Stack
|
||||
|
||||
- **Runtime**: Node.js
|
||||
- **Language**: TypeScript
|
||||
- **Framework**: Express.js
|
||||
- **Database**: MongoDB (Mongoose)
|
||||
- **Cache**: Redis
|
||||
- **Message Queue**: AMQP (RabbitMQ)
|
||||
- **Real-time**: Socket.io
|
||||
- **Blockchain Libraries**:
|
||||
- `bitcoin-core` for Bitcoin
|
||||
- `web3` and `ethereumjs-tx` for Ethereum
|
||||
- `tronweb` for Tron
|
||||
- **Other**: Winston (logging), Nodemailer (emails), bcrypt (hashing)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Node.js (v14 or higher)
|
||||
- MongoDB
|
||||
- Redis
|
||||
- RabbitMQ (AMQP)
|
||||
- TypeScript
|
||||
|
||||
## Installation
|
||||
|
||||
1. Clone the repository:
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd Exchange
|
||||
```
|
||||
|
||||
2. Navigate to the server directory:
|
||||
```bash
|
||||
cd server
|
||||
```
|
||||
|
||||
3. Install dependencies:
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
4. Create a `.env` file in the server directory with the following variables:
|
||||
|
||||
```env
|
||||
# Database
|
||||
MONGO_DATABASE=mongodb://localhost:27017/exchange
|
||||
MONGO_DATABASE_NAME_TICKETS=trudesk
|
||||
|
||||
# Session
|
||||
SESSION_SECRET=your-session-secret-key
|
||||
|
||||
# Redis
|
||||
REDIS_HOST=localhost
|
||||
REDIS_PORT=6379
|
||||
# REDIS_PASS=your-redis-password
|
||||
|
||||
# AMQP (RabbitMQ)
|
||||
AMQP_URL=amqp://localhost
|
||||
|
||||
# Email (Nodemailer)
|
||||
NODEMAILER_HOST=smtp.gmail.com
|
||||
NODEMAILER_PORT=587
|
||||
NODEMAILER_USER=your-email@gmail.com
|
||||
NODEMAILER_PASS=your-email-password
|
||||
SENDER_ADDRESS=your-email@gmail.com
|
||||
|
||||
# API
|
||||
API=http://localhost:3001
|
||||
|
||||
# External APIs
|
||||
CURRENCY_API_KEY=your-nomics-api-key
|
||||
SMS_API_ACCESS_KEY=your-sms-api-key
|
||||
SMS_API_PHONE_PATTERN_CODE=your-sms-pattern-code
|
||||
SMS_API_DEFINITE_SENDER_NUMBER=your-sms-sender-number
|
||||
|
||||
# Ticket System
|
||||
TICKET_START_CONVERSATION=your-ticket-api-url
|
||||
TICKET_GET_MESSAGES_URL=your-ticket-api-url
|
||||
TICKET_CREATE_TICKET_URL=your-ticket-api-url
|
||||
TICKET_ADD_COMMENT_URL=your-ticket-api-url
|
||||
TICKET_SEND_MESSAGE_URL=your-ticket-api-url
|
||||
SUPPORT_ROLE_ID=your-support-role-id
|
||||
USER_ROLE_ID=your-user-role-id
|
||||
ACCESS_TOKEN=your-access-token
|
||||
|
||||
# Crypto
|
||||
CRYPTO_SECRET=your-crypto-secret
|
||||
SALT_I=10
|
||||
OBJECTID_RIAL=your-rial-currency-object-id
|
||||
|
||||
# Feature Flags
|
||||
BUYFROMOFFERS=true
|
||||
|
||||
# Chart
|
||||
CHART_LIMIT=20
|
||||
|
||||
# Test
|
||||
TEST_API_URL=http://localhost:3001
|
||||
NODE_ENV=development
|
||||
```
|
||||
|
||||
5. Compile TypeScript (if needed):
|
||||
```bash
|
||||
npx tsc
|
||||
```
|
||||
|
||||
## Running the Application
|
||||
|
||||
### Development Mode
|
||||
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
|
||||
The server will start on `http://localhost:3001`
|
||||
|
||||
### Test Mode
|
||||
|
||||
```bash
|
||||
npm run test-env
|
||||
```
|
||||
|
||||
### Running Tests
|
||||
|
||||
```bash
|
||||
npm test
|
||||
```
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
server/
|
||||
├── api/ # API utilities and integrations
|
||||
│ ├── walletApi/ # Blockchain wallet APIs (Bitcoin, Ethereum, Tron)
|
||||
│ ├── amqp.ts # AMQP message queue configuration
|
||||
│ ├── logger.ts # Winston logger configuration
|
||||
│ ├── redis.ts # Redis client configuration
|
||||
│ └── socket.ts # Socket.io configuration
|
||||
├── db/ # Database models and schemas
|
||||
│ ├── user.ts # User model
|
||||
│ ├── currencies.ts # Currency model
|
||||
│ ├── activeOffers.ts # Active trading offers
|
||||
│ ├── acceptedOffers.ts # Accepted offers
|
||||
│ └── ... # Other models
|
||||
├── middlewares/ # Express middlewares
|
||||
│ ├── auth.ts # Authentication middleware
|
||||
│ ├── validation.ts # Request validation
|
||||
│ ├── errorHandler.ts # Error handling
|
||||
│ └── preventBruteForce.ts # Rate limiting
|
||||
├── routes/ # API routes
|
||||
│ ├── auth.ts # Authentication routes
|
||||
│ ├── user.ts # User routes
|
||||
│ ├── wallet.ts # Wallet routes
|
||||
│ ├── admin.ts # Admin routes
|
||||
│ ├── service.ts # Service routes
|
||||
│ └── tickets.ts # Support ticket routes
|
||||
├── scripts/ # Utility scripts
|
||||
│ ├── priceStats.ts # Price statistics
|
||||
│ ├── currenciesadder.ts # Currency management
|
||||
│ └── localPriceScript.ts # Local price tracking
|
||||
└── test/ # Test files
|
||||
```
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### Authentication (`/auth`)
|
||||
- `GET /auth` - Check authentication status
|
||||
- `POST /register` - User registration
|
||||
- `POST /login` - User login
|
||||
- `GET /logout` - User logout
|
||||
- `POST /verify` - Verify email/phone
|
||||
|
||||
### User (`/user`)
|
||||
- `GET /getUserWallet` - Get user wallet balance
|
||||
- `GET /getUserOffers` - Get user's trading offers
|
||||
- `POST /createOffer` - Create a new trading offer
|
||||
- `GET /getUserTransactions` - Get user transaction history
|
||||
|
||||
### Wallet (`/wallet`)
|
||||
- `GET /getEtheriumNonce` - Get Ethereum nonce
|
||||
- `POST /transferToExchange` - Transfer cryptocurrency to exchange
|
||||
- `POST /transferFromExchange` - Transfer cryptocurrency from exchange
|
||||
- `POST /transferToExchangeById` - Transfer by transaction ID
|
||||
|
||||
### Service (`/service`)
|
||||
- `GET /getDeafultAcceptedOffers` - Get default accepted offers
|
||||
- `GET /getPriceChart` - Get price chart data
|
||||
- `GET /getCurrencies` - Get supported currencies
|
||||
|
||||
### Admin (`/admin`)
|
||||
- Admin-specific endpoints for managing the exchange
|
||||
|
||||
### Tickets (`/tickets`)
|
||||
- Support ticket management endpoints
|
||||
|
||||
## Key Features
|
||||
|
||||
### Automated Tasks
|
||||
- Daily database backups (runs at 11:59 PM)
|
||||
- Continuous price statistics updates
|
||||
- Local price tracking (hourly, daily, weekly, monthly, yearly)
|
||||
- Dollar to Rial price updates
|
||||
|
||||
### Security
|
||||
- Session-based authentication
|
||||
- CSRF protection
|
||||
- Rate limiting and brute force protection
|
||||
- Password hashing with bcrypt
|
||||
- Input validation
|
||||
|
||||
### Real-time Features
|
||||
- Socket.io for real-time updates
|
||||
- Online user tracking
|
||||
- Live price updates
|
||||
|
||||
## Logging
|
||||
|
||||
The application uses Winston for logging. Logs are written to:
|
||||
- `combined.log` - All logs
|
||||
- `error.log` - Error logs
|
||||
- `exceptions.log` - Uncaught exceptions
|
||||
|
||||
## Database
|
||||
|
||||
The application uses MongoDB with the following main databases:
|
||||
- `exchange` - Main application data
|
||||
- `trudesk` - Support ticket system
|
||||
|
||||
## Contributing
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a feature branch
|
||||
3. Make your changes
|
||||
4. Write tests if applicable
|
||||
5. Submit a pull request
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
## Notes
|
||||
|
||||
- Make sure MongoDB, Redis, and RabbitMQ are running before starting the server
|
||||
- Configure all environment variables in the `.env` file
|
||||
- The application includes automated backup scripts that run daily
|
||||
- Price statistics are updated continuously for real-time trading data
|
||||
|
||||
|
||||
BIN
server/.DS_Store
vendored
Normal file
BIN
server/.DS_Store
vendored
Normal file
Binary file not shown.
57
server/.env
Executable file
57
server/.env
Executable file
@@ -0,0 +1,57 @@
|
||||
#API address
|
||||
|
||||
API=http://localhost:3001
|
||||
|
||||
#session
|
||||
SESSION_SECRET=test
|
||||
|
||||
|
||||
#mongo
|
||||
|
||||
MONGO_SECRET=aaaaa
|
||||
MONGO_DATABASE=mongodb://localhost:27017/exchange
|
||||
SALT_I=10
|
||||
MONGO_DATABASE_NAME=exchange
|
||||
|
||||
|
||||
#nodemailer
|
||||
NODEMAILER_HOST=mail.polychain.ir
|
||||
NODEMAILER_PORT=465
|
||||
NODEMAILER_USER=admin@polychain.ir
|
||||
NODEMAILER_PASS=@polychainAdmin
|
||||
SENDER_ADDRESS=<admin@polychain.ir>
|
||||
|
||||
|
||||
#AMQP
|
||||
AMQP_URL=amqp://guest:guest@localhost
|
||||
|
||||
#REDIS
|
||||
REDIS_PORT=6379
|
||||
REDIS_HOST=localhost
|
||||
CRYPTO_SECRET=abcde
|
||||
BUYFROMOFFERS=true
|
||||
|
||||
|
||||
MONGO_DATABASE_NAME_TICKETS=trudesk
|
||||
TICKET_GET_MESSAGES_URL=http://localhost:8118/api/v1/users/create
|
||||
TICKET_CREATE_TICKET_URL=http://localhost:8118/api/v1/tickets/create
|
||||
TICKET_ADD_COMMENT_URL=http://localhost:8118/api/v1/tickets/addcomment
|
||||
TICKET_TICKET_URL=http://localhost:8118/api/v1/tickets/
|
||||
ACCESS_TOKEN=556a5e513dc8a4e3c0b1643886a9cf3f636b1945
|
||||
SUPPORT_ROLE_ID=5fb21707795091261c6d2194
|
||||
USER_ROLE_ID=5fb21707795091261c6d2192
|
||||
# CURRENCY_API
|
||||
CURRENCY_API_KEY=6ba4711649395555617a5bd91a416dac
|
||||
|
||||
|
||||
process.env.ADMIN_ETHERIUM_ACCOUNT_ADDRESS=0x868453967f6806ef86de7cf5e57a32ab28b875b4
|
||||
process.env.ADMIN_ETHERIUM_ACCOUNT_PASSWORD=exchange
|
||||
process.env.CLIENT_ETHERIUM_ACCOUNT_ADDRESS=0xC1BC3cB61722c959030aF512883F2E884baF5702
|
||||
process.env.CLIENT_ETHERIUM_ACCOUNT_PRIVATE_KEY=64061456066baa81c5097c895b5176fb3e1452eaf6f6776e2d7bf07ddb9accfe
|
||||
# ObjectIDS
|
||||
OBJECTID_RIAL=5f719d994923c95630df06be
|
||||
|
||||
|
||||
CHART_LIMIT=20
|
||||
|
||||
|
||||
100
server/api/amqp.js
Executable file
100
server/api/amqp.js
Executable file
@@ -0,0 +1,100 @@
|
||||
'use strict';
|
||||
exports.__esModule = true;
|
||||
exports.publishQueueConnection = void 0;
|
||||
// This script fetches queued messages from RabbitMQ and delivers these to SMTP
|
||||
var nodemailer = require("nodemailer");
|
||||
var amqp = require("amqp");
|
||||
var queueHost = process.env.AMQP_URL;
|
||||
var queueName = 'outgoing';
|
||||
var smtpHost = {
|
||||
host: process.env.NODEMAILER_HOST,
|
||||
port: process.env.NODEMAILER_PORT,
|
||||
// NB! Must be pooled connection, otherwise 'idle' is never fired and nothing gets sent
|
||||
pool: true,
|
||||
auth: {
|
||||
user: process.env.NODEMAILER_USER,
|
||||
pass: process.env.NODEMAILER_PASS
|
||||
},
|
||||
tls: {
|
||||
// testserver uses self signed certificate, so we need to lax a bit
|
||||
rejectUnauthorized: false
|
||||
},
|
||||
logger: false
|
||||
};
|
||||
// array of prefetched messages waiting for delivery
|
||||
var waiting = [];
|
||||
// Create a SMTP transporter object
|
||||
var transporter = nodemailer.createTransport(smtpHost, {
|
||||
// default message fields
|
||||
from: process.env.SENDER_ADDRESS
|
||||
});
|
||||
// Create connection to RabbitMQ
|
||||
var queueConnection = amqp.createConnection({
|
||||
url: queueHost
|
||||
});
|
||||
queueConnection.on('error', function (e) {
|
||||
console.log('Error from amqp: ', e);
|
||||
});
|
||||
queueConnection.on('ready', function (err) {
|
||||
console.log('AMPQ server is running on port 5672.');
|
||||
queueConnection.queue(queueName, { durable: true }, function (q) {
|
||||
q.bind('#');
|
||||
q.subscribe({
|
||||
ack: true,
|
||||
prefetchCount: 10 // prefetch 10 messages
|
||||
}, function (message, headers, deliveryInfo, ack) {
|
||||
// check if the message object is even valid
|
||||
if (!message || !message.to) {
|
||||
console.log('Invalid message, skipping');
|
||||
// reject, do not requeue
|
||||
return ack.reject();
|
||||
}
|
||||
// push to cache
|
||||
waiting.push({
|
||||
message: message,
|
||||
deliveryTag: deliveryInfo.deliveryTag.toString('hex'),
|
||||
ack: ack
|
||||
});
|
||||
// try to flush cached messages by sending these to SMTP
|
||||
flushWaitingMessages();
|
||||
});
|
||||
});
|
||||
});
|
||||
// Whenever transporter gets into idling, try to send some mail
|
||||
transporter.on('idle', flushWaitingMessages);
|
||||
// Flushes cached messages to nodemailer for delivery
|
||||
function flushWaitingMessages() {
|
||||
// actual send function
|
||||
var send = function (data) {
|
||||
// sendMail does not immediatelly send, instead it tries to allocate a free connection to SMTP server
|
||||
// and if fails, then pushes the message into internal queue. As we only prefetch 10 messages
|
||||
// then the internal queue can never grow into something too large. At most there will be 5 messages
|
||||
// idling in the queue (another 5 are being currently sent by the default number of 5 connections)
|
||||
transporter.sendMail(data.message, function (err, info) {
|
||||
if (err) {
|
||||
console.log('Message failed (%s): %s', data.deliveryTag, err.message);
|
||||
// reject and requeue on error (wait 1 sec. before requeueing)
|
||||
// NB! If the failure is permanent then this approach results in an
|
||||
// infinite loop since failing message is never removed from the queue
|
||||
setTimeout(function () {
|
||||
data.ack.reject(true);
|
||||
}, 1000);
|
||||
return;
|
||||
}
|
||||
console.log('Message delivered (%s): %s', data.deliveryTag, info.response);
|
||||
data.ack.acknowledge();
|
||||
});
|
||||
};
|
||||
// send cached messages if transporter is idling
|
||||
while (transporter.isIdle() && waiting.length) {
|
||||
send(waiting.shift());
|
||||
}
|
||||
}
|
||||
exports.publishQueueConnection = function (mailOptions) {
|
||||
console.log('publishQueueConnection');
|
||||
queueConnection.publish(queueName, mailOptions, function (err) {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
});
|
||||
};
|
||||
112
server/api/amqp.ts
Executable file
112
server/api/amqp.ts
Executable file
@@ -0,0 +1,112 @@
|
||||
'use strict'
|
||||
|
||||
// This script fetches queued messages from RabbitMQ and delivers these to SMTP
|
||||
|
||||
import * as nodemailer from 'nodemailer'
|
||||
import * as amqp from 'amqp'
|
||||
|
||||
const queueHost = process.env.AMQP_URL
|
||||
const queueName = 'outgoing'
|
||||
|
||||
const smtpHost = {
|
||||
host: process.env.NODEMAILER_HOST,
|
||||
port: process.env.NODEMAILER_PORT,
|
||||
// NB! Must be pooled connection, otherwise 'idle' is never fired and nothing gets sent
|
||||
pool: true,
|
||||
auth: {
|
||||
user: process.env.NODEMAILER_USER,
|
||||
pass: process.env.NODEMAILER_PASS
|
||||
},
|
||||
tls: {
|
||||
// testserver uses self signed certificate, so we need to lax a bit
|
||||
rejectUnauthorized: false
|
||||
},
|
||||
logger: false
|
||||
}
|
||||
|
||||
// array of prefetched messages waiting for delivery
|
||||
const waiting = []
|
||||
// Create a SMTP transporter object
|
||||
const transporter = nodemailer.createTransport(smtpHost, {
|
||||
// default message fields
|
||||
from: process.env.SENDER_ADDRESS
|
||||
})
|
||||
|
||||
// Create connection to RabbitMQ
|
||||
const queueConnection = amqp.createConnection({
|
||||
url: queueHost
|
||||
})
|
||||
|
||||
queueConnection.on('error', function (e) {
|
||||
console.log('Error from amqp: ', e)
|
||||
})
|
||||
|
||||
queueConnection.on('ready', function (err) {
|
||||
console.log('AMPQ server is running on port 5672.')
|
||||
queueConnection.queue(queueName, { durable: true }, function (q) {
|
||||
q.bind('#')
|
||||
q.subscribe({
|
||||
ack: true, // do not fetch next messages until previous are acked
|
||||
prefetchCount: 10 // prefetch 10 messages
|
||||
}, function (message, headers, deliveryInfo, ack) {
|
||||
// check if the message object is even valid
|
||||
if (!message || !message.to) {
|
||||
console.log('Invalid message, skipping')
|
||||
// reject, do not requeue
|
||||
return ack.reject()
|
||||
}
|
||||
// push to cache
|
||||
waiting.push({
|
||||
message: message,
|
||||
deliveryTag: deliveryInfo.deliveryTag.toString('hex'),
|
||||
ack: ack
|
||||
})
|
||||
// try to flush cached messages by sending these to SMTP
|
||||
flushWaitingMessages()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
// Whenever transporter gets into idling, try to send some mail
|
||||
transporter.on('idle', flushWaitingMessages)
|
||||
|
||||
// Flushes cached messages to nodemailer for delivery
|
||||
function flushWaitingMessages () {
|
||||
// actual send function
|
||||
var send = function (data) {
|
||||
// sendMail does not immediatelly send, instead it tries to allocate a free connection to SMTP server
|
||||
// and if fails, then pushes the message into internal queue. As we only prefetch 10 messages
|
||||
// then the internal queue can never grow into something too large. At most there will be 5 messages
|
||||
// idling in the queue (another 5 are being currently sent by the default number of 5 connections)
|
||||
transporter.sendMail(data.message, function (err, info) {
|
||||
if (err) {
|
||||
console.log('Message failed (%s): %s', data.deliveryTag, err.message)
|
||||
// reject and requeue on error (wait 1 sec. before requeueing)
|
||||
// NB! If the failure is permanent then this approach results in an
|
||||
// infinite loop since failing message is never removed from the queue
|
||||
setTimeout(function () {
|
||||
data.ack.reject(true)
|
||||
}, 1000)
|
||||
return
|
||||
}
|
||||
console.log('Message delivered (%s): %s', data.deliveryTag, info.response)
|
||||
data.ack.acknowledge()
|
||||
})
|
||||
}
|
||||
|
||||
// send cached messages if transporter is idling
|
||||
while (transporter.isIdle() && waiting.length) {
|
||||
send(waiting.shift())
|
||||
}
|
||||
}
|
||||
|
||||
export const publishQueueConnection = (mailOptions) => {
|
||||
console.log('publishQueueConnection')
|
||||
queueConnection.publish(queueName, mailOptions, (err) => {
|
||||
if (err) {
|
||||
console.log(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
46
server/api/logger.js
Executable file
46
server/api/logger.js
Executable file
@@ -0,0 +1,46 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.LoggerStream = exports.logger = void 0;
|
||||
var winston = require("winston");
|
||||
var _a = winston.format, combine = _a.combine, timestamp = _a.timestamp, label = _a.label, prettyPrint = _a.prettyPrint, colorize = _a.colorize, json = _a.json, splat = _a.splat;
|
||||
/// /////////////////////////////////////////////////////////////////////////////
|
||||
/// ///////////////////////Winston Logger///////////////////////////////////////
|
||||
/// ////////////////////////////////////////////////////////////////////////////
|
||||
exports.logger = winston.createLogger({
|
||||
exitOnError: false,
|
||||
format: combine(timestamp(), prettyPrint(), colorize(), splat()),
|
||||
level: 'info',
|
||||
// format: winston.format.json(),
|
||||
// defaultMeta: { service: 'user-service' },
|
||||
transports: [
|
||||
//
|
||||
// - Write to all logs with level `info` and below to `combined.log`
|
||||
// - Write all logs error (and below) to `error.log`.
|
||||
//
|
||||
new winston.transports.File({ filename: 'error.log', level: 'error' }),
|
||||
new winston.transports.File({ filename: 'combined.log' })
|
||||
],
|
||||
exceptionHandlers: [
|
||||
new winston.transports.File({ filename: 'exceptions.log' })
|
||||
]
|
||||
});
|
||||
// if (process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'development') {
|
||||
exports.logger.add(new winston.transports.Console({
|
||||
format: winston.format.simple()
|
||||
}));
|
||||
// }
|
||||
// logger.stream = {
|
||||
// write: function (message: string, encoding: any) {
|
||||
// logger.info(message)
|
||||
// }
|
||||
// }
|
||||
var LoggerStream = /** @class */ (function () {
|
||||
function LoggerStream() {
|
||||
}
|
||||
LoggerStream.prototype.write = function (message) {
|
||||
exports.logger.info(message);
|
||||
};
|
||||
return LoggerStream;
|
||||
}());
|
||||
exports.LoggerStream = LoggerStream;
|
||||
//module.exports = logger
|
||||
48
server/api/logger.ts
Executable file
48
server/api/logger.ts
Executable file
@@ -0,0 +1,48 @@
|
||||
import * as winston from 'winston'
|
||||
const { combine, timestamp, label, prettyPrint, colorize, json, splat } = winston.format
|
||||
|
||||
/// /////////////////////////////////////////////////////////////////////////////
|
||||
/// ///////////////////////Winston Logger///////////////////////////////////////
|
||||
/// ////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
export const logger = winston.createLogger({
|
||||
exitOnError: false,
|
||||
format: combine(
|
||||
timestamp(),
|
||||
prettyPrint(),
|
||||
colorize(),
|
||||
splat()
|
||||
),
|
||||
level: 'info',
|
||||
// format: winston.format.json(),
|
||||
// defaultMeta: { service: 'user-service' },
|
||||
transports: [
|
||||
//
|
||||
// - Write to all logs with level `info` and below to `combined.log`
|
||||
// - Write all logs error (and below) to `error.log`.
|
||||
//
|
||||
new winston.transports.File({ filename: 'error.log', level: 'error' }),
|
||||
new winston.transports.File({ filename: 'combined.log' })
|
||||
],
|
||||
exceptionHandlers: [
|
||||
new winston.transports.File({ filename: 'exceptions.log' })
|
||||
]
|
||||
})
|
||||
|
||||
// if (process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'development') {
|
||||
logger.add(new winston.transports.Console({
|
||||
format: winston.format.simple()
|
||||
}))
|
||||
// }
|
||||
// logger.stream = {
|
||||
// write: function (message: string, encoding: any) {
|
||||
// logger.info(message)
|
||||
// }
|
||||
// }
|
||||
export class LoggerStream {
|
||||
write(message: string) {
|
||||
logger.info(message);
|
||||
}
|
||||
}
|
||||
|
||||
//module.exports = logger
|
||||
31
server/api/myError.js
Executable file
31
server/api/myError.js
Executable file
@@ -0,0 +1,31 @@
|
||||
"use strict";
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
exports.__esModule = true;
|
||||
var myError = /** @class */ (function (_super) {
|
||||
__extends(myError, _super);
|
||||
function myError(messageEnglish, statusCode, clientCode, clientMessage, title) {
|
||||
var _newTarget = this.constructor;
|
||||
var _this = _super.call(this, messageEnglish) || this;
|
||||
_this.messageEnglish = messageEnglish;
|
||||
_this.statusCode = statusCode;
|
||||
_this.clientCode = clientCode;
|
||||
_this.clientMessage = clientMessage;
|
||||
_this.title = title;
|
||||
Object.setPrototypeOf(_this, _newTarget.prototype); // restore prototype chain
|
||||
return _this;
|
||||
}
|
||||
return myError;
|
||||
}(Error));
|
||||
exports["default"] = myError;
|
||||
25
server/api/myError.ts
Executable file
25
server/api/myError.ts
Executable file
@@ -0,0 +1,25 @@
|
||||
import { cli } from "winston/lib/winston/config";
|
||||
|
||||
export default class myError extends Error {
|
||||
messageEnglish: string;
|
||||
statusCode: Number;
|
||||
clientCode: Number;
|
||||
clientMessage: string;
|
||||
title: string;
|
||||
|
||||
constructor(
|
||||
messageEnglish ?: string,
|
||||
statusCode?: Number,
|
||||
clientCode?: Number,
|
||||
clientMessage?: string,
|
||||
title?: string
|
||||
) {
|
||||
super(messageEnglish);
|
||||
this.messageEnglish = messageEnglish;
|
||||
this.statusCode = statusCode;
|
||||
this.clientCode = clientCode;
|
||||
this.clientMessage = clientMessage;
|
||||
this.title = title;
|
||||
Object.setPrototypeOf(this, new.target.prototype); // restore prototype chain
|
||||
}
|
||||
}
|
||||
326
server/api/query.js
Executable file
326
server/api/query.js
Executable file
@@ -0,0 +1,326 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.searchOnActiveOffers = exports.searchOnTxs = void 0;
|
||||
var redis = require("../api/redis");
|
||||
var acceptedOffers_1 = require("../db/acceptedOffers");
|
||||
var ActiveOffers_1 = require("../db/ActiveOffers");
|
||||
exports.searchOnTxs = function (_a) {
|
||||
var curId = _a.curId, txType = _a.txType, rial = _a.rial;
|
||||
var itemsMap = new Map();
|
||||
var items = ['curId'];
|
||||
var definedItems = [];
|
||||
itemsMap.set('curId', curId);
|
||||
items.map(function (element) {
|
||||
if (itemsMap.get(element)) {
|
||||
definedItems.push(element);
|
||||
}
|
||||
});
|
||||
var query = [];
|
||||
var queryMap = new Map();
|
||||
queryMap.set('curId', [{ $or: [
|
||||
{ $and: [{ curGivenId: curId }, { curTakenId: rial._id }] },
|
||||
{ $and: [{ curTakenId: curId }, { curGivenId: rial._id }] }
|
||||
] }]);
|
||||
var definedItemsMap = definedItems.map(function (element) {
|
||||
query.push.apply(query, queryMap.get(element));
|
||||
});
|
||||
if (query.length === 0) {
|
||||
query = [{ $or: [{ curTakenId: rial._id }, { curGivenId: rial._id }] }];
|
||||
}
|
||||
console.log('query: ', query);
|
||||
return Promise.all(definedItemsMap)
|
||||
.then(function () {
|
||||
return acceptedOffers_1.Accepted_Offers.find({ $and: query })
|
||||
.then(function (result) {
|
||||
var modifiedResult = [];
|
||||
if (itemsMap.get('curId')) {
|
||||
return redis.hashGetAll(curId.toString())
|
||||
.then(function (curObj) {
|
||||
result.map(function (e) {
|
||||
if (e.curTakenId.toString() === rial._id.toString() && txType === 'sell') {
|
||||
modifiedResult.push({
|
||||
GcurrencyName: curObj.currencyName,
|
||||
GpersianName: curObj.per_name,
|
||||
GshortName: curObj.ab_name,
|
||||
Gvalue: e.curGivenVal,
|
||||
Gicon: curObj.icon,
|
||||
acceptedDate: e.created_at,
|
||||
TcurrencyName: rial.currencyName,
|
||||
TpersianName: rial.per_name,
|
||||
TshortName: rial.ab_name,
|
||||
Tvalue: e.curTakenVal,
|
||||
Ticon: rial.icon,
|
||||
txType: 'sell'
|
||||
});
|
||||
}
|
||||
else if (e.curGivenId.toString() === rial._id.toString() && txType === 'buy') {
|
||||
modifiedResult.push({
|
||||
GcurrencyName: curObj.currencyName,
|
||||
GpersianName: curObj.per_name,
|
||||
GshortName: curObj.ab_name,
|
||||
Gvalue: e.curTakenVal,
|
||||
Gicon: curObj.icon,
|
||||
acceptedDate: e.created_at,
|
||||
TcurrencyName: rial.currencyName,
|
||||
TpersianName: rial.per_name,
|
||||
TshortName: rial.ab_name,
|
||||
Tvalue: e.curGivenVal,
|
||||
Ticon: rial.icon,
|
||||
txType: 'buy'
|
||||
});
|
||||
}
|
||||
else if (txType === 'all') {
|
||||
if (e.curTakenId.toString() === rial._id.toString()) {
|
||||
modifiedResult.push({
|
||||
GcurrencyName: curObj.currencyName,
|
||||
GpersianName: curObj.per_name,
|
||||
GshortName: curObj.ab_name,
|
||||
Gvalue: e.curGivenVal,
|
||||
Gicon: curObj.icon,
|
||||
acceptedDate: e.created_at,
|
||||
TcurrencyName: rial.currencyName,
|
||||
TpersianName: rial.per_name,
|
||||
TshortName: rial.ab_name,
|
||||
Tvalue: e.curTakenVal,
|
||||
Ticon: rial.icon,
|
||||
txType: 'sell'
|
||||
});
|
||||
}
|
||||
else if (e.curGivenId.toString() === rial._id.toString()) {
|
||||
modifiedResult.push({
|
||||
GcurrencyName: curObj.currencyName,
|
||||
GpersianName: curObj.per_name,
|
||||
GshortName: curObj.ab_name,
|
||||
Gvalue: e.curTakenVal,
|
||||
Gicon: curObj.icon,
|
||||
acceptedDate: e.created_at,
|
||||
TcurrencyName: rial.currencyName,
|
||||
TpersianName: rial.per_name,
|
||||
TshortName: rial.ab_name,
|
||||
Tvalue: e.curGivenVal,
|
||||
Ticon: rial.icon,
|
||||
txType: 'buy'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
return modifiedResult;
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
else {
|
||||
var resultMap = result.map(function (e) {
|
||||
console.log('eeeeeeeee: ', e);
|
||||
if (e.curTakenId.toString() === rial._id.toString() && txType === 'sell') {
|
||||
return redis.hashGetAll(e.curGivenId.toString())
|
||||
.then(function (curGivenObj) {
|
||||
modifiedResult.push({
|
||||
GcurrencyName: curGivenObj.currencyName,
|
||||
GpersianName: curGivenObj.per_name,
|
||||
GshortName: curGivenObj.ab_name,
|
||||
Gvalue: e.curGivenVal,
|
||||
Gicon: curGivenObj.icon,
|
||||
acceptedDate: e.created_at,
|
||||
TcurrencyName: rial.currencyName,
|
||||
TpersianName: rial.per_name,
|
||||
TshortName: rial.ab_name,
|
||||
Tvalue: e.curTakenVal,
|
||||
Ticon: rial.icon,
|
||||
txType: 'sell'
|
||||
});
|
||||
})["catch"](function (err) {
|
||||
console.log(err);
|
||||
});
|
||||
}
|
||||
else if (e.curGivenId.toString() === rial._id.toString() && txType === 'buy') {
|
||||
return redis.hashGetAll(e.curTakenId.toString())
|
||||
.then(function (curTakenObj) {
|
||||
modifiedResult.push({
|
||||
GcurrencyName: curTakenObj.currencyName,
|
||||
GpersianName: curTakenObj.per_name,
|
||||
GshortName: curTakenObj.ab_name,
|
||||
Gvalue: e.curTakenVal,
|
||||
Gicon: curTakenObj.icon,
|
||||
acceptedDate: e.created_at,
|
||||
TcurrencyName: rial.currencyName,
|
||||
TpersianName: rial.per_name,
|
||||
TshortName: rial.ab_name,
|
||||
Tvalue: e.curGivenVal,
|
||||
Ticon: rial.icon,
|
||||
txType: 'buy'
|
||||
});
|
||||
})["catch"](function (err) {
|
||||
console.log(err);
|
||||
});
|
||||
}
|
||||
else if (txType === 'all') {
|
||||
if (e.curTakenId.toString() === rial._id.toString()) {
|
||||
return redis.hashGetAll(e.curGivenId.toString())
|
||||
.then(function (curGivenObj) {
|
||||
modifiedResult.push({
|
||||
GcurrencyName: curGivenObj.currencyName,
|
||||
GpersianName: curGivenObj.per_name,
|
||||
GshortName: curGivenObj.ab_name,
|
||||
Gvalue: e.curGivenVal,
|
||||
Gicon: curGivenObj.icon,
|
||||
acceptedDate: e.created_at,
|
||||
TcurrencyName: rial.currencyName,
|
||||
TpersianName: rial.per_name,
|
||||
TshortName: rial.ab_name,
|
||||
Tvalue: e.curTakenVal,
|
||||
Ticon: rial.icon,
|
||||
txType: 'sell'
|
||||
});
|
||||
})["catch"](function (err) {
|
||||
console.log(err);
|
||||
});
|
||||
}
|
||||
else if (e.curGivenId.toString() === rial._id.toString()) {
|
||||
return redis.hashGetAll(e.curTakenId.toString())
|
||||
.then(function (curTakenObj) {
|
||||
modifiedResult.push({
|
||||
GcurrencyName: curTakenObj.currencyName,
|
||||
GpersianName: curTakenObj.per_name,
|
||||
GshortName: curTakenObj.ab_name,
|
||||
Gvalue: e.curTakenVal,
|
||||
Gicon: curTakenObj.icon,
|
||||
acceptedDate: e.created_at,
|
||||
TcurrencyName: rial.currencyName,
|
||||
TpersianName: rial.per_name,
|
||||
TshortName: rial.ab_name,
|
||||
Tvalue: e.curGivenVal,
|
||||
Ticon: rial.icon,
|
||||
txType: 'buy'
|
||||
});
|
||||
})["catch"](function (err) {
|
||||
console.log(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
return Promise.all(resultMap)
|
||||
.then(function () {
|
||||
return modifiedResult;
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
};
|
||||
exports.searchOnActiveOffers = function (_a) {
|
||||
var offerId = _a.offerId, curGivenId = _a.curGivenId, curGivenVal = _a.curGivenVal, curTakenId = _a.curTakenId, curTakenVal = _a.curTakenVal, expDate = _a.expDate, created_at = _a.created_at;
|
||||
var itemsMap = new Map();
|
||||
var items = ['offerId', 'curGivenId', 'curGivenVal', 'curTakenId', 'curTakenVal', 'expDate', 'created_at'];
|
||||
var definedItems = [];
|
||||
itemsMap.set('offerId', offerId);
|
||||
itemsMap.set('curGivenId', curGivenId);
|
||||
itemsMap.set('curGivenVal', curGivenVal);
|
||||
itemsMap.set('curTakenId', curTakenId);
|
||||
itemsMap.set('curTakenVal', curTakenVal);
|
||||
itemsMap.set('expDate', expDate);
|
||||
itemsMap.set('created_at', created_at);
|
||||
items.map(function (element) {
|
||||
if (itemsMap.get(element)) {
|
||||
if (element === 'expDate') {
|
||||
if (expDate.from || expDate.to) {
|
||||
definedItems.push(element);
|
||||
}
|
||||
}
|
||||
else if (element === 'created_at') {
|
||||
if (created_at.from || created_at.to) {
|
||||
definedItems.push(element);
|
||||
}
|
||||
}
|
||||
else if (element === 'curGivenVal') {
|
||||
if (curGivenVal.from || curGivenVal.to) {
|
||||
definedItems.push(element);
|
||||
}
|
||||
}
|
||||
else if (element === 'curTakenVal') {
|
||||
if (curTakenVal.from || curTakenVal.to) {
|
||||
definedItems.push(element);
|
||||
}
|
||||
}
|
||||
else {
|
||||
definedItems.push(element);
|
||||
}
|
||||
}
|
||||
});
|
||||
var query = [{ expDate: { $gt: Date.now() } }];
|
||||
var queryMap = new Map();
|
||||
var queryExpDate;
|
||||
var queryCreatedAt;
|
||||
var queryCurGivenVal;
|
||||
var queryCurTakenVal;
|
||||
if (definedItems.includes('expDate')) {
|
||||
if (expDate.from && expDate.to) {
|
||||
queryExpDate = { expDate: { $gt: expDate.from, $lt: expDate.to } };
|
||||
}
|
||||
else if (expDate.from && !expDate.to) {
|
||||
queryExpDate = { expDate: { $gt: expDate.from } };
|
||||
}
|
||||
else if (!expDate.from && expDate.to) {
|
||||
queryExpDate = { expDate: { $lt: expDate.to } };
|
||||
}
|
||||
}
|
||||
if (definedItems.includes('created_at')) {
|
||||
if (created_at.from && created_at.to) {
|
||||
queryCreatedAt = { created_at: { $gt: created_at.from, $lt: created_at.to } };
|
||||
}
|
||||
else if (created_at.from && !created_at.to) {
|
||||
queryCreatedAt = { created_at: { $gt: created_at.from } };
|
||||
}
|
||||
else if (!created_at.from && created_at.to) {
|
||||
queryCreatedAt = { created_at: { $lt: created_at.to } };
|
||||
}
|
||||
}
|
||||
if (definedItems.includes('curGivenVal')) {
|
||||
if (curGivenVal.from && curGivenVal.to) {
|
||||
queryCurGivenVal = { curGivenVal: { $gte: curGivenVal.from, $lte: curGivenVal.to } };
|
||||
}
|
||||
else if (curGivenVal.from && !curGivenVal.to) {
|
||||
queryCurGivenVal = { curGivenVal: { $gte: curGivenVal.from } };
|
||||
}
|
||||
else if (!curGivenVal.from && curGivenVal.to) {
|
||||
queryCurGivenVal = { curGivenVal: { $lte: curGivenVal.to } };
|
||||
}
|
||||
}
|
||||
if (definedItems.includes('curTakenVal')) {
|
||||
if (curTakenVal.from && curTakenVal.to) {
|
||||
queryCurTakenVal = { curTakenVal: { $gte: curTakenVal.from, $lte: curTakenVal.to } };
|
||||
}
|
||||
else if (curTakenVal.from && !curTakenVal.to) {
|
||||
queryCurTakenVal = { curTakenVal: { $gte: curTakenVal.from } };
|
||||
}
|
||||
else if (!curTakenVal.from && curTakenVal.to) {
|
||||
queryCurTakenVal = { curTakenVal: { $lte: curTakenVal.to } };
|
||||
}
|
||||
}
|
||||
queryMap.set('offerId', { offerId: offerId });
|
||||
queryMap.set('curGivenId', { curGivenId: curGivenId });
|
||||
queryMap.set('curGivenVal', queryCurGivenVal);
|
||||
queryMap.set('curTakenId', { curTakenId: curTakenId });
|
||||
queryMap.set('curTakenVal', queryCurTakenVal);
|
||||
queryMap.set('expDate', queryExpDate);
|
||||
queryMap.set('created_at', queryCreatedAt);
|
||||
var definedItemsMap = definedItems.map(function (element) {
|
||||
query.push(queryMap.get(element));
|
||||
});
|
||||
return Promise.all(definedItemsMap)
|
||||
.then(function () {
|
||||
return ActiveOffers_1.Active_Offers.find({ $and: query })
|
||||
.then(function (result) {
|
||||
return result;
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
};
|
||||
334
server/api/query.ts
Executable file
334
server/api/query.ts
Executable file
@@ -0,0 +1,334 @@
|
||||
import * as _ from 'lodash'
|
||||
|
||||
import * as redis from '../api/redis'
|
||||
|
||||
|
||||
import { Accepted_Offers } from '../db/acceptedOffers';
|
||||
import { Active_Offers } from '../db/ActiveOffers';
|
||||
|
||||
export const searchOnTxs = ({ curId, txType, rial }) => {
|
||||
const itemsMap = new Map()
|
||||
const items = ['curId']
|
||||
const definedItems = []
|
||||
itemsMap.set('curId', curId)
|
||||
|
||||
|
||||
items.map((element) => {
|
||||
if(itemsMap.get(element)) {
|
||||
definedItems.push(element)
|
||||
}
|
||||
})
|
||||
|
||||
let query = []
|
||||
let queryMap = new Map()
|
||||
|
||||
queryMap.set('curId', [ { $or: [
|
||||
{ $and: [{ curGivenId: curId }, { curTakenId: rial._id } ] },
|
||||
{ $and: [{ curTakenId: curId }, { curGivenId: rial._id } ] }
|
||||
] } ] )
|
||||
|
||||
const definedItemsMap = definedItems.map((element) => {
|
||||
query.push.apply(query, queryMap.get(element))
|
||||
})
|
||||
|
||||
if(query.length === 0) {
|
||||
query = [ { $or: [ { curTakenId: rial._id }, { curGivenId: rial._id } ] } ]
|
||||
}
|
||||
console.log('query: ', query)
|
||||
return Promise.all(definedItemsMap)
|
||||
.then(() => {
|
||||
return Accepted_Offers.find({ $and: query })
|
||||
.then((result) => {
|
||||
let modifiedResult = []
|
||||
if(itemsMap.get('curId')) {
|
||||
return redis.hashGetAll(curId.toString())
|
||||
.then((curObj: any) => {
|
||||
result.map((e) => {
|
||||
if (e.curTakenId.toString() === rial._id.toString() && txType === 'sell') {
|
||||
modifiedResult.push ({
|
||||
GcurrencyName: curObj.currencyName,
|
||||
GpersianName: curObj.per_name,
|
||||
GshortName: curObj.ab_name,
|
||||
Gvalue: e.curGivenVal,
|
||||
Gicon: curObj.icon,
|
||||
acceptedDate: e.created_at,
|
||||
TcurrencyName: rial.currencyName,
|
||||
TpersianName: rial.per_name,
|
||||
TshortName: rial.ab_name,
|
||||
Tvalue: e.curTakenVal,
|
||||
Ticon: rial.icon,
|
||||
txType: 'sell'
|
||||
})
|
||||
} else if (e.curGivenId.toString() === rial._id.toString() && txType === 'buy') {
|
||||
modifiedResult.push ({
|
||||
GcurrencyName: curObj.currencyName,
|
||||
GpersianName: curObj.per_name,
|
||||
GshortName: curObj.ab_name,
|
||||
Gvalue: e.curTakenVal,
|
||||
Gicon: curObj.icon,
|
||||
acceptedDate: e.created_at,
|
||||
TcurrencyName: rial.currencyName,
|
||||
TpersianName: rial.per_name,
|
||||
TshortName: rial.ab_name,
|
||||
Tvalue: e.curGivenVal,
|
||||
Ticon: rial.icon,
|
||||
txType: 'buy'
|
||||
})
|
||||
} else if (txType === 'all') {
|
||||
if (e.curTakenId.toString() === rial._id.toString()) {
|
||||
modifiedResult.push ({
|
||||
GcurrencyName: curObj.currencyName,
|
||||
GpersianName: curObj.per_name,
|
||||
GshortName: curObj.ab_name,
|
||||
Gvalue: e.curGivenVal,
|
||||
Gicon: curObj.icon,
|
||||
acceptedDate: e.created_at,
|
||||
TcurrencyName: rial.currencyName,
|
||||
TpersianName: rial.per_name,
|
||||
TshortName: rial.ab_name,
|
||||
Tvalue: e.curTakenVal,
|
||||
Ticon: rial.icon,
|
||||
txType: 'sell'
|
||||
})
|
||||
} else if (e.curGivenId.toString() === rial._id.toString()) {
|
||||
modifiedResult.push ({
|
||||
GcurrencyName: curObj.currencyName,
|
||||
GpersianName: curObj.per_name,
|
||||
GshortName: curObj.ab_name,
|
||||
Gvalue: e.curTakenVal,
|
||||
Gicon: curObj.icon,
|
||||
acceptedDate: e.created_at,
|
||||
TcurrencyName: rial.currencyName,
|
||||
TpersianName: rial.per_name,
|
||||
TshortName: rial.ab_name,
|
||||
Tvalue: e.curGivenVal,
|
||||
Ticon: rial.icon,
|
||||
txType: 'buy'
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
return modifiedResult
|
||||
})
|
||||
.catch((err) => {
|
||||
throw err
|
||||
})
|
||||
} else {
|
||||
const resultMap = result.map((e) => {
|
||||
console.log('eeeeeeeee: ', e)
|
||||
if (e.curTakenId.toString() === rial._id.toString() && txType === 'sell') {
|
||||
return redis.hashGetAll(e.curGivenId.toString())
|
||||
.then((curGivenObj: any) => {
|
||||
modifiedResult.push ({
|
||||
GcurrencyName: curGivenObj.currencyName,
|
||||
GpersianName: curGivenObj.per_name,
|
||||
GshortName: curGivenObj.ab_name,
|
||||
Gvalue: e.curGivenVal,
|
||||
Gicon: curGivenObj.icon,
|
||||
acceptedDate: e.created_at,
|
||||
TcurrencyName: rial.currencyName,
|
||||
TpersianName: rial.per_name,
|
||||
TshortName: rial.ab_name,
|
||||
Tvalue: e.curTakenVal,
|
||||
Ticon: rial.icon,
|
||||
txType: 'sell'
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
} else if (e.curGivenId.toString() === rial._id.toString() && txType === 'buy') {
|
||||
return redis.hashGetAll(e.curTakenId.toString())
|
||||
.then((curTakenObj: any) => {
|
||||
modifiedResult.push({
|
||||
GcurrencyName: curTakenObj.currencyName,
|
||||
GpersianName: curTakenObj.per_name,
|
||||
GshortName: curTakenObj.ab_name,
|
||||
Gvalue: e.curTakenVal,
|
||||
Gicon: curTakenObj.icon,
|
||||
acceptedDate: e.created_at,
|
||||
TcurrencyName: rial.currencyName,
|
||||
TpersianName: rial.per_name,
|
||||
TshortName: rial.ab_name,
|
||||
Tvalue: e.curGivenVal,
|
||||
Ticon: rial.icon,
|
||||
txType: 'buy'
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
} else if (txType === 'all') {
|
||||
if (e.curTakenId.toString() === rial._id.toString()) {
|
||||
return redis.hashGetAll(e.curGivenId.toString())
|
||||
.then((curGivenObj: any) => {
|
||||
modifiedResult.push ({
|
||||
GcurrencyName: curGivenObj.currencyName,
|
||||
GpersianName: curGivenObj.per_name,
|
||||
GshortName: curGivenObj.ab_name,
|
||||
Gvalue: e.curGivenVal,
|
||||
Gicon: curGivenObj.icon,
|
||||
acceptedDate: e.created_at,
|
||||
TcurrencyName: rial.currencyName,
|
||||
TpersianName: rial.per_name,
|
||||
TshortName: rial.ab_name,
|
||||
Tvalue: e.curTakenVal,
|
||||
Ticon: rial.icon,
|
||||
txType: 'sell'
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
} else if (e.curGivenId.toString() === rial._id.toString()) {
|
||||
return redis.hashGetAll(e.curTakenId.toString())
|
||||
.then((curTakenObj: any) => {
|
||||
modifiedResult.push ({
|
||||
GcurrencyName: curTakenObj.currencyName,
|
||||
GpersianName: curTakenObj.per_name,
|
||||
GshortName: curTakenObj.ab_name,
|
||||
Gvalue: e.curTakenVal,
|
||||
Gicon: curTakenObj.icon,
|
||||
acceptedDate: e.created_at,
|
||||
TcurrencyName: rial.currencyName,
|
||||
TpersianName: rial.per_name,
|
||||
TshortName: rial.ab_name,
|
||||
Tvalue: e.curGivenVal,
|
||||
Ticon: rial.icon,
|
||||
txType: 'buy'
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
return Promise.all(resultMap)
|
||||
.then(() => {
|
||||
return modifiedResult
|
||||
})
|
||||
.catch((err) => {
|
||||
throw err
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
throw err
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
throw err
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
export const searchOnActiveOffers = ({ offerId, curGivenId, curGivenVal, curTakenId, curTakenVal, expDate, created_at }) => {
|
||||
const itemsMap = new Map()
|
||||
const items = ['offerId', 'curGivenId', 'curGivenVal', 'curTakenId', 'curTakenVal', 'expDate', 'created_at']
|
||||
const definedItems = []
|
||||
itemsMap.set('offerId', offerId)
|
||||
itemsMap.set('curGivenId', curGivenId)
|
||||
itemsMap.set('curGivenVal', curGivenVal)
|
||||
itemsMap.set('curTakenId', curTakenId)
|
||||
itemsMap.set('curTakenVal', curTakenVal)
|
||||
itemsMap.set('expDate', expDate)
|
||||
itemsMap.set('created_at', created_at)
|
||||
|
||||
items.map((element) => {
|
||||
if(itemsMap.get(element)) {
|
||||
if (element === 'expDate') {
|
||||
if(expDate.from || expDate.to) {
|
||||
definedItems.push(element)
|
||||
}
|
||||
} else if (element === 'created_at') {
|
||||
if(created_at.from || created_at.to) {
|
||||
definedItems.push(element)
|
||||
}
|
||||
} else if (element === 'curGivenVal') {
|
||||
if(curGivenVal.from || curGivenVal.to) {
|
||||
definedItems.push(element)
|
||||
}
|
||||
} else if (element === 'curTakenVal') {
|
||||
if(curTakenVal.from || curTakenVal.to) {
|
||||
definedItems.push(element)
|
||||
}
|
||||
} else {
|
||||
definedItems.push(element)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
let query = [ { expDate: { $gt: Date.now() } } ]
|
||||
let queryMap = new Map()
|
||||
let queryExpDate
|
||||
let queryCreatedAt
|
||||
let queryCurGivenVal
|
||||
let queryCurTakenVal
|
||||
|
||||
if (definedItems.includes('expDate')) {
|
||||
if (expDate.from && expDate.to) {
|
||||
queryExpDate = { expDate: { $gt: expDate.from, $lt: expDate.to } }
|
||||
} else if (expDate.from && !expDate.to) {
|
||||
queryExpDate = { expDate: { $gt: expDate.from } }
|
||||
} else if (!expDate.from && expDate.to) {
|
||||
queryExpDate = { expDate: { $lt: expDate.to } }
|
||||
}
|
||||
}
|
||||
if (definedItems.includes('created_at')) {
|
||||
if (created_at.from && created_at.to) {
|
||||
queryCreatedAt = { created_at: { $gt: created_at.from, $lt: created_at.to } }
|
||||
} else if (created_at.from && !created_at.to) {
|
||||
queryCreatedAt = { created_at: { $gt: created_at.from } }
|
||||
} else if (!created_at.from && created_at.to) {
|
||||
queryCreatedAt = { created_at: { $lt: created_at.to } }
|
||||
}
|
||||
}
|
||||
if (definedItems.includes('curGivenVal')) {
|
||||
if (curGivenVal.from && curGivenVal.to) {
|
||||
queryCurGivenVal = { curGivenVal: { $gte: curGivenVal.from, $lte: curGivenVal.to } }
|
||||
} else if (curGivenVal.from && !curGivenVal.to) {
|
||||
queryCurGivenVal = { curGivenVal: { $gte: curGivenVal.from } }
|
||||
} else if (!curGivenVal.from && curGivenVal.to) {
|
||||
queryCurGivenVal = { curGivenVal: { $lte: curGivenVal.to } }
|
||||
}
|
||||
}
|
||||
if (definedItems.includes('curTakenVal')) {
|
||||
if (curTakenVal.from && curTakenVal.to) {
|
||||
queryCurTakenVal = { curTakenVal: { $gte: curTakenVal.from, $lte: curTakenVal.to } }
|
||||
} else if (curTakenVal.from && !curTakenVal.to) {
|
||||
queryCurTakenVal = { curTakenVal: { $gte: curTakenVal.from } }
|
||||
} else if (!curTakenVal.from && curTakenVal.to) {
|
||||
queryCurTakenVal = { curTakenVal: { $lte: curTakenVal.to } }
|
||||
}
|
||||
}
|
||||
|
||||
queryMap.set('offerId', { offerId: offerId })
|
||||
queryMap.set('curGivenId', { curGivenId: curGivenId })
|
||||
queryMap.set('curGivenVal', queryCurGivenVal)
|
||||
queryMap.set('curTakenId', { curTakenId: curTakenId })
|
||||
queryMap.set('curTakenVal', queryCurTakenVal)
|
||||
queryMap.set('expDate', queryExpDate)
|
||||
queryMap.set('created_at', queryCreatedAt)
|
||||
const definedItemsMap = definedItems.map((element) => {
|
||||
query.push(queryMap.get(element))
|
||||
})
|
||||
|
||||
return Promise.all(definedItemsMap)
|
||||
.then(() => {
|
||||
return Active_Offers.find({ $and: query })
|
||||
.then((result) => {
|
||||
return result
|
||||
})
|
||||
.catch((err) => {
|
||||
throw err
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
throw err
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
116
server/api/redis.js
Executable file
116
server/api/redis.js
Executable file
@@ -0,0 +1,116 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.getCurrentPrice = exports.hashSetMembers = exports.hashHMset = exports.hashGetAll = exports.hashset = exports.hashget = exports.globalRedisClient = void 0;
|
||||
var redis = require("redis");
|
||||
var myError_1 = require("./myError");
|
||||
exports.globalRedisClient = redis.createClient({
|
||||
port: process.env.REDIS_PORT,
|
||||
host: process.env.REDIS_HOST,
|
||||
enable_offline_queue: false
|
||||
});
|
||||
// globalRedisClient.auth(process.env.REDIS_PASS, (err) => {
|
||||
// if (err) console.log(err);
|
||||
// })
|
||||
exports.globalRedisClient.on('connect', function (err) {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
else {
|
||||
console.log('Redis-server is connected');
|
||||
}
|
||||
});
|
||||
exports.globalRedisClient.on('error', function (err) {
|
||||
console.log('Error ' + err);
|
||||
});
|
||||
exports.hashget = function (tag) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
exports.globalRedisClient.get(tag, function (err, reply) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
else {
|
||||
resolve(reply);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
exports.hashset = function (tag, val) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
exports.globalRedisClient.set(tag, val, function (err, reply) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
else {
|
||||
resolve(reply);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
exports.hashGetAll = function (tag) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
exports.globalRedisClient.hgetall(tag, function (err, reply) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
else {
|
||||
resolve(reply);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
exports.hashHMset = function (tag, val) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
exports.globalRedisClient.hmset(tag, val, function (err, reply) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
else {
|
||||
resolve(reply);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
exports.hashSetMembers = function (tag) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
exports.globalRedisClient.smembers(tag, function (err, reply) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
else {
|
||||
resolve(reply);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
function getCurrentPrice(currency) {
|
||||
//API for getting current currency price
|
||||
return exports.hashGetAll(currency.toString())
|
||||
.then(function (currencyInfo) {
|
||||
return exports.hashGetAll(currencyInfo.ab_name.toString() + "-g")
|
||||
.then(function (currencyInstantPrice) {
|
||||
if (currencyInstantPrice) {
|
||||
return exports.hashget("dollarPrice")
|
||||
.then(function (rialPrice) {
|
||||
if (rialPrice) {
|
||||
return Number(currencyInstantPrice.current) * Number(rialPrice);
|
||||
}
|
||||
else {
|
||||
var error = new myError_1["default"]('It is not possible to get price currently!', 400, 11, 'امکان قیمت گیری در حال حاضر وجود ندارد!', 'خطا رخ داد');
|
||||
throw error;
|
||||
}
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
else {
|
||||
var error = new myError_1["default"]('It is not possible to get price currently!', 400, 11, 'امکان قیمت گیری در حال حاضر وجود ندارد!', 'خطا رخ داد');
|
||||
throw error;
|
||||
}
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
exports.getCurrentPrice = getCurrentPrice;
|
||||
127
server/api/redis.ts
Executable file
127
server/api/redis.ts
Executable file
@@ -0,0 +1,127 @@
|
||||
import * as redis from 'redis'
|
||||
import myError from './myError'
|
||||
export const globalRedisClient = redis.createClient({
|
||||
port: process.env.REDIS_PORT,
|
||||
host: process.env.REDIS_HOST,
|
||||
enable_offline_queue: false
|
||||
})
|
||||
// globalRedisClient.auth(process.env.REDIS_PASS, (err) => {
|
||||
// if (err) console.log(err);
|
||||
// })
|
||||
globalRedisClient.on('connect', function (err) {
|
||||
if(err) {
|
||||
console.log(err)
|
||||
} else {
|
||||
console.log('Redis-server is connected')
|
||||
}
|
||||
})
|
||||
|
||||
globalRedisClient.on('error', function (err) {
|
||||
console.log('Error ' + err)
|
||||
})
|
||||
|
||||
export const hashget = (tag) => { // It is corresponded to hashset
|
||||
return new Promise((resolve, reject) => {
|
||||
globalRedisClient.get(tag, (err, reply) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
} else {
|
||||
resolve(reply)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export const hashset = (tag, val) => { // value could be only a string
|
||||
return new Promise((resolve, reject) => {
|
||||
globalRedisClient.set(tag, val, (err, reply) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
} else {
|
||||
resolve(reply)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export const hashGetAll = (tag) => { // It is corresponded to hashHMset
|
||||
return new Promise((resolve, reject) => {
|
||||
globalRedisClient.hgetall(tag, (err, reply) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
} else {
|
||||
resolve(reply)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export const hashHMset = (tag, val) => { // value could be object!
|
||||
return new Promise((resolve, reject) => {
|
||||
globalRedisClient.hmset(tag, val, (err, reply) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
} else {
|
||||
resolve(reply)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export const hashSetMembers = (tag) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
globalRedisClient.smembers(tag, (err, reply) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
} else {
|
||||
resolve(reply)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export function getCurrentPrice(currency){
|
||||
//API for getting current currency price
|
||||
return hashGetAll(currency.toString())
|
||||
.then((currencyInfo: any) => {
|
||||
return hashGetAll(currencyInfo.ab_name.toString() + "-g")
|
||||
.then((currencyInstantPrice: any) => {
|
||||
if(currencyInstantPrice) {
|
||||
return hashget("dollarPrice")
|
||||
.then((rialPrice) => {
|
||||
if(rialPrice) {
|
||||
return Number(currencyInstantPrice.current) * Number(rialPrice)
|
||||
} else {
|
||||
const error = new myError(
|
||||
'It is not possible to get price currently!',
|
||||
400,
|
||||
11,
|
||||
'امکان قیمت گیری در حال حاضر وجود ندارد!',
|
||||
'خطا رخ داد'
|
||||
)
|
||||
throw error
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
throw err
|
||||
})
|
||||
} else {
|
||||
const error = new myError(
|
||||
'It is not possible to get price currently!',
|
||||
400,
|
||||
11,
|
||||
'امکان قیمت گیری در حال حاضر وجود ندارد!',
|
||||
'خطا رخ داد'
|
||||
)
|
||||
throw error
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
throw err
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
throw err
|
||||
})
|
||||
}
|
||||
|
||||
52
server/api/socket.js
Executable file
52
server/api/socket.js
Executable file
@@ -0,0 +1,52 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.getonlineNotLoginUsers = exports.getonlineLoginUsers = exports.startIo = void 0;
|
||||
// import * as scocketIo from 'socket.io'
|
||||
var scocketIo = require('socket.io');
|
||||
var redis = require("redis");
|
||||
var client = redis.createClient();
|
||||
var logger_1 = require("./logger");
|
||||
var onlineLoginUsers = null;
|
||||
var onlineNotLoginUsers = null;
|
||||
var socketConnection = function socketConnection(socket) {
|
||||
logger_1.logger.info("Client connected [id=" + socket.id + "]");
|
||||
};
|
||||
var socketDisconnection = function socketDisconnection(socket) {
|
||||
logger_1.logger.info("Client gone [id=" + socket.id + "]");
|
||||
};
|
||||
exports.startIo = function (server) {
|
||||
var io = scocketIo(server, {
|
||||
serveClient: false,
|
||||
cors: {
|
||||
origin: '*'
|
||||
}
|
||||
});
|
||||
io.on('connection', socketConnection);
|
||||
io.on('disconnect', socketDisconnection);
|
||||
onlineLoginUsers = io.of('/onlineLoginUsers');
|
||||
onlineNotLoginUsers = io.of('/onlineNotLoginUsers');
|
||||
onlineLoginUsers.on('connection', function (socket) {
|
||||
logger_1.logger.info("Client connected [id=" + socket.id + "]");
|
||||
console.log('socket.handshake', socket.handshake.session);
|
||||
if (socket.handshake.session.userId) {
|
||||
client.sadd(socket.handshake.session.userId, socket.id, function (err, reply) {
|
||||
if (err)
|
||||
logger_1.logger.warn(err);
|
||||
});
|
||||
logger_1.logger.info("A logged in client connected in :" + socket.id);
|
||||
socket.on('disconnect', function () {
|
||||
logger_1.logger.info("Client gone [id=" + socket.id + "]");
|
||||
client.srem(socket.handshake.session.userId, socket.id, function (err, reply) {
|
||||
logger_1.logger.info("socket with id " + socket.id + " is closed!");
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
return io;
|
||||
};
|
||||
exports.getonlineLoginUsers = function () {
|
||||
return onlineLoginUsers;
|
||||
};
|
||||
exports.getonlineNotLoginUsers = function () {
|
||||
return onlineNotLoginUsers;
|
||||
};
|
||||
55
server/api/socket.ts
Executable file
55
server/api/socket.ts
Executable file
@@ -0,0 +1,55 @@
|
||||
// import * as scocketIo from 'socket.io'
|
||||
const scocketIo = require('socket.io')
|
||||
import * as redis from 'redis'
|
||||
var client = redis.createClient()
|
||||
import { logger } from './logger'
|
||||
|
||||
let onlineLoginUsers = null
|
||||
let onlineNotLoginUsers = null
|
||||
|
||||
var socketConnection = function socketConnection (socket) {
|
||||
logger.info(`Client connected [id=${socket.id}]`)
|
||||
}
|
||||
|
||||
var socketDisconnection = function socketDisconnection (socket) {
|
||||
logger.info(`Client gone [id=${socket.id}]`)
|
||||
}
|
||||
export const startIo = (server) => {
|
||||
const io = scocketIo(server, {
|
||||
serveClient: false,
|
||||
cors: {
|
||||
origin: '*',
|
||||
}
|
||||
})
|
||||
io.on('connection', socketConnection)
|
||||
io.on('disconnect', socketDisconnection)
|
||||
onlineLoginUsers = io.of('/onlineLoginUsers')
|
||||
onlineNotLoginUsers = io.of('/onlineNotLoginUsers')
|
||||
onlineLoginUsers.on('connection', function (socket) {
|
||||
logger.info(`Client connected [id=${socket.id}]`)
|
||||
console.log('socket.handshake', socket.handshake.session)
|
||||
if (socket.handshake.session.userId) {
|
||||
client.sadd(socket.handshake.session.userId, socket.id, (err, reply) => {
|
||||
if (err) logger.warn(err)
|
||||
})
|
||||
logger.info(`A logged in client connected in :${socket.id}`)
|
||||
socket.on('disconnect', () => {
|
||||
logger.info(`Client gone [id=${socket.id}]`)
|
||||
client.srem(socket.handshake.session.userId, socket.id, (err, reply) => {
|
||||
logger.info(`socket with id ${socket.id} is closed!`)
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
return io
|
||||
}
|
||||
|
||||
export const getonlineLoginUsers = () => {
|
||||
return onlineLoginUsers
|
||||
}
|
||||
|
||||
export const getonlineNotLoginUsers = () => {
|
||||
return onlineNotLoginUsers
|
||||
}
|
||||
|
||||
|
||||
190
server/api/suggestOffers.js
Executable file
190
server/api/suggestOffers.js
Executable file
@@ -0,0 +1,190 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.prepForKS = exports.knapsack = exports.suggestOffers = exports.normalizing = void 0;
|
||||
var moment = require('moment-timezone');
|
||||
var math = require('mathjs');
|
||||
var ActiveOffers_1 = require("../db/ActiveOffers");
|
||||
function normalizing(arr, asc) {
|
||||
var mArr = math.matrix(arr);
|
||||
var min = math.min(mArr).valueOf();
|
||||
var max = math.max(mArr).valueOf();
|
||||
var nArr = mArr;
|
||||
var i;
|
||||
if (max == min) {
|
||||
for (i = 0; i < math.size(mArr).get([0]); i++) {
|
||||
nArr = math.subset(nArr, math.index(i), max);
|
||||
}
|
||||
return nArr.valueOf();
|
||||
}
|
||||
if (asc) {
|
||||
for (i = 0; i < math.size(mArr).get([0]); i++) {
|
||||
nArr = math.subset(nArr, math.index(i), (((mArr.get([i]) - min) / (max - min)) + 1));
|
||||
}
|
||||
return nArr.valueOf();
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < math.size(mArr).get([0]); i++) {
|
||||
nArr = math.subset(nArr, math.index(i), 2 - (((mArr.get([i]) - min) / (max - min))));
|
||||
}
|
||||
return nArr.valueOf();
|
||||
}
|
||||
}
|
||||
exports.normalizing = normalizing;
|
||||
function suggestOffers(_a) {
|
||||
var userId = _a.userId, price = _a.price, capacity = _a.capacity, offerType = _a.offerType, currencyId = _a.currencyId, rialId = _a.rialId;
|
||||
if (offerType == 'buy') {
|
||||
// get all offers except the user's offers
|
||||
var maxPrice = price + 0.05 * price;
|
||||
return ActiveOffers_1.Active_Offers.find({ $and: [
|
||||
{ userId: { $ne: userId } },
|
||||
{ expDate: { $gt: Date.now() } },
|
||||
{ curTakenId: currencyId },
|
||||
{ curGivenId: rialId },
|
||||
{ curGivenVal: { $lt: maxPrice } }
|
||||
]
|
||||
})
|
||||
.then(function (offers) {
|
||||
if (offers && Array.isArray(offers) && offers.length > 0) {
|
||||
var offerIds_1 = [];
|
||||
var offerFeatures = [];
|
||||
var prices_1 = [];
|
||||
var values_1 = [];
|
||||
var expDate_1 = [];
|
||||
offers.forEach(function (off) {
|
||||
offerIds_1.push(off._id.toString());
|
||||
prices_1.push(off.curGivenVal);
|
||||
values_1.push(off.curTakenVal);
|
||||
expDate_1.push(Math.round((moment(off.expDate) - moment()) / 60000));
|
||||
});
|
||||
prices_1 = normalizing(prices_1, false);
|
||||
expDate_1 = normalizing(expDate_1, false);
|
||||
var weights = values_1;
|
||||
offerFeatures = math.concat(math.concat(math.reshape(math.matrix(prices_1), [prices_1.length, 1]), math.reshape(math.matrix(values_1), [values_1.length, 1]), 1), math.reshape(math.matrix(expDate_1), [expDate_1.length, 1]), 1).valueOf();
|
||||
var coefs = [[0.3], [0.2], [0.5]];
|
||||
var data = prepForKS(offerIds_1, offerFeatures, weights, coefs);
|
||||
var sugOffers = knapsack(data, capacity);
|
||||
return sugOffers;
|
||||
}
|
||||
else {
|
||||
console.log("There is no offer to suggest");
|
||||
}
|
||||
})["catch"](function (err) {
|
||||
console.log("Error in middlewares/suggestOffers.ts : ", err);
|
||||
});
|
||||
}
|
||||
else {
|
||||
if (offerType == 'sell') {
|
||||
// get all offers except the user's offers
|
||||
var maxPrice = price + 0.05 * price;
|
||||
ActiveOffers_1.Active_Offers.find({ $and: [
|
||||
{ userId: { $ne: userId } },
|
||||
{ expDate: { $gt: Date.now() } },
|
||||
{ curGivenId: currencyId },
|
||||
{ curTakenId: rialId },
|
||||
{ curTakenVal: { $lt: maxPrice } }
|
||||
]
|
||||
})
|
||||
.then(function (offers) {
|
||||
if (offers && Array.isArray(offers) && offers.length > 0) {
|
||||
var offerIds_2 = [];
|
||||
var offerFeatures = [];
|
||||
var prices_2 = [];
|
||||
var values_2 = [];
|
||||
var expDate_2 = [];
|
||||
offers.forEach(function (off) {
|
||||
offerIds_2.push(off._id.toString());
|
||||
prices_2.push(off.curTakenVal);
|
||||
values_2.push(off.curGivenVal);
|
||||
expDate_2.push(Math.round((moment(off.expDate) - moment()) / 60000));
|
||||
});
|
||||
prices_2 = normalizing(prices_2, true);
|
||||
expDate_2 = normalizing(expDate_2, false);
|
||||
var weights = values_2;
|
||||
offerFeatures = math.concat(math.concat(math.reshape(math.matrix(prices_2), [prices_2.length, 1]), math.reshape(math.matrix(values_2), [values_2.length, 1]), 1), math.reshape(math.matrix(expDate_2), [expDate_2.length, 1]), 1).valueOf();
|
||||
var coefs = [[0.3], [0.2], [0.5]];
|
||||
var data = prepForKS(offerIds_2, offerFeatures, weights, coefs);
|
||||
var sugOffers = knapsack(data, capacity);
|
||||
return sugOffers;
|
||||
}
|
||||
else {
|
||||
console.log("There is no offer to suggest");
|
||||
}
|
||||
})["catch"](function (err) {
|
||||
console.log("Error in middlewares/suggestOffers.ts : ", err);
|
||||
});
|
||||
}
|
||||
else {
|
||||
console.log("offerType must be buy or sell");
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.suggestOffers = suggestOffers;
|
||||
function knapsack(items, capacity) {
|
||||
// This implementation uses dynamic programming.
|
||||
// Variable 'memo' is a grid(2-dimentional array) to store optimal solution for sub-problems,
|
||||
// which will be later used as the code execution goes on.
|
||||
// This is called memoization in programming.
|
||||
// The cell will store best solution objects for different capacities and selectable items.
|
||||
var memo = [];
|
||||
// Filling the sub-problem solutions grid.
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
// Variable 'cap' is the capacity for sub-problems. In this example, 'cap' ranges from 1 to 6.
|
||||
var row = [];
|
||||
for (var cap = 1; cap <= capacity; cap++) {
|
||||
row.push(getSolution(i, cap));
|
||||
}
|
||||
memo.push(row);
|
||||
}
|
||||
// The right-bottom-corner cell of the grid contains the final solution for the whole problem.
|
||||
return (getLast());
|
||||
function getLast() {
|
||||
var lastRow = memo[memo.length - 1];
|
||||
return lastRow[lastRow.length - 1];
|
||||
}
|
||||
function getSolution(row, cap) {
|
||||
var NO_SOLUTION = { maxValue: 0, subset: [] };
|
||||
// the column number starts from zero.
|
||||
var col = cap - 1;
|
||||
var lastItem = items[row];
|
||||
// The remaining capacity for the sub-problem to solve.
|
||||
var remaining = cap - lastItem.w;
|
||||
// Refer to the last solution for this capacity,
|
||||
// which is in the cell of the previous row with the same column
|
||||
var lastSolution = row > 0 ? memo[row - 1][col] || NO_SOLUTION : NO_SOLUTION;
|
||||
// Refer to the last solution for the remaining capacity,
|
||||
// which is in the cell of the previous row with the corresponding column
|
||||
var lastSubSolution = row > 0 ? memo[row - 1][remaining - 1] || NO_SOLUTION : NO_SOLUTION;
|
||||
// If any one of the items weights greater than the 'cap', return the last solution
|
||||
if (remaining < 0) {
|
||||
return lastSolution;
|
||||
}
|
||||
// Compare the current best solution for the sub-problem with a specific capacity
|
||||
// to a new solution trial with the lastItem(new item) added
|
||||
var lastValue = lastSolution.maxValue;
|
||||
var lastSubValue = lastSubSolution.maxValue;
|
||||
var newValue = lastSubValue + lastItem.v;
|
||||
if (newValue >= lastValue) {
|
||||
// copy the subset of the last sub-problem solution
|
||||
var _lastSubSet = lastSubSolution.subset.slice();
|
||||
_lastSubSet.push(lastItem);
|
||||
return { maxValue: newValue, subset: _lastSubSet };
|
||||
}
|
||||
else {
|
||||
return lastSolution;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.knapsack = knapsack;
|
||||
function prepForKS(offerIds, offerFeatures, weights, coefs) {
|
||||
var values = math.multiply(math.matrix(offerFeatures), math.matrix(coefs));
|
||||
var data = math.concat(math.concat(math.reshape(math.matrix(offerIds), [offerIds.length, 1]), values, 1), math.reshape(math.matrix(weights), [weights.length, 1]), 1).valueOf();
|
||||
var dataObj = Object.values(data.reduce(function (c, _a) {
|
||||
var n = _a[0], v = _a[1], w = _a[2];
|
||||
c[n] = c[n] || { id: n, v: v, w: w };
|
||||
c[n].v = v;
|
||||
c[n].w = w;
|
||||
return c;
|
||||
}, {}));
|
||||
return dataObj;
|
||||
}
|
||||
exports.prepForKS = prepForKS;
|
||||
201
server/api/suggestOffers.ts
Executable file
201
server/api/suggestOffers.ts
Executable file
@@ -0,0 +1,201 @@
|
||||
const moment = require( 'moment-timezone')
|
||||
const math = require('mathjs');
|
||||
|
||||
import { Active_Offers } from '../db/ActiveOffers';
|
||||
|
||||
export function normalizing(arr, asc) {
|
||||
|
||||
let mArr = math.matrix(arr)
|
||||
const min = math.min(mArr).valueOf()
|
||||
const max = math.max(mArr).valueOf()
|
||||
let nArr = mArr
|
||||
let i
|
||||
if(max == min){
|
||||
for(i=0; i < math.size(mArr).get([0]);i++) {
|
||||
nArr = math.subset(nArr, math.index(i), max )
|
||||
}
|
||||
return nArr.valueOf()
|
||||
}
|
||||
if(asc) {
|
||||
for(i=0; i < math.size(mArr).get([0]);i++) {
|
||||
nArr = math.subset(nArr, math.index(i), (((mArr.get([i]) - min)/(max - min)) + 1))
|
||||
}
|
||||
return nArr.valueOf()
|
||||
} else {
|
||||
for(i=0; i < math.size(mArr).get([0]); i++) {
|
||||
nArr = math.subset(nArr, math.index(i), 2 - (((mArr.get([i]) - min)/(max - min))))
|
||||
}
|
||||
return nArr.valueOf()
|
||||
}
|
||||
}
|
||||
|
||||
export function suggestOffers({ userId, price, capacity, offerType, currencyId, rialId }) {
|
||||
if(offerType == 'buy') {
|
||||
// get all offers except the user's offers
|
||||
let maxPrice = price + 0.05*price
|
||||
return Active_Offers.find({ $and:
|
||||
[
|
||||
{ userId :{ $ne: userId} },
|
||||
{ expDate: { $gt: Date.now() } },
|
||||
{ curTakenId: currencyId },
|
||||
{ curGivenId: rialId },
|
||||
{ curGivenVal: { $lt: maxPrice }}
|
||||
]
|
||||
})
|
||||
.then((offers) => {
|
||||
if(offers && Array.isArray(offers) && offers.length > 0) {
|
||||
let offerIds = []
|
||||
let offerFeatures = []
|
||||
let prices = []
|
||||
let values = []
|
||||
let expDate = []
|
||||
offers.forEach(off => {
|
||||
offerIds.push(off._id.toString())
|
||||
prices.push(off.curGivenVal)
|
||||
values.push(off.curTakenVal)
|
||||
expDate.push(Math.round((moment(off.expDate) - moment())/60000))
|
||||
})
|
||||
prices = normalizing(prices, false)
|
||||
expDate = normalizing(expDate, false)
|
||||
let weights = values
|
||||
|
||||
offerFeatures = math.concat(math.concat(math.reshape(math.matrix(prices), [prices.length, 1]),
|
||||
math.reshape(math.matrix(values), [values.length, 1]), 1),
|
||||
math.reshape(math.matrix(expDate), [expDate.length, 1]), 1).valueOf()
|
||||
let coefs = [[0.3], [0.2], [0.5]]
|
||||
let data = prepForKS(offerIds, offerFeatures, weights, coefs)
|
||||
let sugOffers = knapsack(data, capacity)
|
||||
return sugOffers
|
||||
} else {
|
||||
console.log("There is no offer to suggest")
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("Error in middlewares/suggestOffers.ts : ", err)
|
||||
})
|
||||
} else {
|
||||
if(offerType == 'sell') {
|
||||
// get all offers except the user's offers
|
||||
let maxPrice = price + 0.05*price
|
||||
Active_Offers.find({ $and:
|
||||
[
|
||||
{ userId :{ $ne: userId} },
|
||||
{ expDate: { $gt: Date.now() } },
|
||||
{ curGivenId: currencyId },
|
||||
{ curTakenId: rialId },
|
||||
{ curTakenVal: { $lt: maxPrice }}
|
||||
]
|
||||
})
|
||||
.then((offers) => {
|
||||
if(offers && Array.isArray(offers) && offers.length > 0) {
|
||||
let offerIds = []
|
||||
let offerFeatures = []
|
||||
let prices = []
|
||||
let values = []
|
||||
let expDate = []
|
||||
offers.forEach(off => {
|
||||
offerIds.push(off._id.toString())
|
||||
prices.push(off.curTakenVal)
|
||||
values.push(off.curGivenVal)
|
||||
expDate.push(Math.round((moment(off.expDate) - moment())/60000))
|
||||
})
|
||||
prices = normalizing(prices, true)
|
||||
expDate = normalizing(expDate, false)
|
||||
let weights = values
|
||||
|
||||
offerFeatures = math.concat(math.concat(math.reshape(math.matrix(prices), [prices.length, 1]),
|
||||
math.reshape(math.matrix(values), [values.length, 1]), 1),
|
||||
math.reshape(math.matrix(expDate), [expDate.length, 1]), 1).valueOf()
|
||||
let coefs = [[0.3], [0.2], [0.5]]
|
||||
let data = prepForKS(offerIds, offerFeatures, weights, coefs)
|
||||
let sugOffers = knapsack(data, capacity)
|
||||
return sugOffers
|
||||
} else {
|
||||
console.log("There is no offer to suggest")
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("Error in middlewares/suggestOffers.ts : ", err)
|
||||
})
|
||||
} else {
|
||||
console.log("offerType must be buy or sell")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function knapsack(items, capacity) {
|
||||
// This implementation uses dynamic programming.
|
||||
// Variable 'memo' is a grid(2-dimentional array) to store optimal solution for sub-problems,
|
||||
// which will be later used as the code execution goes on.
|
||||
// This is called memoization in programming.
|
||||
// The cell will store best solution objects for different capacities and selectable items.
|
||||
var memo = [];
|
||||
|
||||
// Filling the sub-problem solutions grid.
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
// Variable 'cap' is the capacity for sub-problems. In this example, 'cap' ranges from 1 to 6.
|
||||
var row = [];
|
||||
for (var cap = 1; cap <= capacity; cap++) {
|
||||
row.push(getSolution(i,cap));
|
||||
}
|
||||
memo.push(row);
|
||||
}
|
||||
|
||||
// The right-bottom-corner cell of the grid contains the final solution for the whole problem.
|
||||
return(getLast());
|
||||
|
||||
function getLast(){
|
||||
var lastRow = memo[memo.length - 1];
|
||||
return lastRow[lastRow.length - 1];
|
||||
}
|
||||
|
||||
function getSolution(row,cap){
|
||||
const NO_SOLUTION = {maxValue:0, subset:[]};
|
||||
// the column number starts from zero.
|
||||
var col = cap - 1;
|
||||
var lastItem = items[row];
|
||||
// The remaining capacity for the sub-problem to solve.
|
||||
var remaining = cap - lastItem.w;
|
||||
|
||||
// Refer to the last solution for this capacity,
|
||||
// which is in the cell of the previous row with the same column
|
||||
var lastSolution = row > 0 ? memo[row - 1][col] || NO_SOLUTION : NO_SOLUTION;
|
||||
// Refer to the last solution for the remaining capacity,
|
||||
// which is in the cell of the previous row with the corresponding column
|
||||
var lastSubSolution = row > 0 ? memo[row - 1][remaining - 1] || NO_SOLUTION : NO_SOLUTION;
|
||||
|
||||
// If any one of the items weights greater than the 'cap', return the last solution
|
||||
if(remaining < 0){
|
||||
return lastSolution;
|
||||
}
|
||||
|
||||
// Compare the current best solution for the sub-problem with a specific capacity
|
||||
// to a new solution trial with the lastItem(new item) added
|
||||
var lastValue = lastSolution.maxValue;
|
||||
var lastSubValue = lastSubSolution.maxValue;
|
||||
|
||||
var newValue = lastSubValue + lastItem.v;
|
||||
if(newValue >= lastValue) {
|
||||
// copy the subset of the last sub-problem solution
|
||||
var _lastSubSet = lastSubSolution.subset.slice();
|
||||
_lastSubSet.push(lastItem);
|
||||
return {maxValue: newValue, subset:_lastSubSet};
|
||||
} else {
|
||||
return lastSolution;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function prepForKS(offerIds, offerFeatures, weights, coefs) {
|
||||
|
||||
let values = math.multiply(math.matrix(offerFeatures), math.matrix(coefs))
|
||||
let data = math.concat(math.concat(math.reshape(math.matrix(offerIds), [offerIds.length, 1]), values, 1),
|
||||
math.reshape(math.matrix(weights), [weights.length, 1]), 1).valueOf()
|
||||
let dataObj = Object.values(data.reduce((c, [n, v, w]) => {
|
||||
c[n] = c[n] || {id: n, v, w};
|
||||
c[n].v = v
|
||||
c[n].w = w
|
||||
return c;
|
||||
}, {}));
|
||||
return dataObj
|
||||
}
|
||||
153
server/api/walletApi/bitcoin.js
Executable file
153
server/api/walletApi/bitcoin.js
Executable file
@@ -0,0 +1,153 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
exports.__esModule = true;
|
||||
exports.bitcoinTransferToExchangeById = exports.bitcoinTransferFromExchange = void 0;
|
||||
var Client = require('bitcoin-core');
|
||||
var myError_1 = require("../myError");
|
||||
var _ = require("lodash");
|
||||
exports.bitcoinTransferFromExchange = function (value, receiver) { return __awaiter(void 0, void 0, void 0, function () {
|
||||
var client, query_options;
|
||||
return __generator(this, function (_a) {
|
||||
client = new Client({
|
||||
network: 'testnet',
|
||||
username: 'polychain',
|
||||
password: '3QtnxrB7P5y4EpBdad1MkCeB2RHmArvcarw7udgXsAce',
|
||||
host: "127.0.0.1",
|
||||
port: 8332
|
||||
});
|
||||
query_options = {
|
||||
"minimumAmount": value,
|
||||
//"maximumAmount":value,
|
||||
"maximumCount": 1
|
||||
};
|
||||
return [2 /*return*/, client.listUnspent(0, 9999999, [], true, query_options)
|
||||
.then(function (unspentTx) {
|
||||
if (unspentTx[0]) {
|
||||
var txid = unspentTx[0].txid;
|
||||
var vout = unspentTx[0].vout;
|
||||
var txValue = unspentTx[0].amount;
|
||||
var txFee = value * (0.001);
|
||||
var StxFee = txFee.toFixed(8);
|
||||
var totalValue = Number(value) + Number(StxFee);
|
||||
var change = txValue - totalValue;
|
||||
var Schange = change.toFixed(8);
|
||||
var nodeAddress = unspentTx[0].address;
|
||||
var input = [{
|
||||
"txid": txid,
|
||||
"vout": vout
|
||||
}];
|
||||
var output = [];
|
||||
var obj = {};
|
||||
var obj_2 = {};
|
||||
obj[receiver] = value;
|
||||
obj_2[nodeAddress] = Schange;
|
||||
output.push(obj, obj_2);
|
||||
return client.createRawTransaction(input, output)
|
||||
.then(function (txHex) {
|
||||
return client.signRawTransactionWithWallet(txHex)
|
||||
.then(function (sinedHex) {
|
||||
return client.sendRawTransaction(sinedHex.hex)
|
||||
.then(function (txHashOrId) {
|
||||
return txHashOrId;
|
||||
})["catch"](function (err) {
|
||||
console.log("error in sendsigned", err);
|
||||
throw err;
|
||||
});
|
||||
})["catch"](function (err) {
|
||||
console.log("error in sign ", err);
|
||||
throw err;
|
||||
});
|
||||
})["catch"](function (err) {
|
||||
console.log("error in create raw tx", err);
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
else {
|
||||
var error = new myError_1["default"]('you do not have unspent trancaction', 400, 5, 'تراکنش خرج نشده پیدا نشد', 'خطا رخ داد');
|
||||
throw error;
|
||||
}
|
||||
})["catch"](function (err) {
|
||||
console.log("error in lisutxo", err);
|
||||
throw err;
|
||||
})];
|
||||
});
|
||||
}); };
|
||||
exports.bitcoinTransferToExchangeById = function (txId) { return __awaiter(void 0, void 0, void 0, function () {
|
||||
var btcAddress, client;
|
||||
return __generator(this, function (_a) {
|
||||
btcAddress = ["tb1qfpf6lss60wmle9wanetjxjjt6lc6z65mapk50s"];
|
||||
client = new Client({
|
||||
network: 'testnet',
|
||||
username: 'polychain',
|
||||
password: '3QtnxrB7P5y4EpBdad1MkCeB2RHmArvcarw7udgXsAce',
|
||||
host: "127.0.0.1",
|
||||
port: 8332
|
||||
});
|
||||
return [2 /*return*/, client.getTransaction(txId)
|
||||
.then(function (txInfo) {
|
||||
if (txInfo) {
|
||||
var tx = _.find(txInfo.details, function (i) { return i.category.toString() === "receive" && btcAddress.includes(i.address.toString()); });
|
||||
if (tx) {
|
||||
var status_1;
|
||||
if (txInfo.confirmations >= 6) {
|
||||
status_1 = "Confirmed";
|
||||
}
|
||||
else {
|
||||
status_1 = "pending";
|
||||
}
|
||||
var info = {
|
||||
"txAddress": tx.address,
|
||||
"txAmount": tx.amount,
|
||||
"status": status_1
|
||||
};
|
||||
return info;
|
||||
}
|
||||
else {
|
||||
var error = new myError_1["default"]('tx not found', 400, 5, 'تراکنش یافت نشد', 'خطا رخ داد');
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
else {
|
||||
var error = new myError_1["default"]('transaction not found', 400, 5, 'تراکنش مربوطه پیدا نشد.', 'خطا رخ داد');
|
||||
throw error;
|
||||
}
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
})];
|
||||
});
|
||||
}); };
|
||||
132
server/api/walletApi/bitcoin.ts
Executable file
132
server/api/walletApi/bitcoin.ts
Executable file
@@ -0,0 +1,132 @@
|
||||
const Client = require('bitcoin-core')
|
||||
import myError from '../myError'
|
||||
import * as _ from 'lodash'
|
||||
|
||||
export const bitcoinTransferFromExchange = async(value, receiver) => {
|
||||
const client = new Client({
|
||||
network: 'testnet',
|
||||
username: 'polychain',
|
||||
password: '3QtnxrB7P5y4EpBdad1MkCeB2RHmArvcarw7udgXsAce',
|
||||
host:"127.0.0.1",
|
||||
port:8332
|
||||
})
|
||||
const query_options = {
|
||||
"minimumAmount":value,
|
||||
//"maximumAmount":value,
|
||||
"maximumCount":1 ,
|
||||
}
|
||||
return client.listUnspent(0, 9999999, [], true, query_options)
|
||||
.then((unspentTx) => {
|
||||
if(unspentTx[0]) {
|
||||
const txid = unspentTx[0].txid
|
||||
const vout = unspentTx[0].vout
|
||||
const txValue = unspentTx[0].amount
|
||||
let txFee = value*(0.001)
|
||||
const StxFee = txFee.toFixed(8)
|
||||
const totalValue = Number(value) + Number(StxFee)
|
||||
let change = txValue - totalValue
|
||||
const Schange = change.toFixed(8)
|
||||
const nodeAddress = unspentTx[0].address
|
||||
const input = [{
|
||||
"txid": txid,
|
||||
"vout": vout,
|
||||
}]
|
||||
let output = []
|
||||
let obj = {}
|
||||
let obj_2 ={}
|
||||
obj[receiver] = value
|
||||
obj_2[nodeAddress] = Schange
|
||||
output.push(obj,obj_2)
|
||||
return client.createRawTransaction(input,output)
|
||||
.then((txHex) => {
|
||||
return client.signRawTransactionWithWallet(txHex)
|
||||
.then((sinedHex) => {
|
||||
return client.sendRawTransaction(sinedHex.hex)
|
||||
.then((txHashOrId) => {
|
||||
return txHashOrId
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("error in sendsigned",err)
|
||||
throw err
|
||||
})
|
||||
})
|
||||
.catch((err)=>{
|
||||
console.log("error in sign ",err)
|
||||
throw err
|
||||
})
|
||||
})
|
||||
.catch((err )=> {
|
||||
console.log("error in create raw tx",err)
|
||||
throw err
|
||||
})
|
||||
} else {
|
||||
const error = new myError(
|
||||
'you do not have unspent trancaction',
|
||||
400,
|
||||
5,
|
||||
'تراکنش خرج نشده پیدا نشد',
|
||||
'خطا رخ داد'
|
||||
)
|
||||
throw error
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("error in lisutxo",err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export const bitcoinTransferToExchangeById = async(txId) => {
|
||||
const btcAddress = ["tb1qfpf6lss60wmle9wanetjxjjt6lc6z65mapk50s"]
|
||||
const client = new Client({
|
||||
network: 'testnet',
|
||||
username: 'polychain',
|
||||
password: '3QtnxrB7P5y4EpBdad1MkCeB2RHmArvcarw7udgXsAce',
|
||||
host: "127.0.0.1",
|
||||
port: 8332
|
||||
})
|
||||
return client.getTransaction(txId)
|
||||
.then((txInfo) => {
|
||||
if(txInfo){
|
||||
const tx = _.find(txInfo.details, (i) => { return i.category.toString() === "receive" && btcAddress.includes(i.address.toString())})
|
||||
if(tx) {
|
||||
let status
|
||||
if(txInfo.confirmations>=6)
|
||||
{
|
||||
status = "Confirmed"
|
||||
}else{
|
||||
status = "pending"
|
||||
}
|
||||
const info = {
|
||||
"txAddress":tx.address,
|
||||
"txAmount":tx.amount,
|
||||
"status":status
|
||||
}
|
||||
return info
|
||||
} else {
|
||||
const error = new myError(
|
||||
'tx not found',
|
||||
400,
|
||||
5,
|
||||
'تراکنش یافت نشد',
|
||||
'خطا رخ داد'
|
||||
)
|
||||
throw error
|
||||
}
|
||||
} else {
|
||||
const error = new myError(
|
||||
'transaction not found',
|
||||
400,
|
||||
5,
|
||||
'تراکنش مربوطه پیدا نشد.',
|
||||
'خطا رخ داد'
|
||||
)
|
||||
throw error
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
throw err
|
||||
})
|
||||
}
|
||||
|
||||
201
server/api/walletApi/etheriuem.js
Executable file
201
server/api/walletApi/etheriuem.js
Executable file
@@ -0,0 +1,201 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
exports.__esModule = true;
|
||||
exports.getAccounts = exports.receiveEtherFromClient = exports.sendEther = exports.getEtheriumNonce = exports.checkTransaction = exports.getBalance = exports.createPersonalAccount = exports.createAccount = void 0;
|
||||
var ethereumjs_common_1 = require("ethereumjs-common");
|
||||
var Web3 = require('web3');
|
||||
var Tx = require('ethereumjs-tx').Transaction;
|
||||
exports.createAccount = function () {
|
||||
var web3 = new Web3("http://localhost:8545");
|
||||
var data = web3.eth.accounts.create();
|
||||
return data;
|
||||
};
|
||||
exports.createPersonalAccount = function () {
|
||||
var web3 = new Web3("http://localhost:8545");
|
||||
return web3.eth.personal.newAccount("exchange")
|
||||
.then(function (result) {
|
||||
return result;
|
||||
})["catch"](function (err) {
|
||||
console.log(err);
|
||||
});
|
||||
};
|
||||
exports.getBalance = function (account) { return __awaiter(void 0, void 0, void 0, function () {
|
||||
var web3;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, new Web3("http://localhost:8545")];
|
||||
case 1:
|
||||
web3 = _a.sent();
|
||||
return [2 /*return*/, web3.eth.getBalance(account.toString())
|
||||
.then(function (balance) {
|
||||
return balance;
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
})];
|
||||
}
|
||||
});
|
||||
}); };
|
||||
exports.checkTransaction = function (transactionId) { return __awaiter(void 0, void 0, void 0, function () {
|
||||
var web3;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, new Web3("http://localhost:8545")];
|
||||
case 1:
|
||||
web3 = _a.sent();
|
||||
return [2 /*return*/, web3.eth.getTransactionReceipt(transactionId)
|
||||
.then(function (txR) {
|
||||
if (txR.blockNumber == undefined) {
|
||||
throw "transaction receipt not found";
|
||||
}
|
||||
else {
|
||||
return web3.eth.getTransaction(transactionId)
|
||||
.then(function (tx) {
|
||||
if (tx.blockNumber == undefined || tx.value == undefined) {
|
||||
throw "transaction receipt not found";
|
||||
}
|
||||
else {
|
||||
return tx;
|
||||
}
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
})["catch"](function (err) {
|
||||
throw (err);
|
||||
})];
|
||||
}
|
||||
});
|
||||
}); };
|
||||
exports.getEtheriumNonce = (function (address) {
|
||||
var web3 = new Web3("http://localhost:8545");
|
||||
return web3.eth.getTransactionCount(address, 'pending')
|
||||
.then(function (nonce) {
|
||||
//got nonce proceed with creating and signing transaction
|
||||
return nonce;
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
});
|
||||
exports.sendEther = function (account, value) { return __awaiter(void 0, void 0, void 0, function () {
|
||||
var web3;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, new Web3("http://localhost:8545")];
|
||||
case 1:
|
||||
web3 = _a.sent();
|
||||
//unlock it for a period of 15 secs
|
||||
return [2 /*return*/, web3.eth.personal.unlockAccount("0x868453967f6806ef86de7cf5e57a32ab28b875b4", "exchange", 15000)
|
||||
.then(function (unlocked) {
|
||||
return web3.eth.sendTransaction({
|
||||
//from: process.env.ADMIN_ETHERIUM_ACCOUNT_ADDRESS,
|
||||
from: '0x868453967f6806ef86de7cf5e57a32ab28b875b4',
|
||||
to: account.toString(),
|
||||
value: web3.utils.toWei(value.toString())
|
||||
})
|
||||
.then(function (receipt) {
|
||||
// then lock it
|
||||
return web3.eth.personal.lockAccount("0x868453967f6806ef86de7cf5e57a32ab28b875b4")
|
||||
.then(function () {
|
||||
return receipt;
|
||||
})["catch"](function (err) {
|
||||
return receipt;
|
||||
});
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
})["catch"](function (err) {
|
||||
throw (err);
|
||||
})];
|
||||
}
|
||||
});
|
||||
}); };
|
||||
exports.receiveEtherFromClient = function (transactionHash) {
|
||||
//receive transaction from the ui and send it
|
||||
var web3 = new Web3("http://localhost:8545");
|
||||
var rawTx = undefined;
|
||||
var transaction = undefined;
|
||||
//custom network
|
||||
var customCommon = ethereumjs_common_1["default"].forCustomChain('mainnet', {
|
||||
name: 'my-network',
|
||||
networkId: 1981,
|
||||
chainId: 1981
|
||||
}, 'petersburg');
|
||||
var preData = function () {
|
||||
var privateKey = Buffer.from('64061456066baa81c5097c895b5176fb3e1452eaf6f6776e2d7bf07ddb9accfe', 'hex');
|
||||
//parameters should be hex string starting with 0x
|
||||
var txParams = {
|
||||
nonce: '0x01',
|
||||
gas: 50002,
|
||||
gasPrice: Number(web3.utils.toWei('601', 'gwei')),
|
||||
to: '0x868453967f6806ef86de7cf5e57a32ab28b875b4',
|
||||
value: 10000003
|
||||
};
|
||||
// The second parameter is not necessary if these values are used
|
||||
var tx = new Tx(txParams, { common: customCommon });
|
||||
tx.sign(privateKey);
|
||||
var serializedTx = tx.serialize();
|
||||
return rawTx = '0x' + serializedTx.toString('hex');
|
||||
};
|
||||
return Promise.all([preData()])
|
||||
.then(function () {
|
||||
return web3.eth.sendSignedTransaction(rawTx)
|
||||
.then(function (result) {
|
||||
return result;
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
};
|
||||
exports.getAccounts = function () { return __awaiter(void 0, void 0, void 0, function () {
|
||||
var web3;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, new Web3("http://localhost:8545")];
|
||||
case 1:
|
||||
web3 = _a.sent();
|
||||
return [2 /*return*/, web3.eth.getAccounts()
|
||||
.then(function (result) {
|
||||
console.log("all acounts is ", result);
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
})];
|
||||
}
|
||||
});
|
||||
}); };
|
||||
157
server/api/walletApi/etheriuem.ts
Executable file
157
server/api/walletApi/etheriuem.ts
Executable file
@@ -0,0 +1,157 @@
|
||||
import Common from 'ethereumjs-common'
|
||||
|
||||
const Web3 = require('web3');
|
||||
const Tx = require('ethereumjs-tx').Transaction;
|
||||
|
||||
export const createAccount = () => {
|
||||
const web3 = new Web3( "http://localhost:8545");
|
||||
const data = web3.eth.accounts.create()
|
||||
return data
|
||||
}
|
||||
|
||||
export const createPersonalAccount = () => {
|
||||
const web3 = new Web3( "http://localhost:8545");
|
||||
return web3.eth.personal.newAccount("exchange")
|
||||
.then((result) => {
|
||||
return result
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
export const getBalance = async (account) => {
|
||||
const web3 = await new Web3( "http://localhost:8545");
|
||||
return web3.eth.getBalance(account.toString())
|
||||
.then((balance) => {
|
||||
return balance
|
||||
})
|
||||
.catch((err) => {
|
||||
throw err
|
||||
})
|
||||
}
|
||||
|
||||
export const checkTransaction = async (transactionId) => {
|
||||
const web3 = await new Web3( "http://localhost:8545");
|
||||
return web3.eth.getTransactionReceipt(transactionId)
|
||||
.then((txR) => {
|
||||
if (txR.blockNumber == undefined) {
|
||||
throw "transaction receipt not found";
|
||||
} else {
|
||||
return web3.eth.getTransaction(transactionId)
|
||||
.then((tx) => {
|
||||
if (tx.blockNumber == undefined|| tx.value == undefined) {
|
||||
throw "transaction receipt not found";
|
||||
} else {
|
||||
return tx
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
throw err
|
||||
})
|
||||
}
|
||||
}).catch((err)=>{
|
||||
throw(err)
|
||||
})
|
||||
}
|
||||
|
||||
export const getEtheriumNonce=((address) => {
|
||||
const web3 = new Web3( "http://localhost:8545");
|
||||
return web3.eth.getTransactionCount(address,'pending')
|
||||
.then((nonce) => {
|
||||
//got nonce proceed with creating and signing transaction
|
||||
return nonce;
|
||||
})
|
||||
.catch((err) => {
|
||||
throw err
|
||||
})
|
||||
})
|
||||
|
||||
export const sendEther = async (account,value) => {
|
||||
const web3 = await new Web3( "http://localhost:8545");
|
||||
//unlock it for a period of 15 secs
|
||||
return web3.eth.personal.unlockAccount("0x868453967f6806ef86de7cf5e57a32ab28b875b4","exchange", 15000)
|
||||
.then((unlocked) => {
|
||||
return web3.eth.sendTransaction({
|
||||
//from: process.env.ADMIN_ETHERIUM_ACCOUNT_ADDRESS,
|
||||
from: '0x868453967f6806ef86de7cf5e57a32ab28b875b4',
|
||||
to: account.toString(),
|
||||
value: web3.utils.toWei (value.toString())
|
||||
})
|
||||
.then((receipt) => {
|
||||
// then lock it
|
||||
return web3.eth.personal.lockAccount("0x868453967f6806ef86de7cf5e57a32ab28b875b4")
|
||||
.then(() => {
|
||||
return receipt
|
||||
})
|
||||
.catch((err) => {
|
||||
return receipt
|
||||
})
|
||||
})
|
||||
.catch((err) =>{
|
||||
throw err
|
||||
})
|
||||
}).catch((err)=>{
|
||||
throw(err)
|
||||
})
|
||||
}
|
||||
|
||||
export const receiveEtherFromClient = (transactionHash) => {
|
||||
//receive transaction from the ui and send it
|
||||
const web3 = new Web3( "http://localhost:8545");
|
||||
let rawTx = undefined
|
||||
let transaction = undefined
|
||||
//custom network
|
||||
const customCommon = Common.forCustomChain(
|
||||
'mainnet',
|
||||
{
|
||||
name: 'my-network',
|
||||
networkId: 1981,
|
||||
chainId: 1981,
|
||||
},
|
||||
'petersburg',
|
||||
)
|
||||
const preData = () => {
|
||||
const privateKey = Buffer.from(
|
||||
'64061456066baa81c5097c895b5176fb3e1452eaf6f6776e2d7bf07ddb9accfe',
|
||||
'hex'
|
||||
)
|
||||
//parameters should be hex string starting with 0x
|
||||
const txParams = {
|
||||
nonce: '0x01',
|
||||
gas: 50002,
|
||||
gasPrice: Number(web3.utils.toWei('601', 'gwei')),
|
||||
to: '0x868453967f6806ef86de7cf5e57a32ab28b875b4',
|
||||
value: 10000003
|
||||
}
|
||||
// The second parameter is not necessary if these values are used
|
||||
const tx = new Tx(txParams,{common : customCommon})
|
||||
tx.sign(privateKey)
|
||||
const serializedTx = tx.serialize()
|
||||
return rawTx = '0x' + serializedTx.toString('hex');
|
||||
}
|
||||
return Promise.all([preData()])
|
||||
.then(()=>{
|
||||
return web3.eth.sendSignedTransaction(rawTx)
|
||||
.then((result) => {
|
||||
return result;
|
||||
})
|
||||
.catch((err) => {
|
||||
throw err;
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
throw err
|
||||
})
|
||||
}
|
||||
|
||||
export const getAccounts = async () => {
|
||||
const web3 = await new Web3( "http://localhost:8545");
|
||||
return web3.eth.getAccounts()
|
||||
.then((result)=>{
|
||||
console.log("all acounts is ", result)
|
||||
})
|
||||
.catch((err)=>{
|
||||
throw err
|
||||
})
|
||||
}
|
||||
220
server/api/walletApi/transferFromExchange.js
Executable file
220
server/api/walletApi/transferFromExchange.js
Executable file
@@ -0,0 +1,220 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
exports.__esModule = true;
|
||||
exports.transferFromExchangeApi = void 0;
|
||||
var myError_1 = require("../myError");
|
||||
var currencies_1 = require("../../db/currencies");
|
||||
var bitcoin = require("../walletApi/bitcoin");
|
||||
var etheriuem = require("../walletApi/etheriuem");
|
||||
var mongoose = require("mongoose");
|
||||
var user_1 = require("../../db/user");
|
||||
var _ = require("lodash");
|
||||
var pendingTransfers_1 = require("../../db/pendingTransfers");
|
||||
exports.transferFromExchangeApi = function (currencyId, value, receiver, userId) { return __awaiter(void 0, void 0, void 0, function () {
|
||||
var info, resObj, checkStatus, session;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
checkStatus = function () {
|
||||
return null;
|
||||
};
|
||||
return [4 /*yield*/, mongoose.startSession()];
|
||||
case 1:
|
||||
session = _a.sent();
|
||||
return [2 /*return*/, session.withTransaction(function () { return __awaiter(void 0, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
return [2 /*return*/, user_1.User.findOne({ _id: userId }).session(session)
|
||||
.then(function (user) { return __awaiter(void 0, void 0, void 0, function () {
|
||||
var error;
|
||||
return __generator(this, function (_a) {
|
||||
if (user) {
|
||||
return [2 /*return*/, currencies_1.Currencies.findOne({ _id: currencyId })
|
||||
.then(function (cur) { return __awaiter(void 0, void 0, void 0, function () {
|
||||
var CurAbName, curInWall_1, error, error, error;
|
||||
return __generator(this, function (_a) {
|
||||
CurAbName = "";
|
||||
if (cur) {
|
||||
curInWall_1 = _.find(user.wallet, function (i) { return i.currency.toString() === currencyId.toString(); });
|
||||
if (curInWall_1) {
|
||||
if (curInWall_1.value >= Number(value)) {
|
||||
CurAbName = cur.ab_name;
|
||||
switch (CurAbName) {
|
||||
case "BTC":
|
||||
checkStatus = function () {
|
||||
return bitcoin.bitcoinTransferFromExchange(value, receiver)
|
||||
.then(function (txHash) {
|
||||
info = {
|
||||
status: "pending",
|
||||
txHash: txHash
|
||||
};
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
};
|
||||
case "ETH":
|
||||
return [2 /*return*/, etheriuem.sendEther(receiver.toString(), value)
|
||||
.then(function (result) { return __awaiter(void 0, void 0, void 0, function () {
|
||||
var bodySuccessfulOffer, bodyTransaction;
|
||||
return __generator(this, function (_a) {
|
||||
if (result && result.transactionHash) {
|
||||
bodySuccessfulOffer = {
|
||||
userId: user._id,
|
||||
transactions: []
|
||||
};
|
||||
bodyTransaction = {
|
||||
txId: result.transactionHash,
|
||||
currencyId: currencyId,
|
||||
currencyName: CurAbName,
|
||||
value: Number(value),
|
||||
type: 'send'
|
||||
};
|
||||
bodySuccessfulOffer.transactions.push(bodyTransaction);
|
||||
}
|
||||
else if (result) {
|
||||
throw ("could not get any transaction " + result);
|
||||
}
|
||||
else {
|
||||
throw ("could not get result ");
|
||||
}
|
||||
return [2 /*return*/];
|
||||
});
|
||||
}); })["catch"](function (err) {
|
||||
throw err;
|
||||
})];
|
||||
case "TRX":
|
||||
}
|
||||
return [2 /*return*/, Promise.all([checkStatus()])
|
||||
.then(function () {
|
||||
return pendingTransfers_1.PendingTransfers.findOne({ userId: userId }).session(session)
|
||||
.then(function (userPending) { return __awaiter(void 0, void 0, void 0, function () {
|
||||
var usrPending;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (!userPending) return [3 /*break*/, 2];
|
||||
userPending.transactions.push({
|
||||
txId: info.txHash,
|
||||
currencyId: currencyId,
|
||||
currencyName: CurAbName,
|
||||
value: value,
|
||||
type: "send"
|
||||
});
|
||||
return [4 /*yield*/, userPending.save()];
|
||||
case 1:
|
||||
_a.sent();
|
||||
return [3 /*break*/, 4];
|
||||
case 2:
|
||||
usrPending = {
|
||||
userId: userId,
|
||||
transactions: [{
|
||||
txId: info.txHash,
|
||||
currencyId: currencyId,
|
||||
currencyName: CurAbName,
|
||||
value: value,
|
||||
type: "id"
|
||||
}]
|
||||
};
|
||||
return [4 /*yield*/, pendingTransfers_1.PendingTransfers.create([usrPending], { session: session })];
|
||||
case 3:
|
||||
_a.sent();
|
||||
_a.label = 4;
|
||||
case 4:
|
||||
curInWall_1.value -= value;
|
||||
return [4 /*yield*/, user.save()];
|
||||
case 5:
|
||||
_a.sent();
|
||||
resObj =
|
||||
{
|
||||
status: "success",
|
||||
txValue: value,
|
||||
txHash: info.txHash
|
||||
};
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); })["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
})];
|
||||
}
|
||||
else {
|
||||
error = new myError_1["default"]('you do not have enough currency ', 400, 5, 'موجودی کافی نمی باشد', 'خطا رخ داد');
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
else {
|
||||
error = new myError_1["default"]('currency not found in user wallet', 400, 5, 'ارز در کیف پول پیدا نشد', 'خطا رخ داد');
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
else {
|
||||
error = new myError_1["default"]('currency not found', 400, 5, 'ارز پیدا نشد', 'خطا رخ داد');
|
||||
throw error;
|
||||
}
|
||||
return [2 /*return*/];
|
||||
});
|
||||
}); })["catch"](function (err) {
|
||||
throw err;
|
||||
})];
|
||||
}
|
||||
else {
|
||||
error = new myError_1["default"]('user not found', 400, 5, 'کاربر پیدا نشد.', 'خطا رخ داد');
|
||||
throw error;
|
||||
}
|
||||
return [2 /*return*/];
|
||||
});
|
||||
}); })["catch"](function (err) {
|
||||
throw err;
|
||||
})];
|
||||
});
|
||||
}); })
|
||||
.then(function () {
|
||||
return resObj;
|
||||
})["catch"](function (err) {
|
||||
console.log("error in with Transaction", err);
|
||||
throw ("error in with transaction");
|
||||
})["finally"](function () {
|
||||
session.endSession();
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
})];
|
||||
}
|
||||
});
|
||||
}); };
|
||||
189
server/api/walletApi/transferFromExchange.ts
Executable file
189
server/api/walletApi/transferFromExchange.ts
Executable file
@@ -0,0 +1,189 @@
|
||||
import myError from '../myError'
|
||||
import { Currencies } from '../../db/currencies'
|
||||
import * as bitcoin from '../walletApi/bitcoin'
|
||||
import * as etheriuem from '../walletApi/etheriuem'
|
||||
import * as tron from '../walletApi/tron'
|
||||
import * as mongoose from 'mongoose'
|
||||
import { User } from '../../db/user'
|
||||
import * as _ from 'lodash'
|
||||
import { PendingTransfers } from '../../db/pendingTransfers'
|
||||
import { SuccessfulTransfers } from '../../db/successfulTransfers'
|
||||
|
||||
export const transferFromExchangeApi = async(currencyId, value, receiver, userId) => {
|
||||
let info
|
||||
let resObj
|
||||
let checkStatus = () => {
|
||||
return null
|
||||
}
|
||||
const session = await mongoose.startSession()
|
||||
return session.withTransaction(async() => {
|
||||
return User.findOne({_id:userId}).session(session)
|
||||
.then(async (user)=>{
|
||||
if(user){
|
||||
return Currencies.findOne({_id:currencyId})
|
||||
.then(async(cur) => {
|
||||
let CurAbName = ""
|
||||
if(cur){
|
||||
let curInWall = _.find(user.wallet, (i) => { return i.currency.toString() === currencyId.toString()})
|
||||
if(curInWall) {
|
||||
|
||||
if(curInWall.value >= Number(value)){
|
||||
CurAbName = cur.ab_name
|
||||
switch(CurAbName) {
|
||||
case "BTC":
|
||||
checkStatus = () => {
|
||||
return bitcoin.bitcoinTransferFromExchange(value,receiver)
|
||||
.then((txHash) => {
|
||||
info = {
|
||||
status:"pending",
|
||||
txHash:txHash
|
||||
}
|
||||
})
|
||||
.catch((err)=>{
|
||||
throw err
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
case "ETH":
|
||||
return etheriuem.sendEther(receiver.toString(),value)
|
||||
.then(async (result) => {
|
||||
if(result&&result.transactionHash) {
|
||||
const bodySuccessfulOffer = {
|
||||
userId: user._id ,
|
||||
transactions : []
|
||||
}
|
||||
const bodyTransaction = {
|
||||
txId : result.transactionHash,
|
||||
currencyId : currencyId,
|
||||
currencyName : CurAbName,
|
||||
value : Number(value),
|
||||
type : 'send'
|
||||
}
|
||||
bodySuccessfulOffer.transactions.push(bodyTransaction)
|
||||
} else if(result) {
|
||||
throw ("could not get any transaction "+ result)
|
||||
} else {
|
||||
throw ("could not get result ")
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
throw err
|
||||
})
|
||||
|
||||
case "TRX":
|
||||
}
|
||||
return Promise.all([checkStatus()])
|
||||
.then(() =>{
|
||||
return PendingTransfers.findOne({ userId:userId }).session(session)
|
||||
.then(async (userPending) => {
|
||||
if(userPending){
|
||||
userPending.transactions.push({
|
||||
txId: info.txHash,
|
||||
currencyId: currencyId,
|
||||
currencyName: CurAbName,
|
||||
value: value,
|
||||
type: "send"
|
||||
})
|
||||
await userPending.save()
|
||||
|
||||
} else {
|
||||
const usrPending = {
|
||||
userId: userId,
|
||||
transactions: [{
|
||||
txId: info.txHash,
|
||||
currencyId: currencyId,
|
||||
currencyName: CurAbName,
|
||||
value: value,
|
||||
type: "id"
|
||||
}]
|
||||
}
|
||||
await PendingTransfers.create([usrPending],{ session })
|
||||
}
|
||||
curInWall.value -= value
|
||||
await user.save()
|
||||
resObj =
|
||||
{
|
||||
status:"success",
|
||||
txValue:value,
|
||||
txHash:info.txHash
|
||||
}
|
||||
}).catch((err)=>{
|
||||
throw err
|
||||
})
|
||||
}).catch((err)=>{
|
||||
throw err
|
||||
})
|
||||
|
||||
} else {
|
||||
const error = new myError(
|
||||
'you do not have enough currency ',
|
||||
400,
|
||||
5,
|
||||
'موجودی کافی نمی باشد',
|
||||
'خطا رخ داد'
|
||||
)
|
||||
throw error
|
||||
}
|
||||
|
||||
} else {
|
||||
const error = new myError(
|
||||
'currency not found in user wallet',
|
||||
400,
|
||||
5,
|
||||
'ارز در کیف پول پیدا نشد',
|
||||
'خطا رخ داد'
|
||||
)
|
||||
throw error
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
const error = new myError(
|
||||
'currency not found',
|
||||
400,
|
||||
5,
|
||||
'ارز پیدا نشد',
|
||||
'خطا رخ داد'
|
||||
)
|
||||
throw error
|
||||
}
|
||||
|
||||
}).catch((err)=>{
|
||||
throw err
|
||||
})
|
||||
} else {
|
||||
const error = new myError(
|
||||
'user not found',
|
||||
400,
|
||||
5,
|
||||
'کاربر پیدا نشد.',
|
||||
'خطا رخ داد'
|
||||
)
|
||||
throw error
|
||||
}
|
||||
}).catch((err)=>{
|
||||
throw err
|
||||
})
|
||||
})
|
||||
.then(() => {
|
||||
|
||||
return resObj
|
||||
|
||||
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("error in with Transaction",err)
|
||||
throw("error in with transaction")
|
||||
})
|
||||
.finally(() => {
|
||||
session.endSession()
|
||||
})
|
||||
|
||||
|
||||
.catch((err) => {
|
||||
throw err
|
||||
})
|
||||
}
|
||||
128
server/api/walletApi/transferInWithTxId.js
Executable file
128
server/api/walletApi/transferInWithTxId.js
Executable file
@@ -0,0 +1,128 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
exports.__esModule = true;
|
||||
exports.transferInWithTxId = void 0;
|
||||
var Client = require('bitcoin-core');
|
||||
var _ = require("lodash");
|
||||
exports.transferInWithTxId = function (currency, txId) { return __awaiter(void 0, void 0, void 0, function () {
|
||||
var client_1;
|
||||
return __generator(this, function (_a) {
|
||||
switch (currency) {
|
||||
case "BTC":
|
||||
client_1 = new Client({
|
||||
network: 'testnet',
|
||||
username: 'polychain',
|
||||
password: '3QtnxrB7P5y4EpBdad1MkCeB2RHmArvcarw7udgXsAce',
|
||||
host: "127.0.0.1",
|
||||
port: 8332
|
||||
});
|
||||
client_1.listTransactions("*", 100, 0)
|
||||
.theb(function (txs) {
|
||||
var tx = _.find(txs, function (i) { return i.txid.toString() === txId.toString(); });
|
||||
if (tx) {
|
||||
if (tx.address === "node address") {
|
||||
var amount_1 = tx.amount;
|
||||
client_1.getBlockCount()
|
||||
.then(function (blockCount) {
|
||||
if (blockCount - Number(tx.blockindex) > 6) {
|
||||
return amount_1;
|
||||
}
|
||||
else {
|
||||
//
|
||||
}
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
else {
|
||||
}
|
||||
}
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
break;
|
||||
case "ETH":
|
||||
//
|
||||
break;
|
||||
case "TRX":
|
||||
//
|
||||
break;
|
||||
}
|
||||
return [2 /*return*/];
|
||||
});
|
||||
}); };
|
||||
// fetch("connect to your bitcoin node",{
|
||||
// method: "POST",
|
||||
// body:{"jsonrpc": "1.0", "id":"curltest",
|
||||
// "method": "listtransactions",
|
||||
// "params": [txId]
|
||||
// },
|
||||
// headers:header
|
||||
// })
|
||||
// .then(res => res.json())
|
||||
// .then((txs) => {
|
||||
// const tx = _.find(txs, (i) => { return i.txid.toString()=== txId.toString()})
|
||||
// if(tx){
|
||||
// const blockIndex = Number(tx.blockindex)
|
||||
// const txValue = Number(tx.vout)
|
||||
// fetch("connect to your bitcoin node",{
|
||||
// method: "POST",
|
||||
// body:{"jsonrpc": "1.0", "id":"curltest",
|
||||
// "method": "getblockcount",
|
||||
// "params": []
|
||||
// },
|
||||
// headers:header
|
||||
// })
|
||||
// .then(res => res.json())
|
||||
// .then((blockCount) => {
|
||||
// if(Number(blockCount)-blockIndex>=6) {
|
||||
// let cur = _.find(user.wallet, (i) => { return i.currency.toString()=== currencyId.toString() })
|
||||
// cur.value += txValue
|
||||
// } else {
|
||||
// //wait for transaction confirmation
|
||||
// }
|
||||
// }).catch((err)=>{
|
||||
// next(err)
|
||||
// })
|
||||
// } else {
|
||||
// //throw errrrrorrrrrr
|
||||
// }
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// next(err)
|
||||
// })
|
||||
114
server/api/walletApi/transferTo.js
Executable file
114
server/api/walletApi/transferTo.js
Executable file
@@ -0,0 +1,114 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
exports.__esModule = true;
|
||||
exports.transferToApi = void 0;
|
||||
var Client = require('bitcoin-core');
|
||||
exports.transferToApi = function (currency, value, receiver) { return __awaiter(void 0, void 0, void 0, function () {
|
||||
var client_1, query_options;
|
||||
return __generator(this, function (_a) {
|
||||
switch (currency) {
|
||||
case "BTC":
|
||||
client_1 = new Client({
|
||||
network: 'testnet',
|
||||
username: 'polychain',
|
||||
password: '3QtnxrB7P5y4EpBdad1MkCeB2RHmArvcarw7udgXsAce',
|
||||
host: "127.0.0.1",
|
||||
port: 8332
|
||||
});
|
||||
query_options = {
|
||||
"minimumAmount": value
|
||||
};
|
||||
client_1.listUnspent(1, 1, [], true, query_options)
|
||||
.then(function (unspentTx) {
|
||||
if (unspentTx[0]) {
|
||||
var txid = unspentTx[0].txid;
|
||||
var txValue = Number(unspentTx[0].amount);
|
||||
var change = txValue - value;
|
||||
var nodeAddress_1 = unspentTx[0].address;
|
||||
var input = [{
|
||||
"txid": txid,
|
||||
"vout": Number(txValue)
|
||||
}];
|
||||
var output = [
|
||||
{
|
||||
"receiver": txValue,
|
||||
"nodeAddress": change
|
||||
},
|
||||
{
|
||||
"data": "Hi"
|
||||
},
|
||||
];
|
||||
client_1.createRawTransaction(input, output)
|
||||
.then(function (txHex) {
|
||||
client_1.dumpprivkey(nodeAddress_1)
|
||||
.then(function (priKey) {
|
||||
client_1.signRawTransactionWithKey(txHex, [priKey])
|
||||
.then(function (sinedHex) {
|
||||
client_1.sendRawTransaction(sinedHex)
|
||||
.then(function (txHashOrId) {
|
||||
return txHashOrId;
|
||||
})["catch"](function (err) {
|
||||
throw (err);
|
||||
});
|
||||
})["catch"](function (err) {
|
||||
throw (err);
|
||||
});
|
||||
})["catch"](function (err) {
|
||||
throw (err);
|
||||
});
|
||||
})["catch"](function (err) {
|
||||
throw (err);
|
||||
});
|
||||
}
|
||||
else {
|
||||
// throw err
|
||||
}
|
||||
})["catch"](function (err) {
|
||||
console.log('the error is', err);
|
||||
});
|
||||
break;
|
||||
case "ETH":
|
||||
//
|
||||
break;
|
||||
case "TRX":
|
||||
//
|
||||
break;
|
||||
}
|
||||
return [2 /*return*/];
|
||||
});
|
||||
}); };
|
||||
100
server/api/walletApi/transferToExchange.js
Executable file
100
server/api/walletApi/transferToExchange.js
Executable file
@@ -0,0 +1,100 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
exports.__esModule = true;
|
||||
exports.transferToExchangeApi = void 0;
|
||||
var Client = require('bitcoin-core');
|
||||
var myError_1 = require("../myError");
|
||||
var currencies_1 = require("../../db/currencies");
|
||||
exports.transferToExchangeApi = function (currencyId, signedRawTxHex, value) { return __awaiter(void 0, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
currencies_1.Currencies.findOne({ _id: currencyId })
|
||||
.then(function (cur) {
|
||||
var CurAbName = "";
|
||||
if (cur) {
|
||||
value = Number(value);
|
||||
CurAbName = cur.ab_name;
|
||||
switch (CurAbName) {
|
||||
case "BTC":
|
||||
// const client = new Client({
|
||||
// network: 'testnet',
|
||||
// username: 'polychain',
|
||||
// password: '3QtnxrB7P5y4EpBdad1MkCeB2RHmArvcarw7udgXsAce',
|
||||
// host:"127.0.0.1",
|
||||
// port:8332
|
||||
// })
|
||||
// client.decodeRawTransaction(signedRawTxHex)
|
||||
// .then((tx) => {
|
||||
// if(tx) {
|
||||
// const txValue = Number(tx[0].vout[0].value)
|
||||
// if(txValue===Number(value)) {
|
||||
// client.sendRawTransaction(signedRawTxHex)
|
||||
// .then((txHashOrId) => {
|
||||
// return txHashOrId
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// throw(err)
|
||||
// })
|
||||
// } else {
|
||||
// //
|
||||
// }
|
||||
// } else {
|
||||
// //
|
||||
// }
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// throw err
|
||||
// })
|
||||
break;
|
||||
case "ETH":
|
||||
//
|
||||
break;
|
||||
case "TRX":
|
||||
//
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
var error = new myError_1["default"]('currency not found', 400, 5, 'ارز مربوطه پیدا نشد.', 'خطا رخ داد');
|
||||
throw error;
|
||||
}
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
return [2 /*return*/];
|
||||
});
|
||||
}); };
|
||||
70
server/api/walletApi/transferToExchange.ts
Executable file
70
server/api/walletApi/transferToExchange.ts
Executable file
@@ -0,0 +1,70 @@
|
||||
const Client = require('bitcoin-core')
|
||||
import { conformsTo } from 'lodash'
|
||||
import myError from '../myError'
|
||||
import { Currencies } from '../../db/currencies'
|
||||
export const transferToExchangeApi = async(currencyId,signedRawTxHex,value) => {
|
||||
Currencies.findOne({_id:currencyId})
|
||||
.then((cur)=>{
|
||||
let CurAbName = ""
|
||||
if(cur){
|
||||
value = Number(value)
|
||||
CurAbName = cur.ab_name
|
||||
switch(CurAbName) {
|
||||
case "BTC":
|
||||
// const client = new Client({
|
||||
// network: 'testnet',
|
||||
// username: 'polychain',
|
||||
// password: '3QtnxrB7P5y4EpBdad1MkCeB2RHmArvcarw7udgXsAce',
|
||||
// host:"127.0.0.1",
|
||||
// port:8332
|
||||
// })
|
||||
// client.decodeRawTransaction(signedRawTxHex)
|
||||
// .then((tx) => {
|
||||
// if(tx) {
|
||||
// const txValue = Number(tx[0].vout[0].value)
|
||||
// if(txValue===Number(value)) {
|
||||
// client.sendRawTransaction(signedRawTxHex)
|
||||
// .then((txHashOrId) => {
|
||||
// return txHashOrId
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// throw(err)
|
||||
// })
|
||||
// } else {
|
||||
// //
|
||||
// }
|
||||
|
||||
// } else {
|
||||
// //
|
||||
// }
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// throw err
|
||||
// })
|
||||
break;
|
||||
|
||||
case "ETH":
|
||||
//
|
||||
break;
|
||||
|
||||
case "TRX":
|
||||
//
|
||||
break;
|
||||
|
||||
}
|
||||
}else{
|
||||
const error = new myError(
|
||||
'currency not found',
|
||||
400,
|
||||
5,
|
||||
'ارز مربوطه پیدا نشد.',
|
||||
'خطا رخ داد'
|
||||
)
|
||||
throw error
|
||||
}
|
||||
}).catch((err)=>{
|
||||
throw err
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
363
server/api/walletApi/transferToExchangeById.js
Executable file
363
server/api/walletApi/transferToExchangeById.js
Executable file
@@ -0,0 +1,363 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
exports.__esModule = true;
|
||||
exports.transferToExchangeByIdApi = void 0;
|
||||
var _ = require("lodash");
|
||||
var myError_1 = require("../myError");
|
||||
var currencies_1 = require("../../db/currencies");
|
||||
var user_1 = require("../../db/user");
|
||||
var mongoose = require("mongoose");
|
||||
var bitcoin = require("../walletApi/bitcoin");
|
||||
var etherium = require("./etheriuem");
|
||||
var tron = require("./tron");
|
||||
var pendingTransfers_1 = require("../../db/pendingTransfers");
|
||||
var successfulTransfers_1 = require("../../db/successfulTransfers");
|
||||
exports.transferToExchangeByIdApi = function (currencyId, txId, userId) { return __awaiter(void 0, void 0, void 0, function () {
|
||||
var info, resObj, userHaveDoc, checkStatus, session;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
userHaveDoc = false;
|
||||
checkStatus = function () {
|
||||
return null;
|
||||
};
|
||||
return [4 /*yield*/, mongoose.startSession()];
|
||||
case 1:
|
||||
session = _a.sent();
|
||||
return [2 /*return*/, session.withTransaction(function () {
|
||||
return user_1.User.findOne({ _id: userId }).session(session)
|
||||
.then(function (user) {
|
||||
if (user) {
|
||||
return pendingTransfers_1.PendingTransfers.findOne({ userId: userId })
|
||||
.then(function (userPending) {
|
||||
if (userPending && userPending.userId.toString() === userId.toString()) {
|
||||
userHaveDoc = true;
|
||||
var pendingTx = _.find(userPending.transactions, function (i) { return i.txId.toString() === txId.toString(); });
|
||||
if (pendingTx) {
|
||||
var error = new myError_1["default"]('transaction already exsist', 400, 5, 'تراکنش قبلا وجود دارد', 'خطا رخ داد');
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return currencies_1.Currencies.findOne({ _id: currencyId })
|
||||
.then(function (cur) {
|
||||
var CurAbName = "";
|
||||
if (cur) {
|
||||
CurAbName = cur.ab_name;
|
||||
switch (CurAbName) {
|
||||
case "BTC":
|
||||
checkStatus = function () {
|
||||
return bitcoin.bitcoinTransferToExchangeById(txId)
|
||||
.then(function (result) {
|
||||
info = result;
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
};
|
||||
break;
|
||||
case "ETH":
|
||||
return etherium.checkTransaction(txId)
|
||||
.then(function (transaction) {
|
||||
if (transaction && transaction.hash.toString() === txId.toString()) {
|
||||
var curInWall = _.find(user.wallet, function (i) { return i.currency.toString() === currencyId.toString(); });
|
||||
if (curInWall) {
|
||||
curInWall.value += Number(transaction.value);
|
||||
}
|
||||
else {
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
throw "transaction not valid";
|
||||
}
|
||||
})["catch"](function (err) {
|
||||
console.log("api error: ", err);
|
||||
});
|
||||
//
|
||||
case "TRX":
|
||||
return tron.validateByTXId(txId)
|
||||
.then(function (transaction) {
|
||||
if (transaction.result) {
|
||||
var resObj_1 = {
|
||||
status: "successful",
|
||||
txValue: transaction
|
||||
};
|
||||
return resObj_1;
|
||||
}
|
||||
else {
|
||||
var resObj_2 = {
|
||||
status: "pending",
|
||||
txValue: transaction
|
||||
};
|
||||
}
|
||||
})["catch"](function (err) {
|
||||
throw (err);
|
||||
});
|
||||
// default
|
||||
}
|
||||
return Promise.all([checkStatus()])
|
||||
.then(function () {
|
||||
if (userHaveDoc) {
|
||||
userPending.transactions.push({
|
||||
txId: txId,
|
||||
currencyId: currencyId,
|
||||
currencyName: CurAbName,
|
||||
value: info.txAmount,
|
||||
type: "id"
|
||||
});
|
||||
userPending.save()
|
||||
.then(function () {
|
||||
if (info.status === 'Confirmed') {
|
||||
return successfulTransfers_1.SuccessfulTransfers.findOne({ userId: userId }).session(session)
|
||||
.then(function (userSuccess) { return __awaiter(void 0, void 0, void 0, function () {
|
||||
var usrSuccess;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (!(userSuccess && userSuccess.userId.toString() === userId.toString())) return [3 /*break*/, 2];
|
||||
userSuccess.transactions.push({
|
||||
txId: txId,
|
||||
currencyId: currencyId,
|
||||
currencyName: CurAbName,
|
||||
value: info.txAmount,
|
||||
type: "id"
|
||||
});
|
||||
return [4 /*yield*/, userSuccess.save()];
|
||||
case 1:
|
||||
_a.sent();
|
||||
return [3 /*break*/, 4];
|
||||
case 2:
|
||||
usrSuccess = {
|
||||
userId: userId,
|
||||
transactions: [{
|
||||
txId: txId,
|
||||
currencyId: currencyId,
|
||||
currencyName: CurAbName,
|
||||
value: info.txAmount,
|
||||
type: "id"
|
||||
}]
|
||||
};
|
||||
return [4 /*yield*/, successfulTransfers_1.SuccessfulTransfers.create([usrSuccess], { session: session })];
|
||||
case 3:
|
||||
_a.sent();
|
||||
_a.label = 4;
|
||||
case 4: return [2 /*return*/, pendingTransfers_1.PendingTransfers.findOne({ userId: userId }).session(session)
|
||||
.then(function (userPendinAfterSave) { return __awaiter(void 0, void 0, void 0, function () {
|
||||
var cur;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
userPendinAfterSave.transactions = _.filter(userPendinAfterSave.transactions, function (i) { return i.txId.toString() !== txId.toString(); });
|
||||
return [4 /*yield*/, userPendinAfterSave.save()];
|
||||
case 1:
|
||||
_a.sent();
|
||||
cur = _.find(user.wallet, function (i) { return i.currency.toString() === currencyId.toString(); });
|
||||
if (!cur) return [3 /*break*/, 3];
|
||||
cur.value += info.txAmount;
|
||||
return [4 /*yield*/, user.save()];
|
||||
case 2:
|
||||
_a.sent();
|
||||
return [3 /*break*/, 5];
|
||||
case 3:
|
||||
user.wallet.push({
|
||||
currency: currencyId,
|
||||
value: info.txAmount
|
||||
});
|
||||
return [4 /*yield*/, user.save()];
|
||||
case 4:
|
||||
_a.sent();
|
||||
_a.label = 5;
|
||||
case 5:
|
||||
resObj = {
|
||||
status: 'successful',
|
||||
value: info.txAmount
|
||||
};
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); })["catch"](function (err) {
|
||||
throw err;
|
||||
})];
|
||||
}
|
||||
});
|
||||
}); })["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
else {
|
||||
resObj = {
|
||||
status: 'pending',
|
||||
value: info.txAmount
|
||||
};
|
||||
}
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
else {
|
||||
var usrPending = {
|
||||
userId: userId,
|
||||
transactions: [{
|
||||
txId: txId,
|
||||
currencyId: currencyId,
|
||||
currencyName: CurAbName,
|
||||
value: info.txAmount,
|
||||
type: "id"
|
||||
}]
|
||||
};
|
||||
pendingTransfers_1.PendingTransfers.create([usrPending])
|
||||
.then(function () {
|
||||
if (info.status === 'Confirmed') {
|
||||
return successfulTransfers_1.SuccessfulTransfers.findOne({ userId: userId }).session(session)
|
||||
.then(function (userSuccess) { return __awaiter(void 0, void 0, void 0, function () {
|
||||
var usrSuccess;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (!(userSuccess && userSuccess.userId.toString() === userId.toString())) return [3 /*break*/, 2];
|
||||
userSuccess.transactions.push({
|
||||
txId: txId,
|
||||
currencyId: currencyId,
|
||||
currencyName: CurAbName,
|
||||
value: info.txAmount,
|
||||
type: "id"
|
||||
});
|
||||
return [4 /*yield*/, userSuccess.save()];
|
||||
case 1:
|
||||
_a.sent();
|
||||
return [3 /*break*/, 4];
|
||||
case 2:
|
||||
usrSuccess = {
|
||||
userId: userId,
|
||||
transactions: [{
|
||||
txId: txId,
|
||||
currencyId: currencyId,
|
||||
currencyName: CurAbName,
|
||||
value: info.txAmount,
|
||||
type: "id"
|
||||
}]
|
||||
};
|
||||
return [4 /*yield*/, successfulTransfers_1.SuccessfulTransfers.create([usrSuccess], { session: session })];
|
||||
case 3:
|
||||
_a.sent();
|
||||
_a.label = 4;
|
||||
case 4: return [2 /*return*/, pendingTransfers_1.PendingTransfers.findOne({ userId: userId }).session(session)
|
||||
.then(function (userPendinAfterSave) { return __awaiter(void 0, void 0, void 0, function () {
|
||||
var cur;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
userPendinAfterSave.transactions = _.filter(userPendinAfterSave.transactions, function (i) { return i.txId.toString() !== txId.toString(); });
|
||||
return [4 /*yield*/, userPendinAfterSave.save()];
|
||||
case 1:
|
||||
_a.sent();
|
||||
cur = _.find(user.wallet, function (i) { return i.currency.toString() === currencyId.toString(); });
|
||||
if (!cur) return [3 /*break*/, 3];
|
||||
cur.value += info.txAmount;
|
||||
return [4 /*yield*/, user.save()];
|
||||
case 2:
|
||||
_a.sent();
|
||||
return [3 /*break*/, 5];
|
||||
case 3:
|
||||
user.wallet.push({
|
||||
currency: currencyId,
|
||||
value: info.txAmount
|
||||
});
|
||||
return [4 /*yield*/, user.save()];
|
||||
case 4:
|
||||
_a.sent();
|
||||
_a.label = 5;
|
||||
case 5:
|
||||
resObj = {
|
||||
status: 'successful',
|
||||
value: info.txAmount
|
||||
};
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); })["catch"](function (err) {
|
||||
throw err;
|
||||
})];
|
||||
}
|
||||
});
|
||||
}); })["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
else {
|
||||
resObj = {
|
||||
status: 'pending',
|
||||
value: info.txAmount
|
||||
};
|
||||
}
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
else {
|
||||
var error = new myError_1["default"]('currency not found', 400, 5, 'ارز مربوطه پیدا نشد.', 'خطا رخ داد');
|
||||
throw error;
|
||||
}
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
else {
|
||||
var error = new myError_1["default"]('user not found', 400, 5, 'کاربر پیدا نشد.', 'خطا رخ داد');
|
||||
throw error;
|
||||
}
|
||||
})["catch"](function (err) {
|
||||
throw err;
|
||||
});
|
||||
})
|
||||
.then(function () {
|
||||
return resObj;
|
||||
})["catch"](function (err) {
|
||||
throw ("error in with Transaction" + ":" + err);
|
||||
})["finally"](function () {
|
||||
session.endSession();
|
||||
})];
|
||||
}
|
||||
});
|
||||
}); };
|
||||
291
server/api/walletApi/transferToExchangeById.ts
Executable file
291
server/api/walletApi/transferToExchangeById.ts
Executable file
@@ -0,0 +1,291 @@
|
||||
import * as _ from 'lodash'
|
||||
import myError from '../myError'
|
||||
import { Currencies } from '../../db/currencies'
|
||||
import { User } from '../../db/user'
|
||||
import * as mongoose from 'mongoose'
|
||||
import * as bitcoin from '../walletApi/bitcoin'
|
||||
import * as etherium from './etheriuem'
|
||||
import * as tron from './tron'
|
||||
import { PendingTransfers } from '../../db/pendingTransfers'
|
||||
import { SuccessfulTransfers } from '../../db/successfulTransfers'
|
||||
export const transferToExchangeByIdApi = async(currencyId, txId, userId) => {
|
||||
let info
|
||||
let resObj
|
||||
let userHaveDoc = false
|
||||
let checkStatus = () => {
|
||||
return null
|
||||
}
|
||||
const session = await mongoose.startSession()
|
||||
return session.withTransaction(() => {
|
||||
return User.findOne({ _id: userId }).session(session)
|
||||
.then((user) => {
|
||||
if(user) {
|
||||
return PendingTransfers.findOne({ userId: userId })
|
||||
.then((userPending) => {
|
||||
if(userPending && userPending.userId.toString() === userId.toString()) {
|
||||
userHaveDoc = true
|
||||
let pendingTx = _.find(userPending.transactions, (i) => { return i.txId.toString() === txId.toString() })
|
||||
if(pendingTx) {
|
||||
const error = new myError(
|
||||
'transaction already exsist',
|
||||
400,
|
||||
5,
|
||||
'تراکنش قبلا وجود دارد',
|
||||
'خطا رخ داد'
|
||||
)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
return Currencies.findOne({ _id: currencyId })
|
||||
.then((cur) => {
|
||||
let CurAbName = ""
|
||||
if(cur) {
|
||||
CurAbName = cur.ab_name
|
||||
switch(CurAbName) {
|
||||
case "BTC":
|
||||
checkStatus = () => {
|
||||
return bitcoin.bitcoinTransferToExchangeById(txId)
|
||||
.then((result) => {
|
||||
info = result
|
||||
})
|
||||
.catch((err) => {
|
||||
throw err
|
||||
})
|
||||
}
|
||||
break;
|
||||
case "ETH":
|
||||
return etherium.checkTransaction(txId)
|
||||
.then((transaction) => {
|
||||
if(transaction && transaction.hash.toString() === txId.toString()) {
|
||||
let curInWall = _.find(user.wallet, (i) => { return i.currency.toString()=== currencyId.toString()})
|
||||
if(curInWall) {
|
||||
curInWall.value += Number(transaction.value)
|
||||
} else {
|
||||
|
||||
}
|
||||
return
|
||||
} else {
|
||||
throw "transaction not valid"
|
||||
}
|
||||
})
|
||||
.catch((err)=>{
|
||||
console.log("api error: ",err)
|
||||
})
|
||||
//
|
||||
case "TRX":
|
||||
return tron.validateByTXId(txId)
|
||||
.then((transaction: any) => {
|
||||
if(transaction.result) {
|
||||
const resObj = {
|
||||
status:"successful",
|
||||
txValue : transaction
|
||||
}
|
||||
return resObj
|
||||
} else {
|
||||
const resObj = {
|
||||
status:"pending",
|
||||
txValue : transaction
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
throw(err)
|
||||
})
|
||||
|
||||
// default
|
||||
}
|
||||
return Promise.all([checkStatus()])
|
||||
.then(() => {
|
||||
if(userHaveDoc) {
|
||||
userPending.transactions.push({
|
||||
txId:txId,
|
||||
currencyId:currencyId,
|
||||
currencyName:CurAbName,
|
||||
value:info.txAmount,
|
||||
type:"id"
|
||||
})
|
||||
userPending.save()
|
||||
.then(() => {
|
||||
if(info.status === 'Confirmed') {
|
||||
return SuccessfulTransfers.findOne({ userId: userId }).session(session)
|
||||
.then(async (userSuccess) => {
|
||||
if(userSuccess && userSuccess.userId.toString() === userId.toString()) {
|
||||
userSuccess.transactions.push({
|
||||
txId,
|
||||
currencyId,
|
||||
currencyName: CurAbName,
|
||||
value: info.txAmount,
|
||||
type: "id"
|
||||
})
|
||||
await userSuccess.save()
|
||||
} else {
|
||||
const usrSuccess = {
|
||||
userId:userId,
|
||||
transactions: [{
|
||||
txId,
|
||||
currencyId,
|
||||
currencyName: CurAbName,
|
||||
value: info.txAmount,
|
||||
type: "id"
|
||||
}]
|
||||
}
|
||||
await SuccessfulTransfers.create([usrSuccess], { session })
|
||||
}
|
||||
return PendingTransfers.findOne({ userId:userId }).session(session)
|
||||
.then(async (userPendinAfterSave) => {
|
||||
userPendinAfterSave.transactions = _.filter(userPendinAfterSave.transactions, (i) => { return i.txId.toString() !== txId.toString() })
|
||||
await userPendinAfterSave.save()
|
||||
let cur = _.find(user.wallet, (i) => { return i.currency.toString() === currencyId.toString()})
|
||||
if(cur) {
|
||||
cur.value +=info.txAmount
|
||||
await user.save()
|
||||
} else {
|
||||
user.wallet.push({
|
||||
currency: currencyId,
|
||||
value: info.txAmount
|
||||
})
|
||||
await user.save()
|
||||
}
|
||||
resObj = {
|
||||
status: 'successful',
|
||||
value: info.txAmount
|
||||
}
|
||||
}).catch((err)=>{
|
||||
throw err
|
||||
})
|
||||
}).catch((err)=>{
|
||||
throw err
|
||||
})
|
||||
} else {
|
||||
resObj = {
|
||||
status: 'pending',
|
||||
value: info.txAmount
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
throw err
|
||||
})
|
||||
} else {
|
||||
const usrPending = {
|
||||
userId:userId,
|
||||
transactions: [{
|
||||
txId,
|
||||
currencyId,
|
||||
currencyName: CurAbName,
|
||||
value: info.txAmount,
|
||||
type: "id"
|
||||
}]
|
||||
}
|
||||
PendingTransfers.create([usrPending])
|
||||
.then(() => {
|
||||
if(info.status === 'Confirmed') {
|
||||
return SuccessfulTransfers.findOne({ userId: userId }).session(session)
|
||||
.then(async (userSuccess) => {
|
||||
if(userSuccess && userSuccess.userId.toString() === userId.toString()) {
|
||||
userSuccess.transactions.push({
|
||||
txId,
|
||||
currencyId,
|
||||
currencyName: CurAbName,
|
||||
value: info.txAmount,
|
||||
type: "id"
|
||||
})
|
||||
await userSuccess.save()
|
||||
} else {
|
||||
const usrSuccess = {
|
||||
userId:userId,
|
||||
transactions: [{
|
||||
txId,
|
||||
currencyId,
|
||||
currencyName: CurAbName,
|
||||
value: info.txAmount,
|
||||
type: "id"
|
||||
}]
|
||||
}
|
||||
await SuccessfulTransfers.create([usrSuccess], { session })
|
||||
}
|
||||
return PendingTransfers.findOne({ userId:userId }).session(session)
|
||||
.then(async (userPendinAfterSave) => {
|
||||
userPendinAfterSave.transactions = _.filter(userPendinAfterSave.transactions, (i) => { return i.txId.toString() !== txId.toString() })
|
||||
await userPendinAfterSave.save()
|
||||
let cur = _.find(user.wallet, (i) => { return i.currency.toString() === currencyId.toString()})
|
||||
if(cur) {
|
||||
cur.value +=info.txAmount
|
||||
await user.save()
|
||||
} else {
|
||||
user.wallet.push({
|
||||
currency: currencyId,
|
||||
value: info.txAmount
|
||||
})
|
||||
await user.save()
|
||||
}
|
||||
resObj = {
|
||||
status: 'successful',
|
||||
value: info.txAmount
|
||||
}
|
||||
}).catch((err)=>{
|
||||
throw err
|
||||
})
|
||||
}).catch((err)=>{
|
||||
throw err
|
||||
})
|
||||
} else {
|
||||
resObj = {
|
||||
status: 'pending',
|
||||
value: info.txAmount
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
throw err
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
throw err
|
||||
})
|
||||
|
||||
} else {
|
||||
const error = new myError(
|
||||
'currency not found',
|
||||
400,
|
||||
5,
|
||||
'ارز مربوطه پیدا نشد.',
|
||||
'خطا رخ داد'
|
||||
)
|
||||
throw error
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
throw err
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
throw err
|
||||
})
|
||||
} else {
|
||||
const error = new myError(
|
||||
'user not found',
|
||||
400,
|
||||
5,
|
||||
'کاربر پیدا نشد.',
|
||||
'خطا رخ داد'
|
||||
)
|
||||
throw error
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
throw err
|
||||
})
|
||||
})
|
||||
.then(() => {
|
||||
return resObj
|
||||
})
|
||||
.catch((err) => {
|
||||
throw ("error in with Transaction"+ ":" + err)
|
||||
})
|
||||
.finally(() => {
|
||||
session.endSession()
|
||||
})
|
||||
}
|
||||
|
||||
109
server/api/walletApi/tron.js
Executable file
109
server/api/walletApi/tron.js
Executable file
@@ -0,0 +1,109 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
exports.__esModule = true;
|
||||
exports.TRONTransferFrom = exports.validateByTXId = void 0;
|
||||
var tronWeb = require("tronweb");
|
||||
// export function TRONTransferTo(userId, systemAccount, userAccount, privateKey, amount){
|
||||
// User.findOne({ _id : userId })
|
||||
// .then((user) => {
|
||||
// if(user && user._id.toString() === userId.toString()){
|
||||
// const HttpProvider = tronWeb.providers.HttpProvider;
|
||||
// const fullNode = new HttpProvider("https://api.shasta.trongrid.io");
|
||||
// const solidityNode = new HttpProvider("https://api.shasta.trongrid.io");
|
||||
// const eventServer = new HttpProvider("https://api.shasta.trongrid.io");
|
||||
// const tw = new tronWeb(fullNode,solidityNode,eventServer,privateKey);
|
||||
// const am = amount * 1000000
|
||||
// tw.trx.getAccount(userAccount.toString()).then((usrAcc) =>{
|
||||
// if(usrAcc){
|
||||
// tw.trx.sendTransaction(systemAccount, am)
|
||||
// }else{
|
||||
// const error = "user Tron Account not fount"
|
||||
// console.log("Error in TRONTransferTo : ", error)
|
||||
// }
|
||||
// })
|
||||
// .catch((err) => console.log(err))
|
||||
// }else{
|
||||
// const error = 'user not fount'
|
||||
// console.log('Error in TRONTransferTo : ', error)
|
||||
// }
|
||||
// })
|
||||
// .catch((err) => console.log('Error in TRONTransferTo : ', err))
|
||||
// }
|
||||
function validateByTXId(hash) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var systemPrivateKey, HttpProvider, fullNode, solidityNode, eventServer, TronWeb;
|
||||
return __generator(this, function (_a) {
|
||||
systemPrivateKey = '4a8f251556d19ab6625c0cc012a3c534bf978e6a099d0bb8f42d6539579a10c5';
|
||||
HttpProvider = tronWeb.providers.HttpProvider;
|
||||
fullNode = new HttpProvider("https://api.shasta.trongrid.io");
|
||||
solidityNode = new HttpProvider("https://api.shasta.trongrid.io");
|
||||
eventServer = new HttpProvider("https://api.shasta.trongrid.io");
|
||||
TronWeb = new tronWeb(fullNode, solidityNode, eventServer, systemPrivateKey);
|
||||
console.log("here : ", TronWeb);
|
||||
TronWeb.trx.getTransaction(hash.toString())
|
||||
.then(function (transaction) {
|
||||
return transaction;
|
||||
})["catch"](function (err) { throw (err); });
|
||||
return [2 /*return*/];
|
||||
});
|
||||
});
|
||||
}
|
||||
exports.validateByTXId = validateByTXId;
|
||||
function TRONTransferFrom(destAccount, am) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var systemPrivateKey, amount, HttpProvider, fullNode, solidityNode, eventServer, TronWeb;
|
||||
return __generator(this, function (_a) {
|
||||
systemPrivateKey = '4a8f251556d19ab6625c0cc012a3c534bf978e6a099d0bb8f42d6539579a10c5';
|
||||
amount = am * 1000000;
|
||||
HttpProvider = tronWeb.providers.HttpProvider;
|
||||
fullNode = new HttpProvider("https://api.shasta.trongrid.io");
|
||||
solidityNode = new HttpProvider("https://api.shasta.trongrid.io");
|
||||
eventServer = new HttpProvider("https://api.shasta.trongrid.io");
|
||||
TronWeb = new tronWeb(fullNode, solidityNode, eventServer, systemPrivateKey);
|
||||
TronWeb.trx.sendTransaction(destAccount, amount)
|
||||
.then(function (transaction) {
|
||||
return transaction;
|
||||
})["catch"](function (err) {
|
||||
console.log("Error : ", err);
|
||||
throw (err);
|
||||
});
|
||||
return [2 /*return*/];
|
||||
});
|
||||
});
|
||||
}
|
||||
exports.TRONTransferFrom = TRONTransferFrom;
|
||||
80
server/api/walletApi/tron.ts
Executable file
80
server/api/walletApi/tron.ts
Executable file
@@ -0,0 +1,80 @@
|
||||
import * as tronWeb from 'tronweb'
|
||||
// import { Currencies } from '../db/currencies';
|
||||
// import { User } from '../db/user'
|
||||
import * as _ from 'lodash'
|
||||
|
||||
// export function TRONTransferTo(userId, systemAccount, userAccount, privateKey, amount){
|
||||
|
||||
// User.findOne({ _id : userId })
|
||||
// .then((user) => {
|
||||
|
||||
// if(user && user._id.toString() === userId.toString()){
|
||||
// const HttpProvider = tronWeb.providers.HttpProvider;
|
||||
// const fullNode = new HttpProvider("https://api.shasta.trongrid.io");
|
||||
// const solidityNode = new HttpProvider("https://api.shasta.trongrid.io");
|
||||
// const eventServer = new HttpProvider("https://api.shasta.trongrid.io");
|
||||
// const tw = new tronWeb(fullNode,solidityNode,eventServer,privateKey);
|
||||
// const am = amount * 1000000
|
||||
// tw.trx.getAccount(userAccount.toString()).then((usrAcc) =>{
|
||||
// if(usrAcc){
|
||||
// tw.trx.sendTransaction(systemAccount, am)
|
||||
|
||||
// }else{
|
||||
// const error = "user Tron Account not fount"
|
||||
// console.log("Error in TRONTransferTo : ", error)
|
||||
// }
|
||||
|
||||
// })
|
||||
// .catch((err) => console.log(err))
|
||||
|
||||
|
||||
// }else{
|
||||
// const error = 'user not fount'
|
||||
// console.log('Error in TRONTransferTo : ', error)
|
||||
// }
|
||||
|
||||
// })
|
||||
// .catch((err) => console.log('Error in TRONTransferTo : ', err))
|
||||
|
||||
// }
|
||||
|
||||
export async function validateByTXId(hash){
|
||||
|
||||
const systemPrivateKey = '4a8f251556d19ab6625c0cc012a3c534bf978e6a099d0bb8f42d6539579a10c5'
|
||||
|
||||
const HttpProvider = tronWeb.providers.HttpProvider;
|
||||
const fullNode = new HttpProvider("https://api.shasta.trongrid.io");
|
||||
const solidityNode = new HttpProvider("https://api.shasta.trongrid.io");
|
||||
const eventServer = new HttpProvider("https://api.shasta.trongrid.io");
|
||||
const TronWeb = new tronWeb(fullNode,solidityNode,eventServer,systemPrivateKey);
|
||||
console.log("here : ", TronWeb)
|
||||
TronWeb.trx.getTransaction(hash.toString())
|
||||
.then((transaction) => {
|
||||
return transaction
|
||||
})
|
||||
.catch((err) => {throw(err)})
|
||||
|
||||
}
|
||||
|
||||
|
||||
export async function TRONTransferFrom(destAccount, am){
|
||||
const systemPrivateKey = '4a8f251556d19ab6625c0cc012a3c534bf978e6a099d0bb8f42d6539579a10c5'
|
||||
const amount = am * 1000000
|
||||
|
||||
|
||||
const HttpProvider = tronWeb.providers.HttpProvider;
|
||||
const fullNode = new HttpProvider("https://api.shasta.trongrid.io");
|
||||
const solidityNode = new HttpProvider("https://api.shasta.trongrid.io");
|
||||
const eventServer = new HttpProvider("https://api.shasta.trongrid.io");
|
||||
const TronWeb = new tronWeb(fullNode,solidityNode,eventServer,systemPrivateKey);
|
||||
TronWeb.trx.sendTransaction(destAccount, amount)
|
||||
.then((transaction) => {
|
||||
|
||||
return transaction
|
||||
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("Error : ", err)
|
||||
throw(err)
|
||||
})
|
||||
}
|
||||
103725
server/combined.log
Executable file
103725
server/combined.log
Executable file
File diff suppressed because it is too large
Load Diff
51
server/db/acceptedOffers.js
Executable file
51
server/db/acceptedOffers.js
Executable file
@@ -0,0 +1,51 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.Accepted_Offers = void 0;
|
||||
var mongoose = require("mongoose");
|
||||
var schemaOptions = {
|
||||
timestamps: { createdAt: 'created_at' }
|
||||
};
|
||||
var acceptedOffers = new mongoose.Schema({
|
||||
buyOrderId: {
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
acceptor: {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
creator: {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
offerId: {
|
||||
type: String,
|
||||
required: true,
|
||||
unique: true
|
||||
},
|
||||
curGivenId: {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
curGivenVal: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
curTakenId: {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
curTakenVal: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
offeredDate: {
|
||||
type: Date,
|
||||
required: true
|
||||
},
|
||||
expiredDate: {
|
||||
type: Date,
|
||||
required: true
|
||||
}
|
||||
}, schemaOptions);
|
||||
exports.Accepted_Offers = mongoose.model('AcceptedOffers', acceptedOffers);
|
||||
57
server/db/acceptedOffers.ts
Executable file
57
server/db/acceptedOffers.ts
Executable file
@@ -0,0 +1,57 @@
|
||||
import * as mongoose from 'mongoose'
|
||||
|
||||
const schemaOptions = {
|
||||
timestamps: { createdAt: 'created_at' },
|
||||
};
|
||||
const acceptedOffers = new mongoose.Schema({
|
||||
|
||||
buyOrderId:{
|
||||
type: String,
|
||||
required: false,
|
||||
},
|
||||
|
||||
acceptor : {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
creator: {
|
||||
type:mongoose.ObjectId,
|
||||
|
||||
required:true,
|
||||
},
|
||||
offerId: {
|
||||
type: String,
|
||||
required: true,
|
||||
unique: true
|
||||
},
|
||||
curGivenId:{
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
curGivenVal:{
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
curTakenId:{
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
curTakenVal:{
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
offeredDate:{
|
||||
type:Date,
|
||||
required: true,
|
||||
},
|
||||
expiredDate:{
|
||||
type:Date,
|
||||
required: true,
|
||||
},
|
||||
|
||||
}, schemaOptions )
|
||||
|
||||
|
||||
export const Accepted_Offers = mongoose.model('AcceptedOffers', acceptedOffers)
|
||||
|
||||
|
||||
46
server/db/activeOffers.js
Executable file
46
server/db/activeOffers.js
Executable file
@@ -0,0 +1,46 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.Active_Offers = void 0;
|
||||
var mongoose = require("mongoose");
|
||||
var schemaOptions = {
|
||||
timestamps: { createdAt: 'created_at' }
|
||||
};
|
||||
var activeOffers = new mongoose.Schema({
|
||||
userId: {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
offerId: {
|
||||
type: String,
|
||||
required: true,
|
||||
unique: true
|
||||
},
|
||||
rank: {
|
||||
type: Number,
|
||||
min: 1,
|
||||
max: 5,
|
||||
"default": 1
|
||||
},
|
||||
curGivenId: {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
curGivenVal: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
curTakenId: {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
curTakenVal: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
expDate: {
|
||||
type: Date,
|
||||
required: true,
|
||||
"default": Date.now()
|
||||
}
|
||||
}, schemaOptions);
|
||||
exports.Active_Offers = mongoose.models.ActiveOffers || mongoose.model('ActiveOffers', activeOffers);
|
||||
49
server/db/activeOffers.ts
Executable file
49
server/db/activeOffers.ts
Executable file
@@ -0,0 +1,49 @@
|
||||
import * as mongoose from 'mongoose'
|
||||
|
||||
const schemaOptions = {
|
||||
timestamps: { createdAt: 'created_at' },
|
||||
};
|
||||
|
||||
const activeOffers = new mongoose.Schema({
|
||||
|
||||
userId : {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
offerId:{
|
||||
type: String,
|
||||
required: true,
|
||||
unique: true
|
||||
},
|
||||
rank: {
|
||||
type: Number,
|
||||
min: 1,
|
||||
max: 5,
|
||||
default: 1
|
||||
},
|
||||
curGivenId:{
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
curGivenVal:{
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
curTakenId:{
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
curTakenVal:{
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
expDate:{
|
||||
type:Date,
|
||||
required: true,
|
||||
default: Date.now()
|
||||
}
|
||||
}, schemaOptions )
|
||||
|
||||
|
||||
|
||||
export const Active_Offers = mongoose.models.ActiveOffers || mongoose.model('ActiveOffers', activeOffers)
|
||||
108
server/db/admin.js
Executable file
108
server/db/admin.js
Executable file
@@ -0,0 +1,108 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.Admin = void 0;
|
||||
var mongoose = require("mongoose");
|
||||
var bcrypt = require("bcrypt");
|
||||
var adminSchema = new mongoose.Schema({
|
||||
name: {
|
||||
type: String
|
||||
},
|
||||
lastName: {
|
||||
type: String
|
||||
},
|
||||
email: {
|
||||
type: String,
|
||||
required: true,
|
||||
trim: true,
|
||||
unique: 1
|
||||
},
|
||||
isActive: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
"default": true
|
||||
},
|
||||
password: {
|
||||
type: String,
|
||||
required: true,
|
||||
minlength: 6,
|
||||
trim: true
|
||||
},
|
||||
role: {
|
||||
type: String,
|
||||
required: true,
|
||||
"enum": ['Admin', 'Manager', 'Supporter']
|
||||
},
|
||||
wallet: [
|
||||
{
|
||||
currency: {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
value: {
|
||||
type: Number,
|
||||
required: true,
|
||||
"default": 0
|
||||
}
|
||||
}
|
||||
],
|
||||
adminActivities: [
|
||||
{
|
||||
action: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
timestamp: {
|
||||
type: Date
|
||||
},
|
||||
device: {
|
||||
type: String
|
||||
},
|
||||
loginDeviceId: {},
|
||||
ip: {
|
||||
type: String
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
// This functions will execute if the password field is modified.
|
||||
adminSchema.pre('save', function (next) {
|
||||
var user = this;
|
||||
if (user.isModified('password')) {
|
||||
bcrypt.genSalt(Number(process.env.SALT_I))
|
||||
.then(function (salt) {
|
||||
bcrypt.hash(user.password, salt)
|
||||
.then(function (hash) {
|
||||
user.password = hash;
|
||||
next();
|
||||
})["catch"](function (err) {
|
||||
next(err);
|
||||
});
|
||||
})["catch"](function (err) {
|
||||
next(err);
|
||||
});
|
||||
}
|
||||
else {
|
||||
next();
|
||||
}
|
||||
});
|
||||
// This method compares the password which is stored in database and
|
||||
// the password which the user entered. It is used in Login.
|
||||
adminSchema.methods.comparePassword = function (candidatePassword, cb) {
|
||||
bcrypt.compare(candidatePassword, this.password, function (err, isMatch) {
|
||||
if (err)
|
||||
return cb(err);
|
||||
cb(null, isMatch);
|
||||
});
|
||||
};
|
||||
adminSchema.methods.comparePasswordPromise = function (candidatePassword) {
|
||||
var _this = this;
|
||||
return new Promise(function (resolve, reject) {
|
||||
bcrypt.compare(candidatePassword, _this.password)
|
||||
.then(function (isMatch) {
|
||||
resolve(isMatch);
|
||||
})["catch"](function (err) {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
exports.Admin = mongoose.model('Admin', adminSchema);
|
||||
111
server/db/admin.ts
Executable file
111
server/db/admin.ts
Executable file
@@ -0,0 +1,111 @@
|
||||
import * as mongoose from 'mongoose'
|
||||
import * as bcrypt from 'bcrypt'
|
||||
|
||||
|
||||
const adminSchema = new mongoose.Schema({
|
||||
name: {
|
||||
type: String
|
||||
},
|
||||
lastName: {
|
||||
type: String
|
||||
},
|
||||
email: {
|
||||
type: String,
|
||||
required: true,
|
||||
trim: true,
|
||||
unique: 1
|
||||
},
|
||||
isActive: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: true
|
||||
},
|
||||
password: {
|
||||
type: String,
|
||||
required: true,
|
||||
minlength: 6,
|
||||
trim: true
|
||||
},
|
||||
role: {
|
||||
type: String,
|
||||
required: true,
|
||||
enum: ['Admin', 'Manager', 'Supporter']
|
||||
},
|
||||
wallet: [
|
||||
{
|
||||
currency: {
|
||||
type:mongoose.ObjectId,
|
||||
required:true,
|
||||
},
|
||||
value: {
|
||||
type:Number,
|
||||
required:true,
|
||||
default:0,
|
||||
}
|
||||
}
|
||||
],
|
||||
adminActivities: [
|
||||
{
|
||||
action: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
timestamp: {
|
||||
type: Date
|
||||
},
|
||||
device: {
|
||||
type: String
|
||||
},
|
||||
loginDeviceId: {},
|
||||
ip: {
|
||||
type: String
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// This functions will execute if the password field is modified.
|
||||
adminSchema.pre('save', function (next) {
|
||||
var user = this
|
||||
if (user.isModified('password')) {
|
||||
bcrypt.genSalt(Number(process.env.SALT_I))
|
||||
.then((salt) => {
|
||||
bcrypt.hash(user.password, salt)
|
||||
.then((hash) => {
|
||||
user.password = hash
|
||||
next()
|
||||
})
|
||||
.catch((err) => {
|
||||
next(err)
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
next(err)
|
||||
})
|
||||
} else {
|
||||
next()
|
||||
}
|
||||
})
|
||||
|
||||
// This method compares the password which is stored in database and
|
||||
// the password which the user entered. It is used in Login.
|
||||
adminSchema.methods.comparePassword = function (candidatePassword, cb) {
|
||||
bcrypt.compare(candidatePassword, this.password, function (err, isMatch) {
|
||||
if (err) return cb(err)
|
||||
cb(null, isMatch)
|
||||
})
|
||||
}
|
||||
|
||||
adminSchema.methods.comparePasswordPromise = function (candidatePassword) {
|
||||
return new Promise((resolve, reject) => {
|
||||
bcrypt.compare(candidatePassword, this.password)
|
||||
.then(function(isMatch) {
|
||||
resolve(isMatch)
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export const Admin = mongoose.model('Admin', adminSchema)
|
||||
42
server/db/buyOrder.ts
Executable file
42
server/db/buyOrder.ts
Executable file
@@ -0,0 +1,42 @@
|
||||
import * as mongoose from 'mongoose'
|
||||
const schemaOptions = {
|
||||
timestamps: { createdAt: 'created_at' },
|
||||
};
|
||||
const buyOrder = new mongoose.Schema({
|
||||
currencyId : {
|
||||
type : mongoose.ObjectId,
|
||||
required : true,
|
||||
}
|
||||
,
|
||||
id:{
|
||||
type: String,
|
||||
required: true,
|
||||
unique: true
|
||||
},
|
||||
|
||||
|
||||
transferredValue : {
|
||||
type : Number,
|
||||
required : true,
|
||||
default : 0,
|
||||
},
|
||||
|
||||
userId : {
|
||||
type : mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
value : {
|
||||
type : Number,
|
||||
//required : true,
|
||||
//default : 0,
|
||||
},
|
||||
shouldBuyValue : {
|
||||
type: Number,
|
||||
required : true,
|
||||
default : 0,
|
||||
}
|
||||
|
||||
|
||||
},schemaOptions)
|
||||
export const BuyOrder = mongoose.model('buyOrder', buyOrder)
|
||||
|
||||
24
server/db/continuesPriceStats.js
Executable file
24
server/db/continuesPriceStats.js
Executable file
@@ -0,0 +1,24 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.ContinuesPriceStat = void 0;
|
||||
var mongoose = require("mongoose");
|
||||
var continuesPriceStat = new mongoose.Schema({
|
||||
name: {
|
||||
type: String,
|
||||
required: true,
|
||||
unique: true
|
||||
},
|
||||
currencyPriceHistory: [
|
||||
{
|
||||
currencyId: {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
price: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
exports.ContinuesPriceStat = mongoose.model('continuesPriceStat', continuesPriceStat);
|
||||
25
server/db/continuesPriceStats.ts
Executable file
25
server/db/continuesPriceStats.ts
Executable file
@@ -0,0 +1,25 @@
|
||||
import * as mongoose from 'mongoose'
|
||||
|
||||
const continuesPriceStat = new mongoose.Schema({
|
||||
name:{
|
||||
type:String,
|
||||
required:true,
|
||||
unique: true,
|
||||
},
|
||||
currencyPriceHistory:[
|
||||
{
|
||||
currencyId : {
|
||||
type : mongoose.ObjectId,
|
||||
required:true,
|
||||
},
|
||||
price: {
|
||||
type : Number,
|
||||
required:true
|
||||
}
|
||||
|
||||
}
|
||||
]
|
||||
|
||||
})
|
||||
|
||||
export const ContinuesPriceStat = mongoose.model('continuesPriceStat', continuesPriceStat)
|
||||
36
server/db/currencies.js
Executable file
36
server/db/currencies.js
Executable file
@@ -0,0 +1,36 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.Currencies = void 0;
|
||||
var mongoose = require("mongoose");
|
||||
var currencies = new mongoose.Schema({
|
||||
name: {
|
||||
type: String,
|
||||
required: true,
|
||||
"enum": ['RIAL', 'BITCOIN', 'TRON', 'ETHEREUM'],
|
||||
unique: true
|
||||
},
|
||||
per_name: {
|
||||
type: String,
|
||||
required: true,
|
||||
"enum": ['ریال', 'بیت کوین', 'ترون', 'اتریوم'],
|
||||
unique: true
|
||||
},
|
||||
ab_name: {
|
||||
type: String,
|
||||
required: true,
|
||||
"enum": ['IRR', 'BTC', 'TRX', 'ETH'],
|
||||
unique: true
|
||||
},
|
||||
icon: {
|
||||
type: String
|
||||
},
|
||||
quantity: {
|
||||
type: Number,
|
||||
//required: true,
|
||||
"default": 0
|
||||
}
|
||||
// value:{
|
||||
// type:Number,
|
||||
// },
|
||||
});
|
||||
exports.Currencies = mongoose.model('currencies', currencies);
|
||||
37
server/db/currencies.ts
Executable file
37
server/db/currencies.ts
Executable file
@@ -0,0 +1,37 @@
|
||||
import * as mongoose from 'mongoose'
|
||||
|
||||
const currencies = new mongoose.Schema({
|
||||
name:{
|
||||
type:String,
|
||||
required:true,
|
||||
enum: ['RIAL', 'BITCOIN', 'TRON', 'ETHEREUM'],
|
||||
unique: true,
|
||||
},
|
||||
per_name:{
|
||||
type:String,
|
||||
required:true,
|
||||
enum:['ریال', 'بیت کوین','ترون','اتریوم'],
|
||||
unique: true,
|
||||
},
|
||||
ab_name:{
|
||||
type:String,
|
||||
required:true,
|
||||
enum: ['IRR', 'BTC', 'TRX', 'ETH'],
|
||||
unique: true,
|
||||
},
|
||||
icon:{
|
||||
type:String,
|
||||
//required:true,
|
||||
//unique: true,
|
||||
},
|
||||
quantity:{
|
||||
type: Number,
|
||||
//required: true,
|
||||
default: 0
|
||||
}
|
||||
// value:{
|
||||
// type:Number,
|
||||
// },
|
||||
})
|
||||
|
||||
export const Currencies = mongoose.model('currencies', currencies)
|
||||
28
server/db/dailyPriceStats.js
Executable file
28
server/db/dailyPriceStats.js
Executable file
@@ -0,0 +1,28 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.DailyPriceStat = void 0;
|
||||
var mongoose = require("mongoose");
|
||||
var dailyPriceStat = new mongoose.Schema({
|
||||
name: {
|
||||
type: String,
|
||||
required: true,
|
||||
unique: true
|
||||
},
|
||||
currencyPriceHistory: [
|
||||
{
|
||||
currencyId: {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
price: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
volume: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
exports.DailyPriceStat = mongoose.model('dailyPriceStat', dailyPriceStat);
|
||||
28
server/db/dailyPriceStats.ts
Executable file
28
server/db/dailyPriceStats.ts
Executable file
@@ -0,0 +1,28 @@
|
||||
import * as mongoose from 'mongoose'
|
||||
|
||||
const dailyPriceStat = new mongoose.Schema({
|
||||
name:{
|
||||
type:String,
|
||||
required:true,
|
||||
unique: true
|
||||
},
|
||||
currencyPriceHistory:[
|
||||
{
|
||||
currencyId : {
|
||||
type : mongoose.ObjectId,
|
||||
required:true
|
||||
},
|
||||
price: {
|
||||
type : Number,
|
||||
required:true
|
||||
},
|
||||
volume:{
|
||||
type: Number,
|
||||
required : true
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
})
|
||||
|
||||
export const DailyPriceStat = mongoose.model('dailyPriceStat', dailyPriceStat)
|
||||
41
server/db/failedTransfers.ts
Executable file
41
server/db/failedTransfers.ts
Executable file
@@ -0,0 +1,41 @@
|
||||
import * as mongoose from 'mongoose'
|
||||
|
||||
const schemaOptions = {
|
||||
timestamps: { createdAt: 'created_at' },
|
||||
};
|
||||
const failedTransfers = new mongoose.Schema({
|
||||
|
||||
|
||||
|
||||
userId : {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
transactions:[
|
||||
{
|
||||
txId:{
|
||||
type : String,
|
||||
required : true
|
||||
},
|
||||
currencyId : {
|
||||
type : mongoose.ObjectId,
|
||||
required : true
|
||||
},
|
||||
currencyName : {
|
||||
type : String
|
||||
},
|
||||
value:{
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
type:{
|
||||
type:String,
|
||||
required:true,
|
||||
enum: ['send','receive'],
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
]
|
||||
}, schemaOptions )
|
||||
export const FailedTransfers = mongoose.model('FailedTransfers', failedTransfers)
|
||||
25
server/db/getPrice.js
Executable file
25
server/db/getPrice.js
Executable file
@@ -0,0 +1,25 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.GetPrice = void 0;
|
||||
var mongodb_1 = require("mongodb");
|
||||
var mongoose = require("mongoose");
|
||||
var getPrice = new mongoose.Schema({
|
||||
currency: {
|
||||
type: mongodb_1.ObjectID,
|
||||
required: true
|
||||
},
|
||||
userId: {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
quantity: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
rialPricePerUnit: {
|
||||
type: Number,
|
||||
"default": 0
|
||||
},
|
||||
createdAt: { type: Date, expires: 20, "default": Date.now }
|
||||
}, { timestamp: true });
|
||||
exports.GetPrice = mongoose.model('getPrice', getPrice);
|
||||
24
server/db/getPrice.ts
Executable file
24
server/db/getPrice.ts
Executable file
@@ -0,0 +1,24 @@
|
||||
import { ObjectID } from 'mongodb'
|
||||
import * as mongoose from 'mongoose'
|
||||
|
||||
const getPrice = new mongoose.Schema({
|
||||
currency: {
|
||||
type:ObjectID,
|
||||
required: true
|
||||
},
|
||||
userId : {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
quantity: {
|
||||
type:Number,
|
||||
required: true
|
||||
},
|
||||
rialPricePerUnit: {
|
||||
type:Number,
|
||||
default: 0
|
||||
},
|
||||
createdAt: { type: Date, expires: 20, default: Date.now }
|
||||
},{ timestamp: true })
|
||||
|
||||
export const GetPrice = mongoose.model('getPrice', getPrice)
|
||||
26
server/db/globalDailyPrice.js
Executable file
26
server/db/globalDailyPrice.js
Executable file
@@ -0,0 +1,26 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.GlobalDailyPrice = void 0;
|
||||
var mongoose = require("mongoose");
|
||||
var globalDailyPriceSchema = new mongoose.Schema({
|
||||
timeStamp: {
|
||||
type: Date
|
||||
},
|
||||
currencyId: {
|
||||
type: mongoose.ObjectId
|
||||
},
|
||||
price: {
|
||||
price: {
|
||||
type: Number
|
||||
},
|
||||
min: { type: Number },
|
||||
max: { type: Number }
|
||||
},
|
||||
volume: {
|
||||
type: Number
|
||||
}
|
||||
});
|
||||
// This functions will execute if the password field is modified.
|
||||
// This method compares the password which is stored in database and
|
||||
// the password which the user entered. It is used in Login.
|
||||
exports.GlobalDailyPrice = mongoose.model('GlobalDailyPrice', globalDailyPriceSchema);
|
||||
33
server/db/globalDailyPrice.ts
Executable file
33
server/db/globalDailyPrice.ts
Executable file
@@ -0,0 +1,33 @@
|
||||
import * as mongoose from 'mongoose'
|
||||
import * as bcrypt from 'bcrypt'
|
||||
|
||||
|
||||
|
||||
const globalDailyPriceSchema = new mongoose.Schema({
|
||||
timeStamp: {
|
||||
type: Date
|
||||
},
|
||||
currencyId: {
|
||||
type: mongoose.ObjectId
|
||||
},
|
||||
price:{
|
||||
price : {
|
||||
type: Number}
|
||||
,min : { type : Number},
|
||||
max : {type : Number},
|
||||
|
||||
|
||||
},
|
||||
volume : {
|
||||
type : Number
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
// This functions will execute if the password field is modified.
|
||||
|
||||
|
||||
// This method compares the password which is stored in database and
|
||||
// the password which the user entered. It is used in Login.
|
||||
|
||||
export const GlobalDailyPrice = mongoose.model('GlobalDailyPrice', globalDailyPriceSchema)
|
||||
30
server/db/globalHourlyPrice.js
Executable file
30
server/db/globalHourlyPrice.js
Executable file
@@ -0,0 +1,30 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.GlobalHourlyPrice = void 0;
|
||||
var mongoose = require("mongoose");
|
||||
var globalHourlyPriceSchema = new mongoose.Schema({
|
||||
timeStamp: {
|
||||
type: Date
|
||||
},
|
||||
currencyId: {
|
||||
type: mongoose.ObjectId
|
||||
},
|
||||
price: {
|
||||
price: {
|
||||
type: Number
|
||||
},
|
||||
min: {
|
||||
type: Number
|
||||
},
|
||||
max: {
|
||||
type: Number
|
||||
}
|
||||
},
|
||||
volume: {
|
||||
type: Number
|
||||
}
|
||||
});
|
||||
// This functions will execute if the password field is modified.
|
||||
// This method compares the password which is stored in database and
|
||||
// the password which the user entered. It is used in Login.
|
||||
exports.GlobalHourlyPrice = mongoose.model('GlobalHourlyPrice', globalHourlyPriceSchema);
|
||||
38
server/db/globalHourlyPrice.ts
Executable file
38
server/db/globalHourlyPrice.ts
Executable file
@@ -0,0 +1,38 @@
|
||||
import * as mongoose from 'mongoose'
|
||||
import * as bcrypt from 'bcrypt'
|
||||
|
||||
|
||||
|
||||
const globalHourlyPriceSchema = new mongoose.Schema({
|
||||
timeStamp: {
|
||||
type: Date
|
||||
},
|
||||
currencyId: {
|
||||
type: mongoose.ObjectId
|
||||
},
|
||||
price:{
|
||||
price :
|
||||
{
|
||||
type: Number
|
||||
},
|
||||
min :{
|
||||
type: Number
|
||||
},
|
||||
max: {
|
||||
type: Number
|
||||
}
|
||||
|
||||
},
|
||||
volume : {
|
||||
type : Number
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
// This functions will execute if the password field is modified.
|
||||
|
||||
|
||||
// This method compares the password which is stored in database and
|
||||
// the password which the user entered. It is used in Login.
|
||||
|
||||
export const GlobalHourlyPrice = mongoose.model('GlobalHourlyPrice', globalHourlyPriceSchema)
|
||||
30
server/db/globalMontlyPrice.js
Executable file
30
server/db/globalMontlyPrice.js
Executable file
@@ -0,0 +1,30 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.GlobalMonthlyPrice = void 0;
|
||||
var mongoose = require("mongoose");
|
||||
var globalMonthlyPriceSchema = new mongoose.Schema({
|
||||
timeStamp: {
|
||||
type: Date
|
||||
},
|
||||
currencyId: {
|
||||
type: mongoose.ObjectId
|
||||
},
|
||||
price: {
|
||||
price: {
|
||||
type: Number
|
||||
},
|
||||
min: {
|
||||
type: Number
|
||||
},
|
||||
max: {
|
||||
type: Number
|
||||
}
|
||||
},
|
||||
volume: {
|
||||
type: Number
|
||||
}
|
||||
});
|
||||
// This functions will execute if the password field is modified.
|
||||
// This method compares the password which is stored in database and
|
||||
// the password which the user entered. It is used in Login.
|
||||
exports.GlobalMonthlyPrice = mongoose.model('GlobalMonthlyPrice', globalMonthlyPriceSchema);
|
||||
38
server/db/globalMontlyPrice.ts
Executable file
38
server/db/globalMontlyPrice.ts
Executable file
@@ -0,0 +1,38 @@
|
||||
import * as mongoose from 'mongoose'
|
||||
import * as bcrypt from 'bcrypt'
|
||||
|
||||
|
||||
|
||||
const globalMonthlyPriceSchema = new mongoose.Schema({
|
||||
timeStamp: {
|
||||
type: Date
|
||||
},
|
||||
currencyId: {
|
||||
type: mongoose.ObjectId
|
||||
},
|
||||
price:{
|
||||
price :
|
||||
{
|
||||
type: Number
|
||||
},
|
||||
min :{
|
||||
type: Number
|
||||
},
|
||||
max: {
|
||||
type: Number
|
||||
}
|
||||
|
||||
},
|
||||
volume : {
|
||||
type : Number
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
// This functions will execute if the password field is modified.
|
||||
|
||||
|
||||
// This method compares the password which is stored in database and
|
||||
// the password which the user entered. It is used in Login.
|
||||
|
||||
export const GlobalMonthlyPrice = mongoose.model('GlobalMonthlyPrice', globalMonthlyPriceSchema)
|
||||
30
server/db/globalWeeklyPrice.js
Executable file
30
server/db/globalWeeklyPrice.js
Executable file
@@ -0,0 +1,30 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.GlobalWeeklyPrice = void 0;
|
||||
var mongoose = require("mongoose");
|
||||
var globalWeeklyPriceSchema = new mongoose.Schema({
|
||||
timeStamp: {
|
||||
type: Date
|
||||
},
|
||||
currencyId: {
|
||||
type: mongoose.ObjectId
|
||||
},
|
||||
price: {
|
||||
price: {
|
||||
type: Number
|
||||
},
|
||||
min: {
|
||||
type: Number
|
||||
},
|
||||
max: {
|
||||
type: Number
|
||||
}
|
||||
},
|
||||
volume: {
|
||||
type: Number
|
||||
}
|
||||
});
|
||||
// This functions will execute if the password field is modified.
|
||||
// This method compares the password which is stored in database and
|
||||
// the password which the user entered. It is used in Login.
|
||||
exports.GlobalWeeklyPrice = mongoose.model('GlobalWeeklyPrice', globalWeeklyPriceSchema);
|
||||
38
server/db/globalWeeklyPrice.ts
Executable file
38
server/db/globalWeeklyPrice.ts
Executable file
@@ -0,0 +1,38 @@
|
||||
import * as mongoose from 'mongoose'
|
||||
import * as bcrypt from 'bcrypt'
|
||||
|
||||
|
||||
|
||||
const globalWeeklyPriceSchema = new mongoose.Schema({
|
||||
timeStamp: {
|
||||
type: Date
|
||||
},
|
||||
currencyId: {
|
||||
type: mongoose.ObjectId
|
||||
},
|
||||
price:{
|
||||
price :
|
||||
{
|
||||
type: Number
|
||||
},
|
||||
min :{
|
||||
type: Number
|
||||
},
|
||||
max: {
|
||||
type: Number
|
||||
}
|
||||
|
||||
},
|
||||
volume : {
|
||||
type : Number
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
// This functions will execute if the password field is modified.
|
||||
|
||||
|
||||
// This method compares the password which is stored in database and
|
||||
// the password which the user entered. It is used in Login.
|
||||
|
||||
export const GlobalWeeklyPrice = mongoose.model('GlobalWeeklyPrice', globalWeeklyPriceSchema)
|
||||
30
server/db/globalYearlyPrice.js
Executable file
30
server/db/globalYearlyPrice.js
Executable file
@@ -0,0 +1,30 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.GlobalYearlyPrice = void 0;
|
||||
var mongoose = require("mongoose");
|
||||
var globalYearlyPriceSchema = new mongoose.Schema({
|
||||
timeStamp: {
|
||||
type: Date
|
||||
},
|
||||
currencyId: {
|
||||
type: mongoose.ObjectId
|
||||
},
|
||||
price: {
|
||||
price: {
|
||||
type: Number
|
||||
},
|
||||
min: {
|
||||
type: Number
|
||||
},
|
||||
max: {
|
||||
type: Number
|
||||
}
|
||||
},
|
||||
volume: {
|
||||
type: Number
|
||||
}
|
||||
});
|
||||
// This functions will execute if the password field is modified.
|
||||
// This method compares the password which is stored in database and
|
||||
// the password which the user entered. It is used in Login.
|
||||
exports.GlobalYearlyPrice = mongoose.model('GlobalYearlyPrice', globalYearlyPriceSchema);
|
||||
38
server/db/globalYearlyPrice.ts
Executable file
38
server/db/globalYearlyPrice.ts
Executable file
@@ -0,0 +1,38 @@
|
||||
import * as mongoose from 'mongoose'
|
||||
import * as bcrypt from 'bcrypt'
|
||||
|
||||
|
||||
|
||||
const globalYearlyPriceSchema = new mongoose.Schema({
|
||||
timeStamp: {
|
||||
type: Date
|
||||
},
|
||||
currencyId: {
|
||||
type: mongoose.ObjectId
|
||||
},
|
||||
price:{
|
||||
price :
|
||||
{
|
||||
type: Number
|
||||
},
|
||||
min :{
|
||||
type: Number
|
||||
},
|
||||
max: {
|
||||
type: Number
|
||||
}
|
||||
|
||||
},
|
||||
volume : {
|
||||
type : Number
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
// This functions will execute if the password field is modified.
|
||||
|
||||
|
||||
// This method compares the password which is stored in database and
|
||||
// the password which the user entered. It is used in Login.
|
||||
|
||||
export const GlobalYearlyPrice = mongoose.model('GlobalYearlyPrice', globalYearlyPriceSchema)
|
||||
38
server/db/localDaily.js
Executable file
38
server/db/localDaily.js
Executable file
@@ -0,0 +1,38 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.LocalDaily = void 0;
|
||||
var mongoose = require("mongoose");
|
||||
var schemaOptions = {
|
||||
timestamps: { createdAt: 'created_at' }
|
||||
};
|
||||
var localDaily = new mongoose.Schema({
|
||||
name: {
|
||||
type: Date,
|
||||
required: true
|
||||
},
|
||||
currencies: [
|
||||
{
|
||||
currencyId: {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
price: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
volume: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
min: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
max: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
]
|
||||
}, schemaOptions);
|
||||
exports.LocalDaily = mongoose.model('localDaily', localDaily);
|
||||
45
server/db/localDaily.ts
Executable file
45
server/db/localDaily.ts
Executable file
@@ -0,0 +1,45 @@
|
||||
import { ObjectID } from 'mongodb'
|
||||
import * as mongoose from 'mongoose'
|
||||
|
||||
const schemaOptions = {
|
||||
timestamps: { createdAt: 'created_at' },
|
||||
};
|
||||
|
||||
const localDaily = new mongoose.Schema({
|
||||
|
||||
|
||||
name:{
|
||||
type: Date,
|
||||
required: true,
|
||||
},
|
||||
currencies:[
|
||||
{
|
||||
currencyId:{
|
||||
type: mongoose.ObjectId,
|
||||
required: true,
|
||||
},
|
||||
|
||||
price:{
|
||||
type:Number,
|
||||
required: true,
|
||||
|
||||
},
|
||||
volume:{
|
||||
type: Number,
|
||||
required: true,
|
||||
|
||||
},
|
||||
min:{
|
||||
type: Number,
|
||||
required: true,
|
||||
|
||||
},
|
||||
max:{
|
||||
type: Number,
|
||||
required: true,
|
||||
}
|
||||
}]
|
||||
|
||||
}, schemaOptions)
|
||||
|
||||
export const LocalDaily = mongoose.model('localDaily', localDaily)
|
||||
38
server/db/localHourly.js
Executable file
38
server/db/localHourly.js
Executable file
@@ -0,0 +1,38 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.LocalHourly = void 0;
|
||||
var mongoose = require("mongoose");
|
||||
var schemaOptions = {
|
||||
timestamps: { createdAt: 'created_at' }
|
||||
};
|
||||
var localHourly = new mongoose.Schema({
|
||||
name: {
|
||||
type: Date,
|
||||
required: true
|
||||
},
|
||||
currencies: [
|
||||
{
|
||||
currencyId: {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
price: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
volume: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
min: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
max: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
]
|
||||
}, schemaOptions);
|
||||
exports.LocalHourly = mongoose.model('localHourly', localHourly);
|
||||
42
server/db/localHourly.ts
Executable file
42
server/db/localHourly.ts
Executable file
@@ -0,0 +1,42 @@
|
||||
import * as mongoose from 'mongoose'
|
||||
|
||||
const schemaOptions = {
|
||||
timestamps: { createdAt: 'created_at' },
|
||||
};
|
||||
|
||||
const localHourly = new mongoose.Schema({
|
||||
name:{
|
||||
type: Date,
|
||||
required: true,
|
||||
},
|
||||
currencies:[
|
||||
{
|
||||
currencyId:{
|
||||
type: mongoose.ObjectId,
|
||||
required: true,
|
||||
},
|
||||
|
||||
price:{
|
||||
type:Number,
|
||||
required: true,
|
||||
|
||||
},
|
||||
volume:{
|
||||
type: Number,
|
||||
required: true,
|
||||
|
||||
},
|
||||
min:{
|
||||
type: Number,
|
||||
required: true,
|
||||
|
||||
},
|
||||
max:{
|
||||
type: Number,
|
||||
required: true,
|
||||
}
|
||||
}]
|
||||
|
||||
}, schemaOptions)
|
||||
|
||||
export const LocalHourly = mongoose.model('localHourly', localHourly)
|
||||
38
server/db/localMonthly.js
Executable file
38
server/db/localMonthly.js
Executable file
@@ -0,0 +1,38 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.LocalMonthly = void 0;
|
||||
var mongoose = require("mongoose");
|
||||
var schemaOptions = {
|
||||
timestamps: { createdAt: 'created_at' }
|
||||
};
|
||||
var localMonthly = new mongoose.Schema({
|
||||
name: {
|
||||
type: Date,
|
||||
required: true
|
||||
},
|
||||
currencies: [
|
||||
{
|
||||
currencyId: {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
price: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
volume: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
min: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
max: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
]
|
||||
}, schemaOptions);
|
||||
exports.LocalMonthly = mongoose.model('localMonthly', localMonthly);
|
||||
45
server/db/localMonthly.ts
Executable file
45
server/db/localMonthly.ts
Executable file
@@ -0,0 +1,45 @@
|
||||
import { ObjectID } from 'mongodb'
|
||||
import * as mongoose from 'mongoose'
|
||||
|
||||
const schemaOptions = {
|
||||
timestamps: { createdAt: 'created_at' },
|
||||
};
|
||||
|
||||
const localMonthly = new mongoose.Schema({
|
||||
|
||||
|
||||
name:{
|
||||
type: Date,
|
||||
required: true,
|
||||
},
|
||||
currencies:[
|
||||
{
|
||||
currencyId:{
|
||||
type: mongoose.ObjectId,
|
||||
required: true,
|
||||
},
|
||||
|
||||
price:{
|
||||
type:Number,
|
||||
required: true,
|
||||
|
||||
},
|
||||
volume:{
|
||||
type: Number,
|
||||
required: true,
|
||||
|
||||
},
|
||||
min:{
|
||||
type: Number,
|
||||
required: true,
|
||||
|
||||
},
|
||||
max:{
|
||||
type: Number,
|
||||
required: true,
|
||||
}
|
||||
}]
|
||||
|
||||
}, schemaOptions)
|
||||
|
||||
export const LocalMonthly = mongoose.model('localMonthly', localMonthly)
|
||||
38
server/db/localWeekly.js
Executable file
38
server/db/localWeekly.js
Executable file
@@ -0,0 +1,38 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.LocalWeekly = void 0;
|
||||
var mongoose = require("mongoose");
|
||||
var schemaOptions = {
|
||||
timestamps: { createdAt: 'created_at' }
|
||||
};
|
||||
var localWeekly = new mongoose.Schema({
|
||||
name: {
|
||||
type: Date,
|
||||
required: true
|
||||
},
|
||||
currencies: [
|
||||
{
|
||||
currencyId: {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
price: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
volume: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
min: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
max: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
]
|
||||
}, schemaOptions);
|
||||
exports.LocalWeekly = mongoose.model('localWeekly', localWeekly);
|
||||
45
server/db/localWeekly.ts
Executable file
45
server/db/localWeekly.ts
Executable file
@@ -0,0 +1,45 @@
|
||||
import { ObjectID } from 'mongodb'
|
||||
import * as mongoose from 'mongoose'
|
||||
|
||||
const schemaOptions = {
|
||||
timestamps: { createdAt: 'created_at' },
|
||||
};
|
||||
|
||||
const localWeekly = new mongoose.Schema({
|
||||
|
||||
|
||||
name:{
|
||||
type: Date,
|
||||
required: true,
|
||||
},
|
||||
currencies:[
|
||||
{
|
||||
currencyId:{
|
||||
type: mongoose.ObjectId,
|
||||
required: true,
|
||||
},
|
||||
|
||||
price:{
|
||||
type:Number,
|
||||
required: true,
|
||||
|
||||
},
|
||||
volume:{
|
||||
type: Number,
|
||||
required: true,
|
||||
|
||||
},
|
||||
min:{
|
||||
type: Number,
|
||||
required: true,
|
||||
|
||||
},
|
||||
max:{
|
||||
type: Number,
|
||||
required: true,
|
||||
}
|
||||
}]
|
||||
|
||||
}, schemaOptions)
|
||||
|
||||
export const LocalWeekly = mongoose.model('localWeekly', localWeekly)
|
||||
38
server/db/localYearly.js
Executable file
38
server/db/localYearly.js
Executable file
@@ -0,0 +1,38 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.LocalYearly = void 0;
|
||||
var mongoose = require("mongoose");
|
||||
var schemaOptions = {
|
||||
timestamps: { createdAt: 'created_at' }
|
||||
};
|
||||
var localYearly = new mongoose.Schema({
|
||||
name: {
|
||||
type: Date,
|
||||
required: true
|
||||
},
|
||||
currencies: [
|
||||
{
|
||||
currencyId: {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
price: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
volume: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
min: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
max: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
]
|
||||
}, schemaOptions);
|
||||
exports.LocalYearly = mongoose.model('localYearly', localYearly);
|
||||
45
server/db/localYearly.ts
Executable file
45
server/db/localYearly.ts
Executable file
@@ -0,0 +1,45 @@
|
||||
import { ObjectID } from 'mongodb'
|
||||
import * as mongoose from 'mongoose'
|
||||
|
||||
const schemaOptions = {
|
||||
timestamps: { createdAt: 'created_at' },
|
||||
};
|
||||
|
||||
const localYearly = new mongoose.Schema({
|
||||
|
||||
|
||||
name:{
|
||||
type: Date,
|
||||
required: true,
|
||||
},
|
||||
currencies:[
|
||||
{
|
||||
currencyId:{
|
||||
type: mongoose.ObjectId,
|
||||
required: true,
|
||||
},
|
||||
|
||||
price:{
|
||||
type:Number,
|
||||
required: true,
|
||||
|
||||
},
|
||||
volume:{
|
||||
type: Number,
|
||||
required: true,
|
||||
|
||||
},
|
||||
min:{
|
||||
type: Number,
|
||||
required: true,
|
||||
|
||||
},
|
||||
max:{
|
||||
type: Number,
|
||||
required: true,
|
||||
}
|
||||
}]
|
||||
|
||||
}, schemaOptions)
|
||||
|
||||
export const LocalYearly = mongoose.model('localYearly', localYearly)
|
||||
38
server/db/pendingTransfers.js
Executable file
38
server/db/pendingTransfers.js
Executable file
@@ -0,0 +1,38 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.PendingTransfers = void 0;
|
||||
var mongoose = require("mongoose");
|
||||
var schemaOptions = {
|
||||
timestamps: { createdAt: 'created_at' }
|
||||
};
|
||||
var pendingTransfers = new mongoose.Schema({
|
||||
userId: {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
transactions: [
|
||||
{
|
||||
txId: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
currencyId: {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
currencyName: {
|
||||
type: String
|
||||
},
|
||||
value: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
"enum": ['send', 'receive']
|
||||
}
|
||||
}
|
||||
]
|
||||
}, schemaOptions);
|
||||
exports.PendingTransfers = mongoose.model('PendingTransfers', pendingTransfers);
|
||||
38
server/db/pendingTransfers.ts
Executable file
38
server/db/pendingTransfers.ts
Executable file
@@ -0,0 +1,38 @@
|
||||
import * as mongoose from 'mongoose'
|
||||
|
||||
const schemaOptions = {
|
||||
timestamps: { createdAt: 'created_at' },
|
||||
};
|
||||
|
||||
const pendingTransfers = new mongoose.Schema({
|
||||
userId : {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
transactions: [
|
||||
{
|
||||
txId: {
|
||||
type : String,
|
||||
required : true
|
||||
},
|
||||
currencyId: {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
currencyName: {
|
||||
type : String
|
||||
},
|
||||
value: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
type: {
|
||||
type:String,
|
||||
required:true,
|
||||
enum: ['send','receive'],
|
||||
}
|
||||
}
|
||||
]
|
||||
}, schemaOptions )
|
||||
|
||||
export const PendingTransfers = mongoose.model('PendingTransfers', pendingTransfers)
|
||||
39
server/db/successfulTransfers.js
Executable file
39
server/db/successfulTransfers.js
Executable file
@@ -0,0 +1,39 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.SuccessfulTransfers = void 0;
|
||||
var mongoose = require("mongoose");
|
||||
var schemaOptions = {
|
||||
timestamps: { createdAt: 'created_at' }
|
||||
};
|
||||
var successfulTransfers = new mongoose.Schema({
|
||||
userId: {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
transactions: [
|
||||
{
|
||||
txId: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
currencyId: {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
currencyName: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
value: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
"enum": ['send', 'receive', 'id']
|
||||
}
|
||||
}
|
||||
]
|
||||
}, schemaOptions);
|
||||
exports.SuccessfulTransfers = mongoose.model('SuccessfulTransfers', successfulTransfers);
|
||||
38
server/db/successfulTransfers.ts
Executable file
38
server/db/successfulTransfers.ts
Executable file
@@ -0,0 +1,38 @@
|
||||
import * as mongoose from 'mongoose'
|
||||
|
||||
const schemaOptions = {
|
||||
timestamps: { createdAt: 'created_at' },
|
||||
};
|
||||
const successfulTransfers = new mongoose.Schema({
|
||||
userId : {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
transactions:[
|
||||
{
|
||||
txId: {
|
||||
type : String,
|
||||
required : true
|
||||
},
|
||||
currencyId : {
|
||||
type : mongoose.ObjectId,
|
||||
required : true
|
||||
},
|
||||
currencyName : {
|
||||
type : String,
|
||||
required : true
|
||||
},
|
||||
value:{
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
type:{
|
||||
type:String,
|
||||
required:true,
|
||||
enum: ['send','receive','id'],
|
||||
}
|
||||
}
|
||||
]
|
||||
}, schemaOptions )
|
||||
|
||||
export const SuccessfulTransfers = mongoose.model('SuccessfulTransfers', successfulTransfers)
|
||||
245
server/db/user.js
Executable file
245
server/db/user.js
Executable file
@@ -0,0 +1,245 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.VerificationPhoneCode = exports.VerificationCode = exports.User = exports.verificationPhoneCodeSchema = exports.verificationCodeSchema = void 0;
|
||||
var mongoose = require("mongoose");
|
||||
var bcrypt = require("bcrypt");
|
||||
exports.verificationCodeSchema = new mongoose.Schema({
|
||||
name: {
|
||||
type: String,
|
||||
required: true,
|
||||
unique: true
|
||||
},
|
||||
email: {
|
||||
type: String
|
||||
},
|
||||
createdAt: { type: Date, expires: 60 * 60 * 2, "default": Date.now }
|
||||
}, { timestamp: true });
|
||||
exports.verificationPhoneCodeSchema = new mongoose.Schema({
|
||||
phoneNumber: {
|
||||
type: String,
|
||||
required: true,
|
||||
min: 11,
|
||||
max: 11,
|
||||
unique: true
|
||||
},
|
||||
validated: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
"default": false
|
||||
},
|
||||
code: {
|
||||
type: String,
|
||||
required: true,
|
||||
unique: true
|
||||
},
|
||||
sessionId: {
|
||||
type: String
|
||||
},
|
||||
createdAt: { type: Date, expires: 60 * 2, "default": Date.now }
|
||||
}, { timestamp: true });
|
||||
var userSchema = new mongoose.Schema({
|
||||
name: {
|
||||
type: String
|
||||
},
|
||||
lastName: {
|
||||
type: String
|
||||
},
|
||||
email: {
|
||||
address: {
|
||||
type: String,
|
||||
// required: true,
|
||||
trim: true,
|
||||
index: {
|
||||
unique: true,
|
||||
partialFilterExpression: { 'email.address': { $type: "string" } }
|
||||
}
|
||||
},
|
||||
validated: {
|
||||
type: Boolean,
|
||||
"default": false,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
rank: {
|
||||
type: Number,
|
||||
min: 1,
|
||||
max: 5,
|
||||
"default": 1
|
||||
},
|
||||
phoneNumber: {
|
||||
number: {
|
||||
type: String,
|
||||
index: {
|
||||
unique: true,
|
||||
partialFilterExpression: { 'phoneNumber.number': { $type: "string" } }
|
||||
},
|
||||
min: 11,
|
||||
max: 11
|
||||
},
|
||||
validated: {
|
||||
type: Boolean,
|
||||
"default": false,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
tempPhoneNumber: {
|
||||
type: mongoose.ObjectId
|
||||
},
|
||||
birthdate: {
|
||||
year: {
|
||||
type: String
|
||||
},
|
||||
month: {
|
||||
type: String
|
||||
},
|
||||
day: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
emailVerificationString: {
|
||||
type: mongoose.ObjectId
|
||||
},
|
||||
resetPasswordVerificationString: {
|
||||
type: mongoose.ObjectId
|
||||
},
|
||||
isActive: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
"default": true
|
||||
},
|
||||
password: {
|
||||
type: String,
|
||||
required: true,
|
||||
minlength: 6,
|
||||
trim: true
|
||||
},
|
||||
label: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
hasTicketAccount: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
"default": false
|
||||
},
|
||||
userActivities: [
|
||||
{
|
||||
action: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
timestamp: {
|
||||
type: Date
|
||||
},
|
||||
device: {
|
||||
type: String
|
||||
},
|
||||
loginDeviceId: {},
|
||||
ip: {
|
||||
type: String
|
||||
}
|
||||
}
|
||||
],
|
||||
address: [{
|
||||
title: {
|
||||
type: String,
|
||||
trim: 1
|
||||
},
|
||||
city: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
district: {
|
||||
type: String
|
||||
},
|
||||
province: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
postalCode: {
|
||||
type: String,
|
||||
required: true,
|
||||
min: [10, 'Postal Code is 10 Digits'],
|
||||
max: [10, 'Postal Code is 10 Digits']
|
||||
},
|
||||
address: {
|
||||
type: String,
|
||||
required: true,
|
||||
max: [130, 'Maximmum allowed string length is 130 ']
|
||||
},
|
||||
mobilePhone: {
|
||||
type: String
|
||||
},
|
||||
phone: {
|
||||
type: String
|
||||
}
|
||||
}],
|
||||
userType: {
|
||||
type: String,
|
||||
"enum": ['Normal', 'Builder', 'Vip'],
|
||||
required: true,
|
||||
"default": 'Normal'
|
||||
},
|
||||
wallet: [
|
||||
{
|
||||
currency: {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
value: {
|
||||
type: Number,
|
||||
required: true,
|
||||
"default": 0
|
||||
},
|
||||
commitment: {
|
||||
type: Number,
|
||||
required: true,
|
||||
"default": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
// This functions will execute if the password field is modified.
|
||||
userSchema.pre('save', function (next) {
|
||||
var user = this;
|
||||
if (user.isModified('password')) {
|
||||
bcrypt.genSalt(Number(process.env.SALT_I))
|
||||
.then(function (salt) {
|
||||
bcrypt.hash(user.password, salt)
|
||||
.then(function (hash) {
|
||||
user.password = hash;
|
||||
next();
|
||||
})["catch"](function (err) {
|
||||
next(err);
|
||||
});
|
||||
})["catch"](function (err) {
|
||||
next(err);
|
||||
});
|
||||
}
|
||||
else {
|
||||
next();
|
||||
}
|
||||
});
|
||||
// This method compares the password which is stored in database and
|
||||
// the password which the user entered. It is used in Login.
|
||||
userSchema.methods.comparePassword = function (candidatePassword, cb) {
|
||||
bcrypt.compare(candidatePassword, this.password, function (err, isMatch) {
|
||||
if (err)
|
||||
return cb(err);
|
||||
cb(null, isMatch);
|
||||
});
|
||||
};
|
||||
userSchema.methods.comparePasswordPromise = function (candidatePassword) {
|
||||
var _this = this;
|
||||
return new Promise(function (resolve, reject) {
|
||||
bcrypt.compare(candidatePassword, _this.password)
|
||||
.then(function (isMatch) {
|
||||
resolve(isMatch);
|
||||
})["catch"](function (err) {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
exports.User = mongoose.model('User', userSchema);
|
||||
exports.VerificationCode = mongoose.model('VerificationCode', exports.verificationCodeSchema);
|
||||
exports.VerificationPhoneCode = mongoose.model('VerificationPhoneCode', exports.verificationPhoneCodeSchema);
|
||||
253
server/db/user.ts
Executable file
253
server/db/user.ts
Executable file
@@ -0,0 +1,253 @@
|
||||
import * as mongoose from 'mongoose'
|
||||
import * as bcrypt from 'bcrypt'
|
||||
|
||||
export const verificationCodeSchema = new mongoose.Schema({
|
||||
name: {
|
||||
type: String,
|
||||
required: true,
|
||||
unique: true
|
||||
},
|
||||
email :{
|
||||
type : String
|
||||
},
|
||||
createdAt: { type: Date, expires: 60 * 60 * 2, default: Date.now }
|
||||
}, { timestamp: true })
|
||||
|
||||
export const verificationPhoneCodeSchema = new mongoose.Schema({
|
||||
phoneNumber: {
|
||||
type: String,
|
||||
required: true,
|
||||
min: 11,
|
||||
max: 11,
|
||||
unique: true
|
||||
},
|
||||
validated: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: false
|
||||
},
|
||||
code: {
|
||||
type: String,
|
||||
required: true,
|
||||
unique: true
|
||||
},
|
||||
sessionId: {
|
||||
type: String
|
||||
},
|
||||
createdAt: { type: Date, expires: 60 * 2, default: Date.now }
|
||||
}, { timestamp: true })
|
||||
|
||||
|
||||
const userSchema = new mongoose.Schema({
|
||||
name: {
|
||||
type: String
|
||||
},
|
||||
lastName: {
|
||||
type: String
|
||||
},
|
||||
email: {
|
||||
address :{
|
||||
type: String,
|
||||
// required: true,
|
||||
trim: true,
|
||||
index: {
|
||||
unique: true,
|
||||
partialFilterExpression: { 'email.address': {$type: "string" } }
|
||||
}
|
||||
},
|
||||
validated: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
rank: {
|
||||
type: Number,
|
||||
min: 1,
|
||||
max: 5,
|
||||
default: 1
|
||||
},
|
||||
phoneNumber: {
|
||||
number: {
|
||||
type: String,
|
||||
index: {
|
||||
unique: true,
|
||||
partialFilterExpression: { 'phoneNumber.number': {$type: "string" } }
|
||||
},
|
||||
min: 11,
|
||||
max: 11
|
||||
},
|
||||
validated: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
tempPhoneNumber: {
|
||||
type: mongoose.ObjectId
|
||||
},
|
||||
birthdate: {
|
||||
year: {
|
||||
type: String
|
||||
},
|
||||
month: {
|
||||
type: String
|
||||
},
|
||||
day: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
emailVerificationString: {
|
||||
type: mongoose.ObjectId
|
||||
},
|
||||
resetPasswordVerificationString: {
|
||||
type: mongoose.ObjectId
|
||||
},
|
||||
isActive: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: true
|
||||
},
|
||||
password: {
|
||||
type: String,
|
||||
required: true,
|
||||
minlength: 6,
|
||||
trim: true
|
||||
},
|
||||
label: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
hasTicketAccount : {
|
||||
type : Boolean ,
|
||||
required : true,
|
||||
default : false
|
||||
},
|
||||
userActivities: [
|
||||
{
|
||||
action: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
timestamp: {
|
||||
type: Date
|
||||
},
|
||||
device: {
|
||||
type: String
|
||||
},
|
||||
loginDeviceId: {},
|
||||
ip: {
|
||||
type: String
|
||||
}
|
||||
}
|
||||
],
|
||||
address: [{
|
||||
title: {
|
||||
type: String,
|
||||
trim: 1
|
||||
},
|
||||
city: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
district: {
|
||||
type: String
|
||||
},
|
||||
province: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
postalCode: {
|
||||
type: String,
|
||||
required: true,
|
||||
min: [10, 'Postal Code is 10 Digits'],
|
||||
max: [10, 'Postal Code is 10 Digits']
|
||||
},
|
||||
address: {
|
||||
type: String,
|
||||
required: true,
|
||||
max: [130, 'Maximmum allowed string length is 130 ']
|
||||
},
|
||||
|
||||
mobilePhone: {
|
||||
type: String
|
||||
},
|
||||
phone: {
|
||||
type: String
|
||||
}
|
||||
}],
|
||||
userType: {
|
||||
type: String,
|
||||
enum: ['Normal', 'Builder', 'Vip'],
|
||||
required: true,
|
||||
default: 'Normal'
|
||||
},
|
||||
wallet: [
|
||||
{
|
||||
currency: {
|
||||
type:mongoose.ObjectId,
|
||||
required:true,
|
||||
},
|
||||
value: {
|
||||
type:Number,
|
||||
required:true,
|
||||
default:0,
|
||||
},
|
||||
commitment:{
|
||||
type: Number,
|
||||
required:true,
|
||||
default:0,
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// This functions will execute if the password field is modified.
|
||||
userSchema.pre('save', function (next) {
|
||||
var user = this
|
||||
if (user.isModified('password')) {
|
||||
bcrypt.genSalt(Number(process.env.SALT_I))
|
||||
.then((salt) => {
|
||||
bcrypt.hash(user.password, salt)
|
||||
.then((hash) => {
|
||||
user.password = hash
|
||||
next()
|
||||
})
|
||||
.catch((err) => {
|
||||
next(err)
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
next(err)
|
||||
})
|
||||
} else {
|
||||
next()
|
||||
}
|
||||
})
|
||||
|
||||
// This method compares the password which is stored in database and
|
||||
// the password which the user entered. It is used in Login.
|
||||
userSchema.methods.comparePassword = function (candidatePassword, cb) {
|
||||
bcrypt.compare(candidatePassword, this.password, function (err, isMatch) {
|
||||
if (err) return cb(err)
|
||||
cb(null, isMatch)
|
||||
})
|
||||
}
|
||||
|
||||
userSchema.methods.comparePasswordPromise = function (candidatePassword) {
|
||||
return new Promise((resolve, reject) => {
|
||||
bcrypt.compare(candidatePassword, this.password)
|
||||
.then(function(isMatch) {
|
||||
resolve(isMatch)
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export const User = mongoose.model('User', userSchema)
|
||||
export const VerificationCode = mongoose.model('VerificationCode', verificationCodeSchema)
|
||||
export const VerificationPhoneCode = mongoose.model('VerificationPhoneCode', verificationPhoneCodeSchema)
|
||||
240
server/db/wallet.ts
Executable file
240
server/db/wallet.ts
Executable file
@@ -0,0 +1,240 @@
|
||||
import * as mongoose from 'mongoose'
|
||||
import * as bcrypt from 'bcrypt'
|
||||
|
||||
export const verificationCodeSchema = new mongoose.Schema({
|
||||
name: {
|
||||
type: String,
|
||||
required: true,
|
||||
unique: true
|
||||
},
|
||||
email :{
|
||||
type : String
|
||||
}
|
||||
,
|
||||
createdAt: { type: Date, expires: 60 * 60 * 2, default: Date.now }
|
||||
}, { timestamp: true })
|
||||
|
||||
export const verificationPhoneCodeSchema = new mongoose.Schema({
|
||||
phoneNumber: {
|
||||
type: String,
|
||||
required: true,
|
||||
min: 11,
|
||||
max: 11,
|
||||
unique: true
|
||||
},
|
||||
validated: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: false
|
||||
},
|
||||
code: {
|
||||
type: String,
|
||||
required: true,
|
||||
unique: true
|
||||
},
|
||||
sessionId: {
|
||||
type: String
|
||||
},
|
||||
createdAt: { type: Date, expires: 60 * 2, default: Date.now }
|
||||
}, { timestamp: true })
|
||||
|
||||
|
||||
const userSchema = new mongoose.Schema({
|
||||
name: {
|
||||
type: String
|
||||
},
|
||||
lastName: {
|
||||
type: String
|
||||
},
|
||||
email: {
|
||||
address :{
|
||||
type: String,
|
||||
// required: true,
|
||||
trim: true,
|
||||
index: {
|
||||
unique: true,
|
||||
partialFilterExpression: { 'email.address': {$type: "string" } }
|
||||
}
|
||||
},
|
||||
validated: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
phoneNumber: {
|
||||
number: {
|
||||
type: String,
|
||||
index: {
|
||||
unique: true,
|
||||
partialFilterExpression: { 'phoneNumber.number': {$type: "string" } }
|
||||
},
|
||||
min: 11,
|
||||
max: 11
|
||||
},
|
||||
validated: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
tempPhoneNumber: {
|
||||
type: mongoose.ObjectId
|
||||
},
|
||||
birthdate: {
|
||||
year: {
|
||||
type: String
|
||||
},
|
||||
month: {
|
||||
type: String
|
||||
},
|
||||
day: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
emailVerificationString: {
|
||||
type: mongoose.ObjectId
|
||||
},
|
||||
resetPasswordVerificationString: {
|
||||
type: mongoose.ObjectId
|
||||
},
|
||||
isActive: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: true
|
||||
},
|
||||
password: {
|
||||
type: String,
|
||||
required: true,
|
||||
minlength: 6,
|
||||
trim: true
|
||||
},
|
||||
label: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
userActivities: [
|
||||
{
|
||||
action: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
timestamp: {
|
||||
type: Date
|
||||
},
|
||||
device: {
|
||||
type: String
|
||||
},
|
||||
loginDeviceId: {},
|
||||
ip: {
|
||||
type: String
|
||||
}
|
||||
}
|
||||
],
|
||||
address: [{
|
||||
title: {
|
||||
type: String,
|
||||
trim: 1
|
||||
},
|
||||
city: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
district: {
|
||||
type: String
|
||||
},
|
||||
province: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
postalCode: {
|
||||
type: String,
|
||||
required: true,
|
||||
min: [10, 'Postal Code is 10 Digits'],
|
||||
max: [10, 'Postal Code is 10 Digits']
|
||||
},
|
||||
address: {
|
||||
type: String,
|
||||
required: true,
|
||||
max: [130, 'Maximmum allowed string length is 130 ']
|
||||
},
|
||||
|
||||
mobilePhone: {
|
||||
type: String
|
||||
},
|
||||
phone: {
|
||||
type: String
|
||||
}
|
||||
}],
|
||||
userType: {
|
||||
type: String,
|
||||
enum: ['Normal', 'Builder', 'Vip'],
|
||||
required: true,
|
||||
default: 'Normal'
|
||||
},
|
||||
wallet:[
|
||||
{
|
||||
currency:{
|
||||
type:mongoose.ObjectId,
|
||||
required:true,
|
||||
|
||||
|
||||
},
|
||||
value:{
|
||||
type:Number,
|
||||
required:true,
|
||||
default:0,
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
]
|
||||
})
|
||||
|
||||
// This functions will execute if the password field is modified.
|
||||
userSchema.pre('save', function (next) {
|
||||
var user = this
|
||||
if (user.isModified('password')) {
|
||||
bcrypt.genSalt(Number(process.env.SALT_I))
|
||||
.then((salt) => {
|
||||
bcrypt.hash(user.password, salt)
|
||||
.then((hash) => {
|
||||
user.password = hash
|
||||
next()
|
||||
})
|
||||
.catch((err) => {
|
||||
next(err)
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
next(err)
|
||||
})
|
||||
} else {
|
||||
next()
|
||||
}
|
||||
})
|
||||
|
||||
// This method compares the password which is stored in database and
|
||||
// the password which the user entered. It is used in Login.
|
||||
userSchema.methods.comparePassword = function (candidatePassword, cb) {
|
||||
bcrypt.compare(candidatePassword, this.password, function (err, isMatch) {
|
||||
if (err) return cb(err)
|
||||
cb(null, isMatch)
|
||||
})
|
||||
}
|
||||
|
||||
userSchema.methods.comparePasswordPromise = function (candidatePassword) {
|
||||
return new Promise((resolve, reject) => {
|
||||
bcrypt.compare(candidatePassword, this.password)
|
||||
.then(function(isMatch) {
|
||||
resolve(isMatch)
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export const User = mongoose.model('User', userSchema)
|
||||
export const VerificationCode = mongoose.model('VerificationCode', verificationCodeSchema)
|
||||
export const VerificationPhoneCode = mongoose.model('VerificationPhoneCode', verificationPhoneCodeSchema)
|
||||
45
server/db/withdrawOffers.js
Executable file
45
server/db/withdrawOffers.js
Executable file
@@ -0,0 +1,45 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.Withdraw_Offers = void 0;
|
||||
var mongoose = require("mongoose");
|
||||
var schemaOptions = {
|
||||
timestamps: { createdAt: 'created_at' }
|
||||
};
|
||||
var withdrawnOffers = new mongoose.Schema({
|
||||
userId: {
|
||||
type: mongoose.ObjectId,
|
||||
required: false
|
||||
},
|
||||
offers: [{
|
||||
offerId: {
|
||||
type: String,
|
||||
required: true,
|
||||
unique: true
|
||||
},
|
||||
curGivenId: {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
curGivenVal: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
curTakenId: {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
curTakenVal: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
offeredDate: {
|
||||
type: Date,
|
||||
required: true
|
||||
},
|
||||
expiredDate: {
|
||||
type: Date,
|
||||
required: true
|
||||
}
|
||||
}]
|
||||
}, schemaOptions);
|
||||
exports.Withdraw_Offers = mongoose.model('WithdrawnOffers', withdrawnOffers);
|
||||
73
server/db/withdrawOffers.ts
Executable file
73
server/db/withdrawOffers.ts
Executable file
@@ -0,0 +1,73 @@
|
||||
import * as mongoose from 'mongoose'
|
||||
const schemaOptions = {
|
||||
timestamps: { createdAt: 'created_at' },
|
||||
};
|
||||
const withdrawnOffers = new mongoose.Schema({
|
||||
|
||||
userId : {
|
||||
type: mongoose.ObjectId,
|
||||
required: false,
|
||||
},
|
||||
offers : [{
|
||||
offerId:{
|
||||
type: String,
|
||||
required: true,
|
||||
unique: true
|
||||
},
|
||||
curGivenId:{
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
curGivenVal:{
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
curTakenId:{
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
curTakenVal:{
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
offeredDate:{
|
||||
type:Date,
|
||||
required: true,
|
||||
},
|
||||
expiredDate:{
|
||||
type:Date,
|
||||
required: true,
|
||||
},
|
||||
//withdrawDate:{
|
||||
// type: Date,
|
||||
// required: true,
|
||||
// default: Date.now,
|
||||
//}
|
||||
// bargains:[{
|
||||
// userId:{
|
||||
// type: mongoose.ObjectId,
|
||||
// required: true,
|
||||
// },
|
||||
|
||||
// value:{
|
||||
// type: Number,
|
||||
// required: true,
|
||||
|
||||
// },
|
||||
|
||||
// cur_id:{
|
||||
// type: mongoose.ObjectId,
|
||||
// required: true,
|
||||
// },
|
||||
// bar_date:{
|
||||
// type:Date,
|
||||
// required:true,
|
||||
// }
|
||||
|
||||
// }]
|
||||
}],
|
||||
}, schemaOptions)
|
||||
|
||||
|
||||
|
||||
export const Withdraw_Offers = mongoose.model('WithdrawnOffers', withdrawnOffers)
|
||||
60
server/db/withdrawnOffers.js
Executable file
60
server/db/withdrawnOffers.js
Executable file
@@ -0,0 +1,60 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.Withdrawn_Offers = void 0;
|
||||
var mongoose = require("mongoose");
|
||||
var withdrawnOffers = new mongoose.Schema({
|
||||
userId: {
|
||||
type: mongoose.ObjectId,
|
||||
required: false
|
||||
},
|
||||
offers: [{
|
||||
curGivenId: {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
curGivenVal: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
curTakenId: {
|
||||
type: mongoose.ObjectId,
|
||||
required: true
|
||||
},
|
||||
curTakenVal: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
offeredDate: {
|
||||
type: Date,
|
||||
required: true
|
||||
},
|
||||
expiredDate: {
|
||||
type: Date,
|
||||
required: true
|
||||
},
|
||||
withdrawDate: {
|
||||
type: Date,
|
||||
required: true,
|
||||
"default": Date.now
|
||||
}
|
||||
// bargains:[{
|
||||
// userId:{
|
||||
// type: mongoose.ObjectId,
|
||||
// required: true,
|
||||
// },
|
||||
// value:{
|
||||
// type: Number,
|
||||
// required: true,
|
||||
// },
|
||||
// cur_id:{
|
||||
// type: mongoose.ObjectId,
|
||||
// required: true,
|
||||
// },
|
||||
// bar_date:{
|
||||
// type:Date,
|
||||
// required:true,
|
||||
// }
|
||||
// }]
|
||||
}]
|
||||
});
|
||||
exports.Withdrawn_Offers = mongoose.model('WithdrawnOffers', withdrawnOffers);
|
||||
BIN
server/dump/admin/system.version.bson
Executable file
BIN
server/dump/admin/system.version.bson
Executable file
Binary file not shown.
1
server/dump/admin/system.version.metadata.json
Executable file
1
server/dump/admin/system.version.metadata.json
Executable file
@@ -0,0 +1 @@
|
||||
{"indexes":[{"v":{"$numberInt":"2"},"key":{"_id":{"$numberInt":"1"}},"name":"_id_"}],"uuid":"daaa08c4bcf54161b9f06c5fc2d402d1","collectionName":"system.version"}
|
||||
0
server/dump/exchange/acceptedoffers.bson
Executable file
0
server/dump/exchange/acceptedoffers.bson
Executable file
1
server/dump/exchange/acceptedoffers.metadata.json
Executable file
1
server/dump/exchange/acceptedoffers.metadata.json
Executable file
@@ -0,0 +1 @@
|
||||
{"indexes":[{"v":{"$numberInt":"2"},"key":{"_id":{"$numberInt":"1"}},"name":"_id_"},{"v":{"$numberInt":"2"},"unique":true,"key":{"offers.offerId":{"$numberInt":"1"}},"name":"offers.offerId_1","background":true},{"v":{"$numberInt":"2"},"unique":true,"key":{"offerId":{"$numberInt":"1"}},"name":"offerId_1","background":true}],"uuid":"8703dc2b5f5d4567a568d80817b56afa","collectionName":"acceptedoffers"}
|
||||
BIN
server/dump/exchange/activeoffers.bson
Executable file
BIN
server/dump/exchange/activeoffers.bson
Executable file
Binary file not shown.
1
server/dump/exchange/activeoffers.metadata.json
Executable file
1
server/dump/exchange/activeoffers.metadata.json
Executable file
@@ -0,0 +1 @@
|
||||
{"indexes":[{"v":{"$numberInt":"2"},"key":{"_id":{"$numberInt":"1"}},"name":"_id_"},{"v":{"$numberInt":"2"},"unique":true,"key":{"userId":{"$numberInt":"1"}},"name":"userId_1","background":true},{"v":{"$numberInt":"2"},"unique":true,"key":{"offerId":{"$numberInt":"1"}},"name":"offerId_1","background":true}],"uuid":"fc4244e986a5438f87685af69e958898","collectionName":"activeoffers"}
|
||||
BIN
server/dump/exchange/admins.bson
Executable file
BIN
server/dump/exchange/admins.bson
Executable file
Binary file not shown.
1
server/dump/exchange/admins.metadata.json
Executable file
1
server/dump/exchange/admins.metadata.json
Executable file
@@ -0,0 +1 @@
|
||||
{"indexes":[{"v":{"$numberInt":"2"},"key":{"_id":{"$numberInt":"1"}},"name":"_id_"},{"v":{"$numberInt":"2"},"unique":true,"key":{"email":{"$numberInt":"1"}},"name":"email_1","background":true}],"uuid":"19571896da2b47d98703ab79ffe3d1f5","collectionName":"admins"}
|
||||
BIN
server/dump/exchange/currencies.bson
Executable file
BIN
server/dump/exchange/currencies.bson
Executable file
Binary file not shown.
1
server/dump/exchange/currencies.metadata.json
Executable file
1
server/dump/exchange/currencies.metadata.json
Executable file
@@ -0,0 +1 @@
|
||||
{"indexes":[{"v":{"$numberInt":"2"},"key":{"_id":{"$numberInt":"1"}},"name":"_id_"},{"v":{"$numberInt":"2"},"unique":true,"key":{"name":{"$numberInt":"1"}},"name":"name_1","background":true},{"v":{"$numberInt":"2"},"unique":true,"key":{"per_name":{"$numberInt":"1"}},"name":"per_name_1","background":true},{"v":{"$numberInt":"2"},"unique":true,"key":{"ab_name":{"$numberInt":"1"}},"name":"ab_name_1","background":true}],"uuid":"17d5a5198d0147478e485f1a6e60cfef","collectionName":"currencies"}
|
||||
0
server/dump/exchange/getprices.bson
Executable file
0
server/dump/exchange/getprices.bson
Executable file
1
server/dump/exchange/getprices.metadata.json
Executable file
1
server/dump/exchange/getprices.metadata.json
Executable file
@@ -0,0 +1 @@
|
||||
{"indexes":[{"v":{"$numberInt":"2"},"key":{"_id":{"$numberInt":"1"}},"name":"_id_"},{"v":{"$numberInt":"2"},"key":{"createdAt":{"$numberInt":"1"}},"name":"createdAt_1","expireAfterSeconds":{"$numberInt":"20"},"background":true}],"uuid":"1b7d90c9468e4d4d8ae0d09010c118fd","collectionName":"getprices"}
|
||||
BIN
server/dump/exchange/globaldailyprices.bson
Executable file
BIN
server/dump/exchange/globaldailyprices.bson
Executable file
Binary file not shown.
1
server/dump/exchange/globaldailyprices.metadata.json
Executable file
1
server/dump/exchange/globaldailyprices.metadata.json
Executable file
@@ -0,0 +1 @@
|
||||
{"indexes":[{"v":{"$numberInt":"2"},"key":{"_id":{"$numberInt":"1"}},"name":"_id_"}],"uuid":"1b7b7f5c1c474ab28210a6c0c16725a6","collectionName":"globaldailyprices"}
|
||||
BIN
server/dump/exchange/globalhourlyprices.bson
Executable file
BIN
server/dump/exchange/globalhourlyprices.bson
Executable file
Binary file not shown.
1
server/dump/exchange/globalhourlyprices.metadata.json
Executable file
1
server/dump/exchange/globalhourlyprices.metadata.json
Executable file
@@ -0,0 +1 @@
|
||||
{"indexes":[{"v":{"$numberInt":"2"},"key":{"_id":{"$numberInt":"1"}},"name":"_id_"}],"uuid":"d36a7159cd864b2e8ce904964d7c91ff","collectionName":"globalhourlyprices"}
|
||||
BIN
server/dump/exchange/globalmonthlyprices.bson
Executable file
BIN
server/dump/exchange/globalmonthlyprices.bson
Executable file
Binary file not shown.
1
server/dump/exchange/globalmonthlyprices.metadata.json
Executable file
1
server/dump/exchange/globalmonthlyprices.metadata.json
Executable file
@@ -0,0 +1 @@
|
||||
{"indexes":[{"v":{"$numberInt":"2"},"key":{"_id":{"$numberInt":"1"}},"name":"_id_"}],"uuid":"f804694693924d74bc73518bfffc61e8","collectionName":"globalmonthlyprices"}
|
||||
BIN
server/dump/exchange/globalweeklyprices.bson
Executable file
BIN
server/dump/exchange/globalweeklyprices.bson
Executable file
Binary file not shown.
1
server/dump/exchange/globalweeklyprices.metadata.json
Executable file
1
server/dump/exchange/globalweeklyprices.metadata.json
Executable file
@@ -0,0 +1 @@
|
||||
{"indexes":[{"v":{"$numberInt":"2"},"key":{"_id":{"$numberInt":"1"}},"name":"_id_"}],"uuid":"beb258360afa44a39fca27c3ed669858","collectionName":"globalweeklyprices"}
|
||||
BIN
server/dump/exchange/globalyearlyprices.bson
Executable file
BIN
server/dump/exchange/globalyearlyprices.bson
Executable file
Binary file not shown.
1
server/dump/exchange/globalyearlyprices.metadata.json
Executable file
1
server/dump/exchange/globalyearlyprices.metadata.json
Executable file
@@ -0,0 +1 @@
|
||||
{"indexes":[{"v":{"$numberInt":"2"},"key":{"_id":{"$numberInt":"1"}},"name":"_id_"}],"uuid":"f9f208ef081748199e70b442bf74143f","collectionName":"globalyearlyprices"}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user