-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* created simple endpoint which interacts with the vechain testnet * able to create and retrieve a wallet * fixed updateWallet function and created deleteWallet endpoint * created test suite for wallet endpoints * created documentation for wallet api endpoints
- Loading branch information
1 parent
26abac8
commit ff9f3de
Showing
13 changed files
with
1,045 additions
and
119 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
import { NextFunction, Request, Response } from 'express'; | ||
import { thor } from '@/utils/thor'; | ||
import { Wallet } from '@/models/Wallet'; | ||
import createBlockchainWallet from '@/utils/createBlockchainWallet'; | ||
|
||
export class WalletController { | ||
// @route POST /wallet | ||
// @desc Create a new wallet | ||
public createWallet = async (req: Request, res: Response, next: NextFunction): Promise<void> => { | ||
try { | ||
const { userId } = req.body; | ||
|
||
// Validate input | ||
if (!userId) { | ||
res.status(400).json({ message: 'User ID required in request body.' }); | ||
return; | ||
} | ||
|
||
// Check if there is an existing wallet for the user | ||
let wallet = await Wallet.findOne().where('user').equals(userId); | ||
|
||
// Perform step to handle existing user wallet | ||
if (wallet) { | ||
res.status(400).json({ msg: 'User has an existing wallet.' }); | ||
return; | ||
} | ||
|
||
// Create a new wallet for the user | ||
const { walletAddress } = createBlockchainWallet(); | ||
|
||
// Create a new wallet for the user | ||
wallet = new Wallet({ | ||
balance: 0, | ||
address: walletAddress, | ||
user: userId, | ||
nftList: [], | ||
}); | ||
|
||
await wallet.save(); | ||
|
||
res.status(200).json({ | ||
msg: `Wallet created successfully`, | ||
wallet: wallet, | ||
}); | ||
} catch (error) { | ||
next(error); | ||
} | ||
}; | ||
|
||
// @route GET /wallet | ||
// @desc Retrieve information on a single wallet | ||
public getWallet = async (req: Request, res: Response) => { | ||
try { | ||
const { userId } = req.params; | ||
|
||
// Check if there is an existing wallet for the user | ||
const wallet = await Wallet.findOne().where('user').equals(userId); | ||
|
||
if (!wallet) { | ||
return res.status(404).json({ message: 'No wallet found for this user' }); | ||
} | ||
|
||
res.status(200).json(wallet); | ||
} catch (error) { | ||
res.status(500).json({ message: 'Error retrieving wallet', error }); | ||
} | ||
}; | ||
|
||
// @route PATCH /wallet/:userId | ||
// @desc Update wallet information | ||
public updateWallet = async (req: Request, res: Response, next: NextFunction) => { | ||
try { | ||
const { userId } = req.params; | ||
const { nftList } = req.body || []; | ||
|
||
// Check if there is an existing wallet for the user | ||
let wallet = await Wallet.findOne().where('user').equals(userId); | ||
|
||
if (!wallet) { | ||
return res.status(404).json({ message: 'No wallet found for this user' }); | ||
} | ||
|
||
// Get account details for the user's wallet from VeChain | ||
const accountDetails = await thor.accounts.getAccount(wallet.address); | ||
|
||
// Store updated balance after converting wei to VET | ||
const updatedBalance = parseInt(accountDetails.balance, 16) / Math.pow(10, 18); | ||
|
||
wallet = await Wallet.findByIdAndUpdate(wallet._id, { $set: { nftList, balance: updatedBalance } }, { new: true }); | ||
|
||
res.status(200).json({ | ||
msg: 'Wallet details have been updated!', | ||
wallet: wallet, | ||
}); | ||
} catch (error) { | ||
next(error); | ||
} | ||
}; | ||
|
||
// @route DELETE /wallet/:userId | ||
// @desc Delete user's wallet | ||
public deleteWallet = async (req: Request, res: Response, next: NextFunction) => { | ||
try { | ||
const { userId } = req.params; | ||
|
||
// Check if there is an existing wallet for the user | ||
const wallet = await Wallet.findOne().where('user').equals(userId); | ||
|
||
if (!wallet) { | ||
return res.status(404).json({ message: 'No wallet found for this user' }); | ||
} | ||
|
||
await Wallet.findByIdAndDelete(wallet._id); | ||
|
||
res.status(200).json({ msg: 'Wallet has been deleted' }); | ||
} catch (error) { | ||
next(error); | ||
} | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { IsNotEmpty, IsString } from 'class-validator'; | ||
|
||
export class WalletDto { | ||
@IsString() | ||
@IsNotEmpty() | ||
public userId: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import mongoose from 'mongoose'; | ||
const Schema = mongoose.Schema; | ||
|
||
const WalletSchema = new Schema({ | ||
balance: { | ||
type: Number, | ||
default: 0, | ||
}, | ||
address: { | ||
type: String, | ||
required: true, | ||
unique: true, | ||
}, | ||
user: { | ||
type: Schema.Types.ObjectId, | ||
ref: 'User', | ||
required: true, | ||
}, | ||
nftList: { | ||
type: [String], | ||
default: [], | ||
}, | ||
createdAt: { | ||
type: Date, | ||
default: Date.now, | ||
}, | ||
}); | ||
|
||
export const Wallet = mongoose.model('Wallet', WalletSchema); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { Router } from 'express'; | ||
import { Routes } from '@interfaces/routes.interface'; | ||
import { WalletController } from '@/controllers/wallet.controller'; | ||
import { ValidationMiddleware } from '@/middlewares/validation.middleware'; | ||
import { WalletDto } from '@/dtos/wallet.dto'; | ||
|
||
export class WalletRoute implements Routes { | ||
public router = Router(); | ||
public wallet = new WalletController(); | ||
|
||
constructor() { | ||
this.initializeRoutes(); | ||
} | ||
|
||
// New routes will be declared here | ||
private initializeRoutes() { | ||
this.router.get('/wallet/:userId', this.wallet.getWallet); | ||
this.router.post('/wallet', ValidationMiddleware(WalletDto), this.wallet.createWallet); | ||
this.router.patch('/wallet/:userId', this.wallet.updateWallet); | ||
this.router.delete('/wallet/:userId', this.wallet.deleteWallet); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { Wallet } from 'ethers'; | ||
|
||
interface WalletDetails { | ||
walletAddress: string; | ||
privateKey: string; | ||
publicKey: string; | ||
} | ||
|
||
export default function createBlockchainWallet(): WalletDetails { | ||
// Generate a random wallet | ||
const wallet = Wallet.createRandom(); | ||
|
||
// Extract details | ||
const privateKey = wallet.privateKey; // Use this securely | ||
const publicKey = wallet.publicKey; | ||
const walletAddress = wallet.address; | ||
|
||
return { walletAddress, privateKey, publicKey }; | ||
} |
Oops, something went wrong.