0

I was tasked to implement software design of serverless PWA of crypto exchange platform which will receive payments from clients by using MetaMask (an Ethereum smart contract) and store withdrawal requests in an AppWrite collection. The main idea is simple: client is paying some coins online, taking a withdrawal ticket and getting money in the crypto bank office

uniswap

The mission of this platform is to help users send their money from different countries without person-to-person coin exchange. Just like in normal bank, but in coins. This means that in the future the code will become enterprise-like: multiple http endpoints, multiple smart contracts (maybe custom ERC-20 token), and no one will want to rewrite it (maybe bsc-like ethereum fork). And all of It is serverless (as much as it can) and build on top of cryptography...

clean-architecture

The frontend must act not like a website, but a desktop app with complicated state management. To resolve this task, I need OOP with composition of services and dependency injection

There is a think: using angular2 is not good enough because It must look great, not like a software from 200x. And It costs. A React sets of components looks great and developers are cheap enough

P.S. I googled, there are some libs like inversifyjs but no one is applied to some starter kit on Envato Market

So, Is there any react app template or starter kit which will fit my task?

Petr Tripolsky
  • 1,419
  • 15
  • 23

1 Answers1

0

I created a special CRA template which uses an onion architecture for global state management.

The source code is published at this GitHub repo

Services inject each with a dependency provider and use MobX to detect changes.

├── lib
│   ├── services
│   │   ├── base
│   │   │   ├── AlertService.ts
│   │   │   ├── ApiService.ts
│   │   │   ├── ErrorService.ts
│   │   │   └── RouterService.ts
│   │   ├── db
│   │   │   └── TodoDbService.ts
│   │   └── view
│   │       └── TodoViewService.ts
│   ├── config.ts
│   ├── ioc.ts
│   └── types.ts

For example, a TodoDbService wraps interactions with AppWrite collection

export class TodoDbService {

    private readonly apiService = inject<ApiService>(TYPES.apiService);

    constructor() {
        makeAutoObservable(this);
    };

    findById = async (id: string) => {
        return await this.apiService.databases.getDocument<ITodoDocument>(
            CC_DB_TODO_DATABASE_ID,
            CC_DB_TODO_COLLECTION_ID,
            id,
        );
    };

    findByUserId = async (userId: string) => {
        return await this.apiService.databases.listDocuments<ITodoDocument>(
            CC_DB_TODO_DATABASE_ID,
            CC_DB_TODO_COLLECTION_ID,
            [
                Query.equal('userId', userId),
            ],
        );
    };

    create = async (payload: ITodoDto) => {
        return await this.apiService.databases.createDocument<ITodoDocument>(
            CC_DB_TODO_DATABASE_ID,
            CC_DB_TODO_COLLECTION_ID,
            'unique()',
            payload,
        );
    };

    update = async (id: string, payload: Partial<ITodoDto>) => {
        return await this.apiService.databases.updateDocument<ITodoDocument>(
            CC_DB_TODO_DATABASE_ID,
            CC_DB_TODO_COLLECTION_ID,
            id,
            payload,
        );
    };

    remove = async (id: string) => {
        return await this.apiService.databases.deleteDocument(
            CC_DB_TODO_DATABASE_ID,
            CC_DB_TODO_COLLECTION_ID,
            id,
        );
    };

};

As a benefit, you would not need to take database and collections ids to every component in UI

const [title, setTitle] = useState('');

const handleCreate = async () => {
    await ioc.todoViewService.create(title);
    reloadListSubject.next();
};

...

<Button onClick={handleCreate} ...

I think this starter kit is indispensable for startups at the time of MVP development because It helps to keep code as clean as possible

screenshot

P.S. A DeFi-specific services has been written in separate project

Petr Tripolsky
  • 1,419
  • 15
  • 23