This service maintains TAPv2 / GraphTally escrow balances on behalf of a gateway sender.
The following data sources are monitored to guide the allocation of GRT into the Graph Horizon Escrow contract:
- Graph Network Subgraph - for active allocations, escrow accounts, and authorized signers
- Kafka topics for receipts and RAVs - to track outstanding debts from query fees
Configuration options are set via a single JSON file. The structure of the file is defined in src/config.rs.
| Field | Description |
|---|---|
authorize_signers |
If true, automatically authorize signers on startup |
dry_run |
If true, skip contract calls (useful for testing) |
port_metrics |
Port for Prometheus metrics server (default: 9090) |
update_interval_seconds |
Polling interval for the main loop |
The sender address used for tap-escrow-manager expects authorizedSigners:
- Sender: Requires ETH for transaction gas and GRT to allocate into TAP escrow balances for paying indexers
- Authorized signer: Used by the gateway and tap-aggregator to sign receipts and RAVs
When authorize_signers is set to true, the tap-escrow-manager will automatically setup authorized signers on startup. This requires the secret keys for the authorized signer wallets to be present in the signers config field.
To set up authorized signers for tap-escrow-manager:
- Find the escrow-contract address for your network.
- Navigate to the relevant blockchain explorer (e.g., https://sepolia.arbiscan.io/address/0x1e4dC4f9F95E102635D8F7ED71c5CdbFa20e2d02).
- Connect the sender address (the address tap-escrow-manager is running with, or the address whose private key you provide in the
secret_keyfield oftap-escrow-managerconfig). - Go to the "Write Contract" tab and find the
authorizeSignerfunction. - Generate proof and proofDeadline using the script below.
mkdir proof-generator && cd proof-generator
npm init -y
npm install ethers
cat > generateProof.js << EOL
const ethers = require('ethers');
async function generateProof(signerPrivateKey, proofDeadline, senderAddress, chainId) {
const signer = new ethers.Wallet(signerPrivateKey);
const messageHash = ethers.solidityPackedKeccak256(
['uint256', 'uint256', 'address'],
[chainId, proofDeadline, senderAddress]
);
const digest = ethers.hashMessage(ethers.getBytes(messageHash));
const signature = await signer.signMessage(ethers.getBytes(messageHash));
return signature;
}
const signerPrivateKey = process.argv[2];
const senderAddress = process.argv[3];
const chainId = parseInt(process.argv[4]);
const proofDeadline = Math.floor(Date.now() / 1000) + 3600; // 1 hour from now
if (!signerPrivateKey || !senderAddress || !chainId) {
console.error('Usage: node generateProof.js <signerPrivateKey> <senderAddress> <chainId>');
process.exit(1);
}
generateProof(signerPrivateKey, proofDeadline, senderAddress, chainId)
.then(proof => {
console.log('Proof:', proof);
console.log('ProofDeadline:', proofDeadline);
console.log('Human-readable date:', new Date(proofDeadline * 1000).toUTCString());
console.log('Chain ID:', chainId);
})
.catch(error => console.error('Error:', error));
EOL
echo "Setup complete. Run the script with:"
echo "node generateProof.js <authorizedSignerPrivateKey> <senderAddress> <chainId>"- Pass signerAddress, proofDeadline, and proof to the contract and sign the transaction. Repeat if using multiple authorisedSigners
Log levels are controlled by the RUST_LOG environment variable (details).
Example: RUST_LOG=info,tap_escrow_manager=debug cargo run -- config.json
Prometheus metrics are exposed on a separate HTTP server. Configure the port via port_metrics in the config file (default: 9090).
curl http://localhost:9090/metrics| Metric | Type | Description |
|---|---|---|
escrow_total_debt_grt |
Gauge | Total outstanding debt across all receivers |
escrow_total_balance_grt |
Gauge | Total escrow balance across all receivers |
escrow_total_adjustment_grt |
Gauge | Total GRT deposited in the last cycle |
escrow_receiver_count |
Gauge | Number of receivers being tracked |
escrow_loop_duration_seconds |
Histogram | Duration of each polling cycle |
escrow_debt_grt{receiver} |
Gauge | Outstanding debt per receiver |
escrow_balance_grt{receiver} |
Gauge | Escrow balance per receiver |
escrow_adjustment_grt{receiver} |
Gauge | Last adjustment per receiver |
escrow_deposit_ok |
Counter | Successful deposit transactions |
escrow_deposit_err |
Counter | Failed deposit transactions |
escrow_deposit_duration |
Histogram | Deposit transaction duration |