diff --git a/docs/home/1-setup/20-paima-bacher.md b/docs/home/1-setup/20-paima-bacher.md index 44a35951..cbc71c22 100644 --- a/docs/home/1-setup/20-paima-bacher.md +++ b/docs/home/1-setup/20-paima-bacher.md @@ -156,6 +156,42 @@ At any point after stopping the batcher, you can clean up via the following comm sh ./shutdown.sh ``` +## Batcher Wallet Balance + +The Batcher can be set to only post transactions if the wallet has a positive balance for your specific batcher. + +Paima Engine always keeps track of individual wallet address for batcher gas fees. + + +To active this functionality the Batcher's .env file must include: +``` +BATCHER_PAYMENT_ENABLED="true" +``` + +You can setup a batcher for any Paima-Engine game, and only post if the wallet has a positive balance. + +```mermaid +flowchart LR + Player -->|Game Input| Batcher-A + Player -->|"PayBatcher(Batcher-A)"| PaimaL2Contract + PaimaEngine -->|Updated Wallet Balance| Batcher-A + PaimaL2Contract -->|Events| PaimaEngine + Batcher-A -->|Post TX| PaimaL2Contract + Batcher-B -->|Post TX| PaimaL2Contract + Batcher-C -->|Post TX| PaimaL2Contract +``` + +### Batcher Payment Workflow +* Player deposits funds by calling `PaimaL2Contract` function `payBatcher(batcherAddress)` with some arbitrary value of native chain tokens. +* Paima-Engine registers the wallet's funds for the `batcherAddress` wallet. +* The Player submits an game-input through the Batcher. +* The Batcher checks if the Player's Wallet has a positive balance. +* The Batcher Posts in behalf of the Player. +* Once the transaction is written Paima-Engine discounts the transaction gas cost (NOTE: One Batcher Post can contain the data of multiple Players, in this case the total fee gets divided between the Players) + +To allow Players sending funds for your batcher, you can add a Web Frontend button following this [example](./21-paima-batcher-payments.md) + + ## Batcher Security (reCAPTCHA) As the Paima Batcher posts user submissions, you might want only to allow human users to submit data and avoid bots or malicious agents. This is a difficult task, but Paima Batcher can leverage Google's reCAPTCHA V3 and easily be integrated into games. diff --git a/docs/home/1-setup/21-paima-batcher-payments.md b/docs/home/1-setup/21-paima-batcher-payments.md new file mode 100644 index 00000000..780071e2 --- /dev/null +++ b/docs/home/1-setup/21-paima-batcher-payments.md @@ -0,0 +1,66 @@ +# Paima Batcher Payment Example + +To enable this functionality set the batcher's .env: +``` +BATCHER_PAYMENT_ENABLED="true" +``` + +Optionally you can set your .env value, and will be available as `ENV.BATCHER_PAYMENT_ADDRESS` in the middleware. +``` +BATCHER_PAYMENT_ADDRESS=0x1234567890 +``` + +In your frontend, using `viem` you can call the contract `payBatcher` function: + +```TS +async function buttonPressed(amountEth = '0.0001') { + // amountEth: Amount to be deposited + // PaimaL2 Contract's ABI + const paimal2Abi = [...]; + + // Create a Viem custom chain definition + const gameChain = defineChain({ + id: ENV.CHAIN_ID, + name: ENV.CHAIN_NAME, + network: 'local', + nativeCurrency: { + name: ENV.CHAIN_CURRENCY_NAME, + symbol: ENV.CHAIN_CURRENCY_SYMBOL, + decimals: ENV.CHAIN_CURRENCY_DECIMALS, + }, + rpcUrls: { + default: { + http: [ENV.CHAIN_URI], + webSocket: undefined, + }, + public: { + http: [ENV.CHAIN_URI], + webSocket: undefined, + }, + }, + }); + + // Get the player's wallet + const wallet = await endpoints.userWalletLogin({ + mode: WalletMode.EvmInjected, + preferBatchedMode: true, + }); + if (!wallet.success) return; + + // Create a View Wallet Client + const walletClient = createWalletClient({ + chain: gameChain, + transport: custom(window.ethereum!), + }); + + const { request } = await gamePublicClient.simulateContract({ + account: wallet.result.walletAddress as `0x${string}`, + address: ENV.CONTRACT_ADDRESS as `0x${string}`, + abi: paimal2Abi, + functionName: 'payBatcher', + args: [ENV.BATCHER_PAYMENT_ADDRESS as `0x${string}`], + value: parseEther(amountEth), + }); + await walletClient.writeContract(request); +} +``` \ No newline at end of file