From 86defc9cbf6f5e1df7cfddf434805aeca71a5793 Mon Sep 17 00:00:00 2001 From: Raj Ranjan Date: Wed, 26 Nov 2025 14:22:53 +0530 Subject: [PATCH 1/2] handle stakeable locktimes for building utxo bytes --- client/src/utils/buildUtxoBytes.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/client/src/utils/buildUtxoBytes.ts b/client/src/utils/buildUtxoBytes.ts index ee2add56..9a9ab5d8 100644 --- a/client/src/utils/buildUtxoBytes.ts +++ b/client/src/utils/buildUtxoBytes.ts @@ -4,6 +4,7 @@ import { Id, Int, OutputOwners, + pvmSerial, Short, TransferOutput, utils, @@ -19,6 +20,7 @@ import { * @param addresses - The addresses who can sign the transaction for consuming this output. * @param locktime - The UNIX timestamp in seconds after which this output can be consumed. * @param threshold - The threshold of the addresses who can sign the transaction for consuming this output. + * @param stakeableLocktime - The stakeable locktime in seconds before which this output can only be used as staking input. * @returns The UTXO hex string. * * @example @@ -42,7 +44,8 @@ export function buildUtxoBytes( amount: string, addresses: string[], locktime: string, - threshold: number + threshold: number, + stakeableLocktime = '0', ): `0x${string}` { const transferOutput = new TransferOutput( new BigIntPr(BigInt(amount)), @@ -60,10 +63,15 @@ export function buildUtxoBytes( ) ); + const stakeableLockOut = new pvmSerial.StakeableLockOut( + new BigIntPr(BigInt(stakeableLocktime ?? 0)), + transferOutput, + ); + const utxo = new Utxo( new avaxSerial.UTXOID(Id.fromString(txHash), new Int(outputIndex)), Id.fromString(assetId), - transferOutput + stakeableLocktime !== '0' ? stakeableLockOut : transferOutput ); return utils.bufferToHex( From 41ea8171969e1db4c1ef9834937843628bede9f9 Mon Sep 17 00:00:00 2001 From: Raj Ranjan Date: Wed, 26 Nov 2025 14:28:52 +0530 Subject: [PATCH 2/2] stakeable locktime test --- client/src/utils/buildUtxoBytes.test.ts | 26 +++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/client/src/utils/buildUtxoBytes.test.ts b/client/src/utils/buildUtxoBytes.test.ts index 1724cf78..cfb38692 100644 --- a/client/src/utils/buildUtxoBytes.test.ts +++ b/client/src/utils/buildUtxoBytes.test.ts @@ -157,6 +157,32 @@ describe("buildUtxoBytes", () => { expect(parsedUtxo).toBeDefined(); }); + test("handles stakeable locktime", () => { + const txHash = "2R5bJqAd6evMJAuV4TYGqfaHkdCEQfYUx4GoHpJZxsFeor6wMi"; + const outputIndex = 0; + const assetId = "U8iRqJoiJm8xZHAacmvYyZVwqQx6uDNtQeP3CQ6fcgQk3JqnK"; + const amount = "50000000000"; + const addresses = [account1.getXPAddress("P", "fuji")]; + const threshold = 1; + const locktime = "1672531200"; // Some future timestamp + const stakeableLocktime = "1672531200"; // Some future timestamp + + const result = buildUtxoBytes( + txHash, + outputIndex, + assetId, + amount, + addresses, + locktime, + threshold, + stakeableLocktime + ); + + expect(result).toMatch(/^0x/); + const parsedUtxo = getUtxoFromBytes(result, "P"); + expect(parsedUtxo).toBeDefined(); + }); + test("handles different thresholds", () => { const txHash = "2R5bJqAd6evMJAuV4TYGqfaHkdCEQfYUx4GoHpJZxsFeor6wMi"; const outputIndex = 0;