@@ -11,24 +11,24 @@ import {
1111 AnchorInfo ,
1212 COMMITMENT_TX_VERSION ,
1313} from './iface' ;
14- import { encodeBase58 , decodeBase58ToFixed } from './utils' ;
14+ import { encodeBase58 , decodeBase58ToFixed , hexAddressToBytes } from './utils' ;
15+
16+ /** String commitment type for the standard coin API (e.g. wallet-platform) */
17+ export type CommitmentTypeString = 'STAKE' | 'PLEDGE' ;
1518
1619/**
1720 * Builder for Irys commitment transactions (STAKE, PLEDGE).
1821 *
1922 * Commitment transactions are NOT standard EVM transactions. They use a custom
2023 * 7-field RLP encoding with keccak256 prehash and raw ECDSA signing.
2124 *
22- * Usage (STAKE):
23- * const builder = new IrysCommitmentTransactionBuilder(apiUrl, chainId);
24- * builder.setCommitmentType({ type: CommitmentTypeId.STAKE });
25- * builder.setFee(fee);
26- * builder.setValue(value);
27- * builder.setSigner(signerAddress);
28- * const result = await builder.build(); // fetches anchor, RLP encodes, returns prehash
25+ * Usage (standard coin pattern, e.g. from TransactionBuilderFactory):
26+ * const builder = factory.getCommitmentTransactionBuilder();
27+ * builder.setCommitmentType('STAKE').setSigner(hexAddress).setFee('1000').setValue('5000');
28+ * const result = await builder.build(); // { serializedTxHex, signableHex, fields, coinSpecific }
2929 *
30- * Usage (PLEDGE ):
31- * builder.setCommitmentType({ type: CommitmentTypeId.PLEDGE, pledgeCount: 0n });
30+ * Usage (low-level, for tests or advanced use ):
31+ * builder.setCommitmentType({ type: CommitmentTypeId.STAKE }).setSigner(bytes).setFee(1000n)...
3232 */
3333export class IrysCommitmentTransactionBuilder {
3434 private _irysApiUrl : string ;
@@ -38,40 +38,62 @@ export class IrysCommitmentTransactionBuilder {
3838 private _value ?: bigint ;
3939 private _signer ?: Uint8Array ; // 20 bytes
4040 private _anchor ?: Uint8Array ; // 32 bytes (set during build, or manually for testing)
41+ private _pledgeCount = 0 ;
4142
4243 constructor ( irysApiUrl : string , chainId : bigint ) {
4344 this . _irysApiUrl = irysApiUrl ;
4445 this . _chainId = chainId ;
4546 }
4647
4748 /**
48- * Set the commitment type for this transaction.
49- * STAKE is a single-operation type.
50- * PLEDGE requires pledgeCount.
49+ * Set the commitment type. Accepts string ('STAKE' | 'PLEDGE') for the standard API
50+ * or CommitmentType for low-level use. For PLEDGE string form, use setPledgeCount() before or after.
5151 */
52- setCommitmentType ( type : CommitmentType ) : this {
53- this . _commitmentType = type ;
52+ setCommitmentType ( type : CommitmentType | CommitmentTypeString ) : this {
53+ if ( type === 'STAKE' ) {
54+ this . _commitmentType = { type : CommitmentTypeId . STAKE } ;
55+ } else if ( type === 'PLEDGE' ) {
56+ this . _commitmentType = { type : CommitmentTypeId . PLEDGE , pledgeCount : BigInt ( this . _pledgeCount ) } ;
57+ } else {
58+ this . _commitmentType = type ;
59+ }
60+ return this ;
61+ }
62+
63+ /** Set the transaction fee (bigint or string from Irys price API) */
64+ setFee ( fee : bigint | string ) : this {
65+ this . _fee = typeof fee === 'string' ? BigInt ( fee ) : fee ;
66+ return this ;
67+ }
68+
69+ /** Set the transaction value (bigint or string from Irys price API) */
70+ setValue ( value : bigint | string ) : this {
71+ this . _value = typeof value === 'string' ? BigInt ( value ) : value ;
5472 return this ;
5573 }
5674
57- /** Set the transaction fee (from Irys price API) */
58- setFee ( fee : bigint ) : this {
59- this . _fee = fee ;
75+ /** Set the signer address (hex string with or without 0x, or 20-byte Uint8Array) */
76+ setSigner ( signer : Uint8Array | string ) : this {
77+ const bytes = typeof signer === 'string' ? hexAddressToBytes ( signer ) : signer ;
78+ if ( bytes . length !== 20 ) {
79+ throw new Error ( `Signer must be 20 bytes, got ${ bytes . length } ` ) ;
80+ }
81+ this . _signer = bytes ;
6082 return this ;
6183 }
6284
63- /** Set the transaction value (from Irys price API ) */
64- setValue ( value : bigint ) : this {
65- this . _value = value ;
85+ /** Set the chain ID (number or bigint, e.g. 3282 mainnet, 1270 testnet ) */
86+ setChainId ( chainId : bigint | number ) : this {
87+ this . _chainId = typeof chainId === 'number' ? BigInt ( chainId ) : chainId ;
6688 return this ;
6789 }
6890
69- /** Set the signer address (20-byte Ethereum address as Uint8Array) */
70- setSigner ( signer : Uint8Array ) : this {
71- if ( signer . length !== 20 ) {
72- throw new Error ( `Signer must be 20 bytes, got ${ signer . length } ` ) ;
91+ /** Set the pledge count for PLEDGE. Call before or after setCommitmentType('PLEDGE'). */
92+ setPledgeCount ( n : number ) : this {
93+ this . _pledgeCount = n ;
94+ if ( this . _commitmentType ?. type === CommitmentTypeId . PLEDGE ) {
95+ this . _commitmentType = { type : CommitmentTypeId . PLEDGE , pledgeCount : BigInt ( n ) } ;
7396 }
74- this . _signer = signer ;
7597 return this ;
7698 }
7799
@@ -150,17 +172,11 @@ export class IrysCommitmentTransactionBuilder {
150172
151173 /**
152174 * Build the unsigned commitment transaction.
153- *
154- * 1. Validates all fields are set
155- * 2. Fetches anchor from Irys API (if not manually set) -- done LAST to minimize expiration
156- * 3. RLP encodes the 7 fields in exact order
157- * 4. Computes keccak256 prehash
158- * 5. Returns prehash (for HSM) and rlpEncoded (for HSM validation)
175+ * Returns the standard build result with serializedTxHex, signableHex, fields, and coinSpecific.
159176 */
160177 async build ( ) : Promise < CommitmentTransactionBuildResult > {
161178 this . validateFields ( ) ;
162179
163- // Fetch anchor LAST -- it expires in ~45 blocks (~9 min)
164180 if ( ! this . _anchor ) {
165181 this . _anchor = await this . fetchAnchor ( ) ;
166182 }
@@ -178,7 +194,12 @@ export class IrysCommitmentTransactionBuilder {
178194 const rlpEncoded = this . rlpEncode ( fields ) ;
179195 const prehash = this . computePrehash ( rlpEncoded ) ;
180196
181- return { prehash, rlpEncoded, fields } ;
197+ return {
198+ serializedTxHex : Buffer . from ( rlpEncoded ) . toString ( 'hex' ) ,
199+ signableHex : Buffer . from ( prehash ) . toString ( 'hex' ) ,
200+ fields,
201+ coinSpecific : { keyServerPathPrefix : 'irys' } ,
202+ } ;
182203 }
183204
184205 /**
0 commit comments