Skip to content

Batcher Balance #58

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions docs/home/1-setup/20-paima-bacher.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
66 changes: 66 additions & 0 deletions docs/home/1-setup/21-paima-batcher-payments.md
Original file line number Diff line number Diff line change
@@ -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);
}
```
Loading