Skip to content

Commit

Permalink
🔄 synced file(s) with circlefin/pw-sdk-nodejs-server-internal (#3)
Browse files Browse the repository at this point in the history
synced local file(s) with
[circlefin/pw-sdk-nodejs-server-internal](https://github.com/circlefin/pw-sdk-nodejs-server-internal).



<details>
<summary>Changed files</summary>
<ul>
<li>synced local <code>package.json</code> with remote
<code>package.json</code></li><li>synced local <code>yarn.lock</code>
with remote <code>yarn.lock</code></li><li>synced local
<code>README.md</code> with remote <code>README.md</code></li><li>synced
local directory <code>src/</code> with remote directory
<code>src/</code></li><li>synced local <code>LICENSE</code> with remote
<code>LICENSE</code></li>
</ul>
</details>

---

This PR was created automatically by the
[repo-file-sync-action](https://github.com/BetaHuhn/repo-file-sync-action)
workflow run
[#8842310024](https://github.com/circlefin/pw-sdk-nodejs-server-internal/actions/runs/8842310024)
  • Loading branch information
tgu-circle committed Apr 26, 2024
2 parents 32b6d0d + 513c3ae commit fedb868
Show file tree
Hide file tree
Showing 11 changed files with 268 additions and 125 deletions.
2 changes: 2 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@

© Circle Internet Financial, LTD 2024. All rights reserved.

SPDX-License-Identifier: Apache-2.0

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ yarn dev
## Additional Resources

- Sample App
- Frontend Repo: <TODO: link to public fe repo>
- Live Demo: <TODO: link to hosted sample app>
- [Frontend Repo](https://github.com/circlefin/w3s-sample-user-controlled-client-web)
- [Live Demo](http://sample-app.circle.com/pw-user-controlled/foundational)
- Walkthrough Video: <TODO: link to video>

- [Circle Web3 Services Node.js SDK](https://developers.circle.com/w3s/docs/nodejs-sdk) supports User-Controlled Wallets, Developer-Controlled Wallets and Smart Contract Platform. See [Programmable Wallets](https://developers.circle.com/w3s/docs/circle-programmable-wallets-an-overview) and [Smart Contract Platform](https://developers.circle.com/w3s/docs/smart-contract-platform) to learn about these features and concepts.
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"scripts": {
"env:config": "cp .env.sample .env",
"test": "jest",
"dev": "nodemon src/index.ts",
"dev": "tsx watch src/index.ts",
"start": "npx ts-node src/index.ts",
"prettier-format": "prettier --config .prettierrc 'src/**/*.ts' --write",
"lint": "eslint . --ext .ts",
Expand Down Expand Up @@ -40,9 +40,9 @@
"eslint-plugin-prettier": "^5.1.3",
"husky": "^9.0.11",
"jest": "^29.7.0",
"nodemon": "^3.1.0",
"prettier": "^3.2.5",
"ts-jest": "^29.1.2"
"ts-jest": "^29.1.2",
"tsx": "^4.7.2"
},
"packageManager": "yarn@1.22.19"
}
}
35 changes: 20 additions & 15 deletions src/app.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import cors from 'cors';
import express, { Express, Request, Response } from 'express';
import { Express, Request, Response } from 'express';
import express from 'express';
import { signUp, signIn } from './controllers';
import {
validate,
Expand All @@ -16,20 +17,20 @@ import {
authTransRouter
} from './routers';

const app: Express = express();
const port = process.env.PORT ?? 8080;
export const app: Express = express();
const parentRouter = express.Router();

app.use(cors());
app.use(express.json());

app.get('/', (_req: Request, res: Response) => {
parentRouter.get('/', (_req: Request, res: Response) => {
res.send('Sample Server');
});

/**
* Health check endpoint.
*/
app.get('/ping', (_req: Request, res: Response) => {
parentRouter.get('/ping', (_req: Request, res: Response) => {
res.status(200).send('pong');
});

Expand All @@ -46,7 +47,7 @@ app.get('/ping', (_req: Request, res: Response) => {
* encryptionKey: string - encryption key to use to execute challengeIds
* challengeId: string - used to initiate a challenge flow to setup PIN + Wallet
*/
app.post('/signup', validate(authenticationSchema), signUp);
parentRouter.post('/signup', validate(authenticationSchema), signUp);

/**
* POST - /signIn
Expand All @@ -66,16 +67,20 @@ app.post('/signup', validate(authenticationSchema), signUp);
* If user credentials wrong or don't exist:
* returns 404
*/
app.post('/signin', validate(authenticationSchema), signIn);
parentRouter.post('/signin', validate(authenticationSchema), signIn);

app.use('/users', usersRouter, authUserRouter);
app.use('/tokens', tokensRouter);
app.use('/wallets', authMiddleware, walletsRouter);
app.use('/transactions', transactionsRouter, authTransRouter);
/*
* Add all sub paths to the parent router
*/
parentRouter.use('/users', usersRouter, authUserRouter);
parentRouter.use('/tokens', tokensRouter);
parentRouter.use('/wallets', authMiddleware, walletsRouter);
parentRouter.use('/transactions', transactionsRouter, authTransRouter);

/*
* Add the parent router with ALL paths to the main app
*/
app.use('/pw-user-controlled/foundational', parentRouter);

// Error handling
app.use(errorHandler);

export const server = app.listen(port, () => {
console.log(`[server]: Server is running at http://localhost:${port}`);
});
10 changes: 9 additions & 1 deletion src/controllers/onboarding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { circleUserSdk, userDAO } from '../services';
import { Request, Response, NextFunction } from 'express';
import { User } from '../middleware';
import { hash, compare } from 'bcrypt';
import { CreateUserWithPinChallenge200Response } from '@circle-fin/user-controlled-wallets/dist/types/clients/user-controlled-wallets';
import { TrimDataResponse } from '@circle-fin/user-controlled-wallets/dist/types/clients/core';
import { logger } from '../services/logging/logger';

export const signUpCallback = (req: Request, res: Response) =>
async function (err: Error | null, rows: User[]) {
Expand Down Expand Up @@ -31,6 +34,9 @@ export const signUpCallback = (req: Request, res: Response) =>
req.body.email,
await hash(req.body.password, 10)
);
logger.info(
`New user inserted into DB, userId: ${newUserId}, email: ${req.body.email}`
);
res.status(200).send({
userId: newUserId,
userToken: tokenResponse.data?.userToken,
Expand Down Expand Up @@ -70,7 +76,9 @@ export const signInCallback = (req: Request, res: Response) =>
const userResponse = await circleUserSdk.getUser({
userId: user.userId
});
let challengeResponse = undefined;
let challengeResponse:
| TrimDataResponse<CreateUserWithPinChallenge200Response>
| undefined = undefined;
if (
userResponse.data?.user?.pinStatus !== 'ENABLED' ||
userResponse.data?.user?.securityQuestionStatus !== 'ENABLED'
Expand Down
5 changes: 5 additions & 0 deletions src/controllers/tests/onboarding.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { signUpCallback, signInCallback } from '../onboarding';
import { getMockReq, getMockRes } from '@jest-mock/express';
import { hashSync } from 'bcrypt';
import {
registerLogger,
SampleServerLogger
} from '../../services/logging/logger';

jest.mock('../../services', () => ({
circleUserSdk: {
Expand Down Expand Up @@ -43,6 +47,7 @@ jest.mock('../../services', () => ({
}
}));

registerLogger(new SampleServerLogger());
const hashedPassword = hashSync('123', 10);

const user = {
Expand Down
15 changes: 13 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
import { server } from './app';
import { app } from './app';
import { initDB, cleanupDB } from './services/db/sqlite/sqliteDB';
import {
logger,
registerLogger,
SampleServerLogger
} from './services/logging/logger';

registerLogger(new SampleServerLogger());
initDB();

const port = process.env.PORT ?? 8080;
const server = app.listen(port, () => {
logger.info(`Server is running at http://localhost:${port}`);
});

process.on('SIGINT', function () {
cleanupDB();
server.close();
console.log('http server closed successfully.');
logger.info('Server closed successfully');
});
14 changes: 9 additions & 5 deletions src/services/db/sqlite/sqliteDB.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
import { Database } from 'sqlite3';
import { registerUserDAO } from '../dao';
import { SqliteUserDAO } from './sqliteUserDAO';
import { logger } from '../../logging/logger';

const client = new Database(process.env.DATABASE_FILENAME ?? ':memory:');
const userDAO = new SqliteUserDAO(client);

export const createUserTable = (db: Database) => {
db.exec(
'CREATE TABLE IF NOT EXISTS users (userId TEXT PRIMARY KEY, email TEXT UNIQUE, password TEXT, createdAt TEXT DEFAULT CURRENT_TIMESTAMP)'
);
db.serialize(() => {
db.exec(
'CREATE TABLE IF NOT EXISTS users (userId TEXT PRIMARY KEY, email TEXT UNIQUE, password TEXT, createdAt TEXT DEFAULT CURRENT_TIMESTAMP)'
);
});
};

export const initDB = () => {
registerUserDAO(userDAO);
createUserTable(client);
logger.info('Created users table');
};

export const cleanupDB = () => {
client.close((err) => {
if (err) {
return console.error(err.message);
return logger.error(err.message);
}
console.log('Close the database connection.');
logger.info('Database connection closed successfully');
});
};
3 changes: 2 additions & 1 deletion src/services/db/sqlite/tests/sqliteUserDAOIT.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ describe('Sqlite User DAO', () => {
let client: Database;
let userDAO: UserDAO;

beforeAll(() => {
beforeAll((done) => {
client = new Database(':memory:');
userDAO = new SqliteUserDAO(client);
createUserTable(client);
done();
});

afterAll(() => {
Expand Down
27 changes: 27 additions & 0 deletions src/services/logging/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
export interface Logger {
info: (message: string) => void;
warn: (message: string) => void;
error: (message: string) => void;
debug: (message: string) => void;
}

export class SampleServerLogger implements Logger {
info(message: string) {
console.log('[SampleServerLogger]: ' + message);
}
warn(message: string) {
console.log('[SampleServerLogger]: ' + message);
}
error(message: string) {
console.log('[SampleServerLogger]: ' + message);
}
debug(message: string) {
console.log('[SampleServerLogger]: ' + message);
}
}

export let logger: Logger;

export const registerLogger = (newLogger: Logger) => {
logger = newLogger;
};
Loading

0 comments on commit fedb868

Please sign in to comment.