-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
209 lines (182 loc) · 7.3 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
const express = require('express');
const { Coinbase } = require('@coinbase/coinbase-sdk');
const path = require('path');
const fs = require('fs');
const winston = require('winston');
const app = express();
app.use(express.json());
// Configure winston logger
const logger = winston.createLogger({
level: 'debug', // Set the default log level
format: winston.format.combine(
winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
winston.format.printf(({ timestamp, level, message }) => {
return `${timestamp} [${level.toUpperCase()}]: ${message}`;
})
),
transports: [
new winston.transports.Console(),
new winston.transports.File({ filename: 'logs/application.log' })
]
});
// Initialize Coinbase SDK
let coinbase;
(async () => {
try {
coinbase = await Coinbase.configureFromJson({
filePath: './secrets/cdp_api_key.json' // Update with your API key file path
});
logger.info('Coinbase SDK initialized successfully');
} catch (error) {
logger.error('Failed to initialize Coinbase SDK:', error);
}
})();
// Utility function to get the file path for a wallet seed
const getWalletSeedPath = (walletId) => {
return path.join(__dirname, 'wallet_seeds', `${walletId}.json`);
};
// Utility function to rehydrate a wallet
const rehydrateWallet = async (user, walletId) => {
const wallet = await user.getWallet(walletId);
const filePath = getWalletSeedPath(walletId);
await wallet.loadSeed(filePath);
return wallet;
};
// Create a Wallet
app.post('/create-wallet', async (req, res) => {
logger.debug('POST /create-wallet called');
try {
const user = await coinbase.getDefaultUser();
const wallet = await user.createWallet();
// Save the wallet seed
const filePath = getWalletSeedPath(wallet.getId());
// Create the directory if it doesn't exist
const directoryPath = path.dirname(filePath);
if (!fs.existsSync(directoryPath)) {
fs.mkdirSync(directoryPath, { recursive: true });
logger.info(`Directory created: ${directoryPath}`);
}
await wallet.saveSeed(filePath, true); // true for encryption
logger.info(`Wallet created and seed saved: ${wallet.getId()}`);
res.json({ message: 'Wallet created and seed saved successfully', walletId: wallet.getId() });
} catch (error) {
logger.error('Error creating wallet:', error);
res.status(500).json({ error: error.message });
}
});
// Fund a Wallet with testnet ETH
app.post('/fund-wallet', async (req, res) => {
logger.debug('POST /fund-wallet called');
try {
const { walletId } = req.body;
logger.debug(`walletId: ${walletId}`);
let user = await coinbase.getDefaultUser();
logger.debug('User retrieved');
// Rehydrate the wallet
const wallet = await rehydrateWallet(user, walletId);
logger.debug('Wallet rehydrated');
logger.debug(`Wallet is hydrated: ${wallet.canSign()}`);
const faucetTransaction = await wallet.faucet();
logger.info('Faucet transaction completed', faucetTransaction);
res.json({ message: 'Faucet transaction completed', transaction: faucetTransaction });
} catch (error) {
logger.error('Error funding wallet:', error);
res.status(500).json({ error: error.message });
}
});
// Transfer Funds
app.post('/transfer-funds', async (req, res) => {
logger.debug('POST /transfer-funds called');
try {
const { sourceWalletId, destinationWalletAddress, amount } = req.body;
logger.debug(`sourceWalletId: ${sourceWalletId}, destinationWalletAddress: ${destinationWalletAddress}, amount: ${amount}`);
let user = await coinbase.getDefaultUser();
logger.debug('User retrieved');
// Rehydrate the wallet
const sourceWallet = await rehydrateWallet(user, sourceWalletId);
logger.debug('Wallet rehydrated');
logger.debug(`Wallet is hydrated: ${sourceWallet.canSign()}`);
const transfer = await sourceWallet.createTransfer({
amount,
assetId: Coinbase.assets.Eth,
destination: destinationWalletAddress,
});
logger.info('Transfer completed successfully', transfer);
res.json({ message: 'Transfer completed successfully', transfer });
} catch (error) {
logger.error('Error transferring funds:', error);
res.status(500).json({ error: error.message });
}
});
// Trade Assets
app.post('/trade-assets', async (req, res) => {
logger.debug('POST /trade-assets called');
try {
const { walletId, fromAssetId, toAssetId, amount } = req.body;
logger.debug(`walletId: ${walletId}, fromAssetId: ${fromAssetId}, toAssetId: ${toAssetId}, amount: ${amount}`);
const user = await coinbase.getDefaultUser();
logger.debug('User retrieved');
// Rehydrate the wallet
const wallet = await rehydrateWallet(user, walletId);
logger.debug('Wallet rehydrated');
logger.debug(`Wallet is hydrated: ${wallet.canSign()}`);
const trade = await wallet.createTrade({
amount,
fromAssetId,
toAssetId
});
logger.info('Trade completed successfully', trade);
res.json({ message: 'Trade completed successfully', trade });
} catch (error) {
logger.error('Error trading assets:', error);
res.status(500).json({ error: error.message });
}
});
// Get ETH Balance
app.get('/wallet-balance/:walletId', async (req, res) => {
logger.debug('GET /wallet-balance/:walletId called');
try {
const { walletId } = req.params;
logger.debug(`walletId: ${walletId}`);
let user = await coinbase.getDefaultUser();
logger.debug('User retrieved');
// Rehydrate the wallet
const wallet = await rehydrateWallet(user, walletId);
logger.debug('Wallet rehydrated');
// Get the balance of ETH
const balance = await wallet.getBalance(Coinbase.assets.Eth);
logger.info('ETH balance retrieved successfully', balance);
res.json({ message: 'ETH balance retrieved successfully', balance });
} catch (error) {
logger.error('Error retrieving wallet balance:', error);
res.status(500).json({ error: error.message });
}
});
// Get a Wallet
app.get('/get-wallet/:walletId', async (req, res) => {
logger.debug('GET /get-wallet/:walletId called');
try {
const { walletId } = req.params;
logger.debug(`walletId: ${walletId}`);
let user = await coinbase.getDefaultUser();
logger.debug('User retrieved');
const wallet = await user.getWallet(walletId);
logger.info('Wallet retrieved successfully', wallet);
res.json({ message: 'Wallet retrieved successfully', wallet });
} catch (error) {
logger.error('Error retrieving wallet:', error);
res.status(500).json({ error: error.message });
}
});
// Function to start the server
const startServer = () => {
const PORT = process.env.PORT || 3000;
return app.listen(PORT, () => {
logger.info(`Server is running on port ${PORT}`);
});
};
// Start the server if this file is run directly
if (require.main === module) {
startServer();
}
module.exports = { app, startServer };