Skip to content

Commit 37812c5

Browse files
committed
add missing examples
1 parent 261e516 commit 37812c5

File tree

18 files changed

+4598
-2
lines changed

18 files changed

+4598
-2
lines changed

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ go.work
1818
# Build artifacts
1919
server
2020
server.exe
21-
simple-send
22-
feepayer
21+
/simple-send
22+
/feepayer
2323
bin/
2424

2525
# Profiling files

examples/feepayer/README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Fee Payer
2+
3+
## Overview
4+
5+
Example fee payer relay server that enables gasless transactions on Tempo.
6+
7+
The server accepts user-signed Type 0x76 transactions, adds its own fee payer signature, and broadcasts the dual-signed transaction to the network.
8+
9+
## Running
10+
11+
1. Copy the environment file and configure your settings:
12+
13+
```bash
14+
cd examples/feepayer
15+
cp env.example .env
16+
```
17+
18+
2. Edit `.env` with your values:
19+
20+
```env
21+
FEE_PAYER_PORT=3000
22+
TEMPO_RPC_URL=https://rpc.testnet.tempo.xyz
23+
TEMPO_USERNAME=your-username
24+
TEMPO_PASSWORD=your-password
25+
TEMPO_FEE_PAYER_PRIVATE_KEY=0x...
26+
ALPHAUSD_ADDRESS=0x20c0000000000000000000000000000000000001
27+
TEMPO_CHAIN_ID=42424
28+
```
29+
30+
3. Run the server:
31+
32+
```bash
33+
go run cmd/main.go
34+
```
35+
36+
The server exposes `eth_sendRawTransaction` and `eth_sendRawTransactionSync` JSON-RPC methods on the configured port.

examples/feepayer/client/client.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { createClient, http, walletActions, publicActions } from 'viem';
2+
import { privateKeyToAccount } from 'viem/accounts';
3+
import { tempo } from 'tempo.ts/chains';
4+
import { withFeePayer } from 'tempo.ts/viem';
5+
import { config } from './config.js';
6+
7+
async function main() {
8+
console.log('Tempo Fee Payer Client Example');
9+
10+
const account = privateKeyToAccount(config.clientPrivateKey);
11+
console.log('Client address:', account.address);
12+
13+
const client = createClient({
14+
account,
15+
chain: tempo({ feeToken: config.alphaUsdAddress }),
16+
transport: withFeePayer(
17+
http(config.getCleanRpcUrl(), {
18+
fetchOptions: {
19+
headers: {
20+
Authorization: config.getAuthHeader(),
21+
},
22+
},
23+
}),
24+
http(config.feePayerServerUrl)
25+
),
26+
})
27+
.extend(publicActions)
28+
.extend(walletActions);
29+
30+
console.log('Sending transaction via fee payer relay...');
31+
32+
const hash = await client.sendTransaction({
33+
to: '0x0000000000000000000000000000000000000000',
34+
data: '0xdeadbeef',
35+
value: 0n,
36+
feeToken: config.alphaUsdAddress,
37+
feePayer: true,
38+
} as any);
39+
40+
console.log('Transaction hash:', hash);
41+
console.log('Waiting for confirmation...');
42+
43+
await client.waitForTransactionReceipt({ hash });
44+
45+
const transaction = await client.getTransaction({ hash });
46+
console.log('Transaction confirmed!');
47+
if (transaction.feePayer) {
48+
console.log('Fee payer address:', transaction.feePayer);
49+
}
50+
}
51+
52+
main().catch(console.error);

examples/feepayer/client/config.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import 'dotenv/config';
2+
3+
export class Config {
4+
readonly tempoRpcUrl: string;
5+
readonly tempoUsername: string;
6+
readonly tempoPassword: string;
7+
readonly feePayerServerUrl: string;
8+
readonly clientPrivateKey: `0x${string}`;
9+
readonly alphaUsdAddress: `0x${string}`;
10+
11+
constructor() {
12+
this.tempoRpcUrl = process.env.TEMPO_RPC_URL || 'https://rpc.testnet.tempo.xyz';
13+
this.tempoUsername = process.env.TEMPO_USERNAME || '';
14+
this.tempoPassword = process.env.TEMPO_PASSWORD || '';
15+
this.feePayerServerUrl = process.env.FEE_PAYER_SERVER_URL || 'http://localhost:3000';
16+
17+
const privateKey = process.env.TEMPO_CLIENT_PRIVATE_KEY;
18+
if (!privateKey) {
19+
throw new Error('TEMPO_CLIENT_PRIVATE_KEY environment variable is required');
20+
}
21+
this.clientPrivateKey = privateKey as `0x${string}`;
22+
this.alphaUsdAddress = '0x20c0000000000000000000000000000000000001' as `0x${string}`;
23+
}
24+
25+
/**
26+
* Returns the RPC URL with credentials removed (for use in transport)
27+
*/
28+
getCleanRpcUrl(): string {
29+
return this.tempoRpcUrl.replace(/https?:\/\/[^@]+@/, 'https://');
30+
}
31+
32+
/**
33+
* Returns the Basic Auth credentials string (username:password)
34+
*/
35+
getCredentials(): string {
36+
return `${this.tempoUsername}:${this.tempoPassword}`;
37+
}
38+
39+
/**
40+
* Returns the Base64 encoded Basic Auth header value
41+
*/
42+
getAuthHeader(): string {
43+
return `Basic ${btoa(this.getCredentials())}`;
44+
}
45+
}
46+
47+
export const config = new Config();
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Tempo RPC Configuration
2+
TEMPO_RPC_URL=https://rpc.testnet.tempo.xyz
3+
TEMPO_USERNAME=your-username
4+
TEMPO_PASSWORD=your-password
5+
6+
# Client Private Key
7+
TEMPO_CLIENT_PRIVATE_KEY=0x...
8+
9+
# Fee Payer Server URL
10+
FEE_PAYER_SERVER_URL=http://localhost:3000

0 commit comments

Comments
 (0)