{"id":21942825,"url":"https://github.com/react-declarative/erc20-payment-gateway","last_synced_at":"2026-04-13T23:04:38.238Z","repository":{"id":114135060,"uuid":"586340695","full_name":"react-declarative/erc20-payment-gateway","owner":"react-declarative","description":"Payment gateway for ERC-20 (USDT-like) tokens","archived":false,"fork":false,"pushed_at":"2023-04-08T13:08:24.000Z","size":4368,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-05-04T00:17:51.252Z","etag":null,"topics":["dependency-injection","erc20","ethereum","evm","functional-programming","mobx","mui","object-oriented-programming","openzeppelin","payment-gateway","react","smart-contracts","solid","solidity","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/react-declarative.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-01-07T19:36:09.000Z","updated_at":"2024-05-29T22:16:28.751Z","dependencies_parsed_at":"2023-06-14T06:30:39.146Z","dependency_job_id":null,"html_url":"https://github.com/react-declarative/erc20-payment-gateway","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-declarative%2Ferc20-payment-gateway","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-declarative%2Ferc20-payment-gateway/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-declarative%2Ferc20-payment-gateway/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-declarative%2Ferc20-payment-gateway/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/react-declarative","download_url":"https://codeload.github.com/react-declarative/erc20-payment-gateway/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244981009,"owners_count":20542287,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dependency-injection","erc20","ethereum","evm","functional-programming","mobx","mui","object-oriented-programming","openzeppelin","payment-gateway","react","smart-contracts","solid","solidity","typescript"],"created_at":"2024-11-29T03:26:41.912Z","updated_at":"2026-04-13T23:04:38.210Z","avatar_url":"https://github.com/react-declarative.png","language":"TypeScript","readme":"# erc20-payment-gateway\n\n\u003e A payment gateway for any `IERC20` tokens (USDT) with testbed on top of [TestERC20](https://stackoverflow.com/questions/75043524/minimal-erc20-contract-for-testing/75043525#75043525) token\n\n![screencast.git](./assets/screencast.gif)\n\n## Contribute\n\n\u003e [!IMPORTANT]\n\u003e Made by using [react-declarative](https://github.com/react-declarative/react-declarative) to solve your problems. **⭐Star** and **💻Fork** It on github will be appreciated\n\n## Usage\n\n1. Run `npm run start:ganache` in separated terminal\n2. Run `npm run deploy:contracts` to deploy contracts to ganache\n3. Run this DApp by running `npm start` in [client](./packages/client) folder. Send some tokens\n4. Check admin menu by typing secret cheat-code `133337`\n5. If you need test eth's on a balance check [config.json](./config.json). The smart-contract is going to mint 10_000 tokens for the first address in the list.\n\n## Contract source code\n\n\u003e Solidity\n\n```solidity\ncontract PaymentGatewayContract {\n\n    IERC20 private erc20;\n    address public owner;\n\n    uint256 public deployBlock;\n\n    constructor(address _erc20Address) {\n        erc20 = IERC20(_erc20Address);\n        owner = msg.sender;\n        deployBlock = block.number;\n    }\n\n    function sendUSDT(uint256 _amount, bytes32 _data) public {\n        uint256 allowance = erc20.allowance(msg.sender, address(this));\n\n        require(allowance \u003e= _amount, \"ERC20 allowance not sufficient\");\n        bool transferSuccess = erc20.transferFrom(msg.sender, owner, _amount);\n\n        require(transferSuccess, \"Failed to transfer ERC20\");\n        emit Transfer(msg.sender, _amount, _data);\n    }\n\n    event Transfer(address indexed sender, uint256 amount, bytes32 _data);\n\n}\n```\n\n\u003e TypeScript\n\n```tsx\nexport class ContractService {\n\n    private readonly ethersService = inject\u003cEthersService\u003e(TYPES.ethersService);\n\n    public readonly transferSubject = new Subject\u003c{\n        sender: string;\n        amount: number;\n        data: string;\n    }\u003e();\n\n    private _instance: IContract = null as never;\n\n    get isContractConnected() {\n        return !!this._instance;\n    };\n\n    constructor() {\n        makeAutoObservable(this);\n    };\n\n    getDeployBlock = async () =\u003e Number(await this._instance.deployBlock());\n\n    sendUSDT = async (_amount: number, _data: string) =\u003e {\n        const result = await this._instance.sendUSDT(String(_amount), toBytes32(_data));\n        const rc = await result.wait();\n        const event = rc.events.find((event: any) =\u003e event.event === 'Transfer');\n        const [sender, amount, data] = event.args;\n        return {\n            sender,\n            amount: Number(amount),\n            data: fromBytes32(data),\n        };\n    };\n\n    getTransferList = async () =\u003e {\n        const eventSignature = 'Transfer(address,uint256,bytes32)';\n        const eventTopic = ethers.utils.id(eventSignature);\n        const deployBlock = await this.getDeployBlock();\n        const currentBlock = await this.ethersService.provider.getBlockNumber();\n        const parser = new ethers.utils.Interface(CC_CONTRACT_ABI);\n        const rawLogs = await this.ethersService.provider.getLogs({\n            address: CC_CONTRACT_ADDRESS,\n            topics: [eventTopic],\n            fromBlock: deployBlock, \n            toBlock: currentBlock,\n        });\n        return rawLogs.map((log, idx) =\u003e {\n            const parsedLog = parser.parseLog(log);\n            const [sender, amount, data] = parsedLog.args;\n            return {\n                id: `${idx}`,\n                sender,\n                amount: Number(amount),\n                data: fromBytes32(data),\n            };\n        });\n    };\n\n    prefetch = singleshot(async () =\u003e {\n        console.log(\"ContractService prefetch started\");\n        try {\n            const deployedCode = await this.ethersService.getCode(CC_CONTRACT_ADDRESS);\n            if (deployedCode === '0x') {\n                throw new Error('ContractService contract not deployed');\n            }\n            const instance = new ethers.Contract(\n                CC_CONTRACT_ADDRESS,\n                CC_CONTRACT_ABI,\n                this.ethersService.getSigner(),\n            ) as IContract;\n            runInAction(() =\u003e this._instance = instance);\n            this.ethersService.provider.once(\"block\", () =\u003e {\n                instance.on('Transfer', (sender: string, amount: BigInt, data: string) =\u003e {\n                    this.transferSubject.next({\n                        sender,\n                        amount: Number(amount),\n                        data: fromBytes32(data),\n                    });\n                });\n            });\n        } catch (e) {\n            console.warn('ContractService prefetch failed', e);\n        }\n    });\n\n};\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freact-declarative%2Ferc20-payment-gateway","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freact-declarative%2Ferc20-payment-gateway","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freact-declarative%2Ferc20-payment-gateway/lists"}