diff --git a/client/src/methods/consts.ts b/client/src/methods/consts.ts index db46ee3c..38ae39c7 100644 --- a/client/src/methods/consts.ts +++ b/client/src/methods/consts.ts @@ -9,7 +9,7 @@ export const AVALANCHE_CHAIN_IDS = { export const AVALANCHE_NETWORK_IDS = { MAINNET: 1, FUJI: 5, - LOCAL: 1337, + LOCAL: 12345, } as const; export const P_CHAIN_MAINNET_ID = '11111111111111111111111111111111LpoYY'; @@ -29,4 +29,4 @@ export const C_CHAIN_ALIAS = 'C'; export const MAINNET_NETWORK_ID = 1; export const TESTNET_NETWORK_ID = 5; -export const LOCAL_NETWORK_ID = 1337; \ No newline at end of file +export const LOCAL_NETWORK_ID = 12345; \ No newline at end of file diff --git a/client/src/methods/pChain/getFeeState.ts b/client/src/methods/pChain/getFeeState.ts index 1e24f3b6..f479f3d9 100644 --- a/client/src/methods/pChain/getFeeState.ts +++ b/client/src/methods/pChain/getFeeState.ts @@ -46,10 +46,23 @@ export async function getFeeState( params: {}, }); + // Convert to BigInt + let capacity = BigInt(feeState.capacity); + const excess = BigInt(feeState.excess); + const price = BigInt(feeState.price); + + // WORKAROUND: On local networks with Etna upgrade not yet active or freshly started, + // capacity can be 0 which causes all transactions to fail with "gas exceeds capacity". + // Set a default capacity of 1,000,000 to allow transactions to proceed. + // This matches the default maxGasCapacity from AvalancheGo's local network params. + if (capacity === 0n) { + capacity = BigInt(1_000_000); + } + return { ...feeState, - capacity: BigInt(feeState.capacity), - excess: BigInt(feeState.excess), - price: BigInt(feeState.price), + capacity, + excess, + price, }; } diff --git a/client/src/methods/wallet/signXPTransaction.ts b/client/src/methods/wallet/signXPTransaction.ts index b43ae138..523ef792 100644 --- a/client/src/methods/wallet/signXPTransaction.ts +++ b/client/src/methods/wallet/signXPTransaction.ts @@ -13,7 +13,7 @@ import { getTxFromBytes } from "../../utils/getTxFromBytes.js"; import { getUtxosForAddress } from "../../utils/getUtxosForAddress.js"; import { AvalancheWalletRpcSchema } from "./avalancheWalletRPCSchema.js"; import { SepkSignatureLength } from "./constants.js"; -import { getContextFromURI } from "./getContextFromURI.js"; +import { getContextFromURI, getHRP } from "./getContextFromURI.js"; import { SignXPTransactionParameters, SignXPTransactionReturnType, @@ -88,20 +88,16 @@ export async function signXPTransaction( const paramAc = parseAvalancheAccount(account); const xpAccount = paramAc?.xpAccount || client.xpAccount; - let isTestnet, networkId; - if (client.chain?.testnet) { - isTestnet = client.chain?.testnet; - networkId = isTestnet ? 5 : 1; - } else { - const context = params.context || (await getContextFromURI(client)); - isTestnet = context.networkID === 5; - networkId = context.networkID; - } + // Always get the actual network ID from the node to determine the correct HRP + // Don't rely on chain.testnet flag as it doesn't distinguish between different test networks + const context = params.context || (await getContextFromURI(client)); + const networkId = context.networkID; + const hrp = getHRP(networkId); if (xpAccount) { const xpAddress = publicKeyToXPAddress( xpAccount.publicKey, - isTestnet ? "fuji" : "avax" + hrp ); if (typeof txOrTxHex === "string") { @@ -165,7 +161,7 @@ export async function signXPTransaction( utxo .getOutputOwners() .addrs.findIndex( - (add) => add.toString(isTestnet ? "fuji" : "avax") === xpAddress + (add) => add.toString(hrp) === xpAddress ), ]); } @@ -191,7 +187,7 @@ export async function signXPTransaction( const credentialIndex = credentials.length - 1; const signerIndex = signingOwners.findIndex( - (owner) => owner.toString(isTestnet ? "fuji" : "avax") === xpAddress + (owner) => owner.toString(hrp) === xpAddress ); if (signerIndex !== -1) { diff --git a/client/src/methods/wallet/transferUtils/transferCtoPChain.ts b/client/src/methods/wallet/transferUtils/transferCtoPChain.ts index 7c52364f..32bea9af 100644 --- a/client/src/methods/wallet/transferUtils/transferCtoPChain.ts +++ b/client/src/methods/wallet/transferUtils/transferCtoPChain.ts @@ -5,7 +5,7 @@ import { P_CHAIN_ALIAS } from "../../consts.js"; import { getFeeState } from "../../pChain/getFeeState.js"; import { baseFee as getBaseFee } from "../../public/baseFee.js"; import { prepareExportTxn as prepareExportTxnCChain } from "../cChain/prepareExportTxn.js"; -import { getContextFromURI } from "../getContextFromURI.js"; +import { getContextFromURI, getHRP } from "../getContextFromURI.js"; import { prepareImportTxn as prepareImportTxnPChain } from "../pChain/prepareImportTxn.js"; import { sendXPTransaction } from "../sendXPTransaction.js"; import { SendParameters, SendReturnType } from "../types/send.js"; @@ -38,7 +38,7 @@ export async function transferCtoPChain( client, params.account, P_CHAIN_ALIAS, - context.networkID === 5 ? "fuji" : "avax" + getHRP(context.networkID) ); // Validate the P chain address diff --git a/client/src/methods/wallet/transferUtils/transferPtoCChain.ts b/client/src/methods/wallet/transferUtils/transferPtoCChain.ts index ec448ed6..18c5f65e 100644 --- a/client/src/methods/wallet/transferUtils/transferPtoCChain.ts +++ b/client/src/methods/wallet/transferUtils/transferPtoCChain.ts @@ -6,7 +6,7 @@ import { getBalance } from "../../pChain/getBalance.js"; import { getFeeState } from "../../pChain/getFeeState.js"; import { baseFee as getBaseFee } from "../../public/baseFee.js"; import { prepareImportTxn as prepareImportTxnCChain } from "../cChain/prepareImportTxn.js"; -import { getContextFromURI } from "../getContextFromURI.js"; +import { getContextFromURI, getHRP } from "../getContextFromURI.js"; import { prepareExportTxn as prepareExportTxnPChain } from "../pChain/prepareExportTxn.js"; import { sendXPTransaction } from "../sendXPTransaction.js"; import { SendParameters, SendReturnType } from "../types/send.js"; @@ -25,7 +25,7 @@ export async function transferPtoCChain( params: TransferPtoCChainParameters ): Promise { const context = params.context || (await getContextFromURI(client)); - const isTestnet = context.networkID === 5; + const hrp = getHRP(context.networkID); // Note: CChain and PChain have different bech32 addresses for seedless accounts on core // The value in both can be same for seed accounts @@ -37,7 +37,7 @@ export async function transferPtoCChain( client, params.account, C_CHAIN_ALIAS, - isTestnet ? "fuji" : "avax" + hrp ); } @@ -49,7 +49,7 @@ export async function transferPtoCChain( client, params.account, P_CHAIN_ALIAS, - isTestnet ? "fuji" : "avax" + hrp ); } diff --git a/client/src/methods/wallet/transferUtils/transferPtoPChain.ts b/client/src/methods/wallet/transferUtils/transferPtoPChain.ts index 8915b818..fecacec6 100644 --- a/client/src/methods/wallet/transferUtils/transferPtoPChain.ts +++ b/client/src/methods/wallet/transferUtils/transferPtoPChain.ts @@ -2,7 +2,7 @@ import { pvm } from "@avalabs/avalanchejs"; import { AvalancheWalletCoreClient } from "../../../clients/createAvalancheWalletCoreClient.js"; import { getBalance } from "../../pChain/getBalance.js"; import { getFeeState } from "../../pChain/getFeeState.js"; -import { getContextFromURI } from "../getContextFromURI.js"; +import { getContextFromURI, getHRP } from "../getContextFromURI.js"; import { prepareBaseTxn } from "../pChain/prepareBaseTxn.js"; import { sendXPTransaction } from "../sendXPTransaction.js"; import { SendParameters, SendReturnType } from "../types/send.js"; @@ -21,14 +21,13 @@ export async function transferPtoPChain( params: TransferPtoPChainParameters ): Promise { const context = params.context || (await getContextFromURI(client)); - const isTestnet = context.networkID === 5; // Get the current account P chain address const currentAccountPChainAddress = await getBech32AddressFromAccountOrClient( client, params.account, "P", - isTestnet ? "fuji" : "avax" + getHRP(context.networkID) ); // Validate the destination address