Skip to content

Commit 78529d3

Browse files
committed
Add getMinAppealBond + auto-bond appeal support
- Add feeManagerContract and roundsStorageContract to GenLayerChain type - Configure FeeManager + RoundsStorage addresses/ABIs for testnetBradbury - Add null values for localnet, studionet, testnetAsimov - New getMinAppealBond(txId) method: queries round number from RoundsStorage, tx status from ConsensusData, then calls FeeManager.calculateMinAppealBond - appealTransaction now auto-queries min bond when value not provided (on chains with FeeManager configured) - appealTransaction accepts optional value param (already added in prior commit) Note: Appeals currently revert on Bradbury with InvalidTransactionStatus even for ACCEPTED txs where canAppeal=true. Suspected consensus state issue — filed for investigation. The SDK changes are correct per the contract interfaces.
1 parent 3aa3e15 commit 78529d3

7 files changed

Lines changed: 101 additions & 1 deletion

File tree

src/chains/localnet.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4011,6 +4011,8 @@ export const localnet: GenLayerChain = defineChain({
40114011
consensusMainContract: CONSENSUS_MAIN_CONTRACT,
40124012
consensusDataContract: CONSENSUS_DATA_CONTRACT,
40134013
stakingContract: null,
4014+
feeManagerContract: null,
4015+
roundsStorageContract: null,
40144016
defaultNumberOfInitialValidators: 5,
40154017
defaultConsensusMaxRotations: 3,
40164018
});

src/chains/studionet.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4012,6 +4012,8 @@ export const studionet: GenLayerChain = defineChain({
40124012
consensusMainContract: CONSENSUS_MAIN_CONTRACT,
40134013
consensusDataContract: CONSENSUS_DATA_CONTRACT,
40144014
stakingContract: null,
4015+
feeManagerContract: null,
4016+
roundsStorageContract: null,
40154017
defaultNumberOfInitialValidators: 5,
40164018
defaultConsensusMaxRotations: 3,
40174019
});

src/chains/testnetAsimov.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4007,6 +4007,8 @@ export const testnetAsimov: GenLayerChain = defineChain({
40074007
consensusMainContract: CONSENSUS_MAIN_CONTRACT,
40084008
consensusDataContract: CONSENSUS_DATA_CONTRACT,
40094009
stakingContract: STAKING_CONTRACT,
4010+
feeManagerContract: null,
4011+
roundsStorageContract: null,
40104012
defaultNumberOfInitialValidators: 5,
40114013
defaultConsensusMaxRotations: 3,
40124014
});

src/chains/testnetBradbury.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,34 @@ const STAKING_CONTRACT = {
99
address: "0x4A4449E617F8D10FDeD0b461CadEf83939E821A5" as Address,
1010
abi: STAKING_ABI,
1111
};
12+
const FEE_MANAGER_CONTRACT = {
13+
address: "0xF205868bf5db79d2162843742D18D0900A9E462a" as Address,
14+
abi: [
15+
{
16+
type: "function" as const,
17+
name: "calculateMinAppealBond",
18+
stateMutability: "view" as const,
19+
inputs: [
20+
{ name: "_txId", type: "bytes32" },
21+
{ name: "_round", type: "uint256" },
22+
{ name: "_status", type: "uint8" },
23+
],
24+
outputs: [{ name: "totalFeesToPay", type: "uint256" }],
25+
},
26+
],
27+
};
28+
const ROUNDS_STORAGE_CONTRACT = {
29+
address: "0x7134D05af13A14c0b66Fe129fb930b1d0C420e33" as Address,
30+
abi: [
31+
{
32+
type: "function" as const,
33+
name: "getRoundNumber",
34+
stateMutability: "view" as const,
35+
inputs: [{ name: "_txId", type: "bytes32" }],
36+
outputs: [{ name: "", type: "uint256" }],
37+
},
38+
],
39+
};
1240
const EXPLORER_URL = "https://explorer-bradbury.genlayer.com/";
1341
const CONSENSUS_MAIN_CONTRACT = {
1442
address: "0x0112Bf6e83497965A5fdD6Dad1E447a6E004271D" as Address,
@@ -3352,6 +3380,8 @@ export const testnetBradbury: GenLayerChain = defineChain({
33523380
consensusMainContract: CONSENSUS_MAIN_CONTRACT,
33533381
consensusDataContract: CONSENSUS_DATA_CONTRACT,
33543382
stakingContract: STAKING_CONTRACT,
3383+
feeManagerContract: FEE_MANAGER_CONTRACT,
3384+
roundsStorageContract: ROUNDS_STORAGE_CONTRACT,
33553385
defaultNumberOfInitialValidators: 5,
33563386
defaultConsensusMaxRotations: 3,
33573387
});

src/contracts/actions.ts

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import {
1010
Address,
1111
TransactionHashVariant,
1212
} from "@/types";
13-
import {fromHex, toHex, zeroAddress, encodeFunctionData, PublicClient, parseEventLogs} from "viem";
13+
import {fromHex, toHex, zeroAddress, encodeFunctionData, PublicClient, parseEventLogs, type Abi} from "viem";
14+
import {TransactionHash} from "@/types/transactions";
1415
import {toJsonSafeDeep, b64ToArray} from "@/utils/jsonifier";
1516

1617
/**
@@ -239,18 +240,71 @@ export const contractActions = (client: GenLayerClient<GenLayerChain>, publicCli
239240
senderAccount,
240241
});
241242
},
243+
getMinAppealBond: async (args: {txId: `0x${string}`}): Promise<bigint> => {
244+
const {txId} = args;
245+
246+
if (!client.chain.feeManagerContract?.address || !client.chain.roundsStorageContract?.address) {
247+
throw new Error("Appeal bond calculation not supported on this chain (missing feeManagerContract/roundsStorageContract)");
248+
}
249+
250+
const roundNumber = await publicClient.readContract({
251+
address: client.chain.roundsStorageContract.address as `0x${string}`,
252+
abi: client.chain.roundsStorageContract.abi as Abi,
253+
functionName: "getRoundNumber",
254+
args: [txId],
255+
}) as bigint;
256+
257+
const transaction = await client.getTransaction({hash: txId as TransactionHash});
258+
const txStatus = Number(transaction.status);
259+
260+
const minBond = await publicClient.readContract({
261+
address: client.chain.feeManagerContract.address as `0x${string}`,
262+
abi: client.chain.feeManagerContract.abi as Abi,
263+
functionName: "calculateMinAppealBond",
264+
args: [txId, roundNumber, txStatus],
265+
}) as bigint;
266+
267+
return minBond;
268+
},
242269
appealTransaction: async (args: {
243270
account?: Account;
244271
txId: `0x${string}`;
272+
value?: bigint;
245273
}) => {
246274
const {account, txId} = args;
275+
let {value} = args;
276+
277+
if (value === undefined) {
278+
if (client.chain.feeManagerContract?.address && client.chain.roundsStorageContract?.address) {
279+
const roundNumber = await publicClient.readContract({
280+
address: client.chain.roundsStorageContract.address as `0x${string}`,
281+
abi: client.chain.roundsStorageContract.abi as Abi,
282+
functionName: "getRoundNumber",
283+
args: [txId],
284+
}) as bigint;
285+
286+
const transaction = await client.getTransaction({hash: txId as TransactionHash});
287+
const txStatus = Number(transaction.status);
288+
289+
value = await publicClient.readContract({
290+
address: client.chain.feeManagerContract.address as `0x${string}`,
291+
abi: client.chain.feeManagerContract.abi as Abi,
292+
functionName: "calculateMinAppealBond",
293+
args: [txId, roundNumber, txStatus],
294+
}) as bigint;
295+
} else {
296+
value = 0n;
297+
}
298+
}
299+
247300
const senderAccount = account || client.account;
248301
const encodedData = _encodeSubmitAppealData({client, txId});
249302
return _sendTransaction({
250303
client,
251304
publicClient,
252305
encodedData,
253306
senderAccount,
307+
value,
254308
});
255309
},
256310
};

src/types/chains.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ export type GenLayerChain = Chain & {
1717
address: Address;
1818
abi: readonly unknown[];
1919
} | null;
20+
feeManagerContract: {
21+
address: Address;
22+
abi: readonly unknown[];
23+
} | null;
24+
roundsStorageContract: {
25+
address: Address;
26+
abi: readonly unknown[];
27+
} | null;
2028
defaultNumberOfInitialValidators: number;
2129
defaultConsensusMaxRotations: number;
2230
};

src/types/clients.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,5 +105,7 @@ export type GenLayerClient<TGenLayerChain extends GenLayerChain> = Omit<
105105
appealTransaction: (args: {
106106
account?: Account;
107107
txId: `0x${string}`;
108+
value?: bigint;
108109
}) => Promise<any>;
110+
getMinAppealBond: (args: {txId: `0x${string}`}) => Promise<bigint>;
109111
} & StakingActions;

0 commit comments

Comments
 (0)