Skip to content
Draft
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
18 changes: 18 additions & 0 deletions modules/sdk-coin-flrp/src/flrp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,24 @@ export class Flrp extends BaseCoin {
};
}

// For a P→C export (ExportInP), the exported UTXO amount includes the C-chain
// import fee that will be deducted when ImportInC is confirmed. Subtract the
// minimum import-to-C fee so the displayed amount reflects the expected net
// C-chain receipt, consistent with how ExportInC subtracts minImportToPFee.
if (!tx.isTransactionForCChain && explanation.type === TransactionType.Export) {
const minImportToCFee = BigInt((this._staticsCoin.network as FlareNetwork).minImportToCFee);
const adjustedOutputs = explanation.outputs.map((o) => ({
...o,
amount: (BigInt(o.amount) - minImportToCFee).toString(),
}));
const adjustedOutputAmount = (BigInt(explanation.outputAmount) - minImportToCFee).toString();
return {
...explanation,
outputs: adjustedOutputs,
outputAmount: adjustedOutputAmount,
};
}

return explanation;
} catch (e) {
throw new Error(`Invalid transaction: ${e.message}`);
Expand Down
24 changes: 24 additions & 0 deletions modules/sdk-coin-flrp/test/unit/flrp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,30 @@ describe('Flrp test cases', function () {
signedExplain.outputs[0].amount.should.equal(expectedAdjustedAmount);
});

it('should subtract minImportToCFee from ExportInP outputAmount to show expected net C-chain receipt', async () => {
// The ExportInP UTXO amount is the gross amount going to C-chain, which includes
// the C-chain import fee that will be deducted when ImportInC is confirmed. We
// subtract minImportToCFee to show the minimum net amount the user will receive
// on C-chain, preventing the confirmation UI from showing a higher-than-actual
// amount and causing the display to appear as "- TFLR" instead of the correct amount.
const minImportToCFee = BigInt('2850000'); // from FlarePTestnet.minImportToCFee
const grossOutputAmount = BigInt(EXPORT_IN_P.amount); // 55000000 (includes import fee)
const expectedAdjustedAmount = (grossOutputAmount - minImportToCFee).toString();

// Should work for both half-signed and fully-signed ExportInP hex
const halfSignedExplain = await basecoin.explainTransaction({
halfSigned: { txHex: EXPORT_IN_P.halfSigntxHex },
});
halfSignedExplain.outputAmount.should.equal(expectedAdjustedAmount);
halfSignedExplain.outputs.should.be.an.Array();
halfSignedExplain.outputs.length.should.equal(1);
halfSignedExplain.outputs[0].amount.should.equal(expectedAdjustedAmount);

const signedExplain = await basecoin.explainTransaction({ txHex: EXPORT_IN_P.fullSigntxHex });
signedExplain.outputAmount.should.equal(expectedAdjustedAmount);
signedExplain.outputs[0].amount.should.equal(expectedAdjustedAmount);
});

it('should fail when transaction hex is not provided', async () => {
await basecoin.explainTransaction({}).should.be.rejectedWith('missing transaction hex');
});
Expand Down
7 changes: 5 additions & 2 deletions modules/statics/src/networks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export interface FlareNetwork extends BaseNetwork {
vm?: string;
txFee: string;
minImportToPFee: string;
minImportToCFee: string;
maxImportFee: string;
createSubnetTx?: string;
createChainTx?: string;
Expand Down Expand Up @@ -2318,7 +2319,8 @@ export class FlareP extends Mainnet implements FlareNetwork {
hrp = 'flare';
alias = 'P';
vm = 'platformvm';
minImportToPFee = '1261000'; // 0.1261 FLR
minImportToPFee = '1261000'; // minimum PVM import-to-P fee in nFLR
minImportToCFee = '2850000'; // minimum EVM import-to-C fee in nFLR (250 nFLR/gas * ~11400 gas)
txFee = '200000'; // FLR P-chain import requires higher fee than base txFee
baseTxFee = '1000000';
maxImportFee = '10000000'; // defaults
Expand Down Expand Up @@ -2354,7 +2356,8 @@ export class FlarePTestnet extends Testnet implements FlareNetwork {
alias = 'P';
assetId = 'fxMAKpBQQpFedrUhWMsDYfCUJxdUw4mneTczKBzNg3rc2JUub';
vm = 'platformvm';
minImportToPFee = '1261000'; // 0.1261 FLR
minImportToPFee = '1261000'; // minimum PVM import-to-P fee in nFLR
minImportToCFee = '2850000'; // minimum EVM import-to-C fee in nFLR (250 nFLR/gas * ~11400 gas)
txFee = '200000'; // FLR P-chain import requires higher fee than base txFee
baseTxFee = '1000000';
maxImportFee = '10000000'; // defaults
Expand Down
Loading