@@ -152,14 +152,43 @@ interface UtxoEntry {
152
152
utxo : Utxo ;
153
153
}
154
154
155
- type Utxo = {
156
- type : 'Transfer' | 'LockThenTransfer' | 'IssueNft' ;
155
+ type BaseUtxo = {
157
156
value : Value ;
158
157
destination : string ;
159
158
token_id ?: string ;
160
- data ?: any ; // split NFT utxo
161
159
} ;
162
160
161
+ type TransferUtxo = BaseUtxo & {
162
+ type : 'Transfer' ;
163
+ } ;
164
+
165
+ type LockThenTransferUtxo = BaseUtxo & {
166
+ type : 'LockThenTransfer' ;
167
+ lock : {
168
+ type : 'ForBlockCount' | 'UntilTime' ;
169
+ content : string ;
170
+ } ;
171
+ } ;
172
+
173
+ type IssueNftUtxo = {
174
+ type : 'IssueNft' ;
175
+ value : Value ;
176
+ destination : string ;
177
+ token_id ?: string ;
178
+ data : {
179
+ name : { hex : string ; string : string } ;
180
+ ticker : { hex : string ; string : string } ;
181
+ description : { hex : string ; string : string } ;
182
+ media_hash : { hex : string ; string : string } ;
183
+ media_uri : { hex : string ; string : string } ;
184
+ icon_uri : { hex : string ; string : string } ;
185
+ additional_metadata_uri : { hex : string ; string : string } ;
186
+ creator : string | null ;
187
+ } ;
188
+ } ;
189
+
190
+ type Utxo = TransferUtxo | LockThenTransferUtxo | IssueNftUtxo ;
191
+
163
192
type UtxoInput = {
164
193
input : {
165
194
index : number ;
@@ -2701,7 +2730,21 @@ class Client {
2701
2730
} ) ;
2702
2731
2703
2732
tx . JSONRepresentation . outputs . forEach ( ( output , index ) => {
2704
- if ( output . type === 'Transfer' || output . type === 'LockThenTransfer' ) {
2733
+ if ( output . type === 'Transfer' ) {
2734
+ created . push ( {
2735
+ outpoint : {
2736
+ index,
2737
+ source_type : SourceId . Transaction ,
2738
+ source_id : tx . transaction_id ,
2739
+ } ,
2740
+ utxo : {
2741
+ type : output . type ,
2742
+ value : output . value ,
2743
+ destination : output . destination ,
2744
+ } ,
2745
+ } ) ;
2746
+ }
2747
+ if ( output . type === 'LockThenTransfer' ) {
2705
2748
created . push ( {
2706
2749
outpoint : {
2707
2750
index,
@@ -2712,6 +2755,7 @@ class Client {
2712
2755
type : output . type ,
2713
2756
value : output . value ,
2714
2757
destination : output . destination ,
2758
+ lock : output . lock ,
2715
2759
} ,
2716
2760
} ) ;
2717
2761
}
@@ -2784,10 +2828,14 @@ class Client {
2784
2828
}
2785
2829
2786
2830
export class TransactionSigner {
2787
- private key : Uint8Array [ ] ;
2831
+ private keys : Record < string , Uint8Array > ;
2788
2832
2789
- constructor ( privateKey : Uint8Array [ ] ) {
2790
- this . key = privateKey ;
2833
+ constructor ( privateKeys : Record < string , Uint8Array > ) {
2834
+ this . keys = privateKeys ;
2835
+ }
2836
+
2837
+ private getPrivateKey ( address : string ) : Uint8Array | undefined {
2838
+ return this . keys [ address ] ;
2791
2839
}
2792
2840
2793
2841
private createSignature ( tx : Transaction ) {
@@ -2824,25 +2872,52 @@ export class TransactionSigner {
2824
2872
}
2825
2873
} )
2826
2874
2827
- const optUtxos : any [ ] = [ ]
2875
+ const optUtxosArray : number [ ] = [ ] ;
2876
+
2828
2877
for ( let i = 0 ; i < optUtxos_ . length ; i ++ ) {
2878
+ const utxoBytes = optUtxos_ [ i ] ;
2829
2879
if ( tx . JSONRepresentation . inputs [ i ] . input . input_type !== 'UTXO' ) {
2830
- optUtxos . push ( 0 )
2831
- continue
2880
+ optUtxosArray . push ( 0 ) ;
2832
2881
} else {
2833
- optUtxos . push ( 1 )
2834
- optUtxos . push ( ...optUtxos_ [ i ] )
2835
- continue
2882
+ if ( ! ( utxoBytes instanceof Uint8Array ) ) {
2883
+ throw new Error ( `optUtxos_[${ i } ] is not a valid Uint8Array` ) ;
2884
+ }
2885
+ optUtxosArray . push ( 1 ) ;
2886
+ optUtxosArray . push ( ...utxoBytes ) ;
2836
2887
}
2837
2888
}
2838
2889
2890
+ const optUtxos = new Uint8Array ( optUtxosArray ) ;
2891
+
2839
2892
const encodedWitnesses = tx . JSONRepresentation . inputs . map (
2840
2893
( input , index ) => {
2841
- const address =
2842
- input ?. utxo ?. destination ||
2843
- input ?. input ?. authority ||
2844
- input ?. input ?. destination
2845
- const addressPrivateKey = addressesPrivateKeys [ address ]
2894
+ let address : string | undefined = undefined ;
2895
+
2896
+ if ( input . input . input_type === 'UTXO' ) {
2897
+ const utxoInput = input as UtxoInput ;
2898
+ address = utxoInput . utxo . destination ;
2899
+ }
2900
+
2901
+ if ( input . input . input_type === 'AccountCommand' ) {
2902
+ // @ts -ignore
2903
+ address = input . input . authority ;
2904
+ }
2905
+
2906
+ if ( input . input . input_type === 'AccountCommand' && input . input . command === 'FillOrder' ) {
2907
+ address = input . input . destination ;
2908
+ }
2909
+
2910
+ if ( address === undefined ) {
2911
+ throw new Error ( `Address not found for input at index ${ index } ` ) ;
2912
+ }
2913
+
2914
+ const addressPrivateKey = this . getPrivateKey ( address )
2915
+
2916
+ if ( ! addressPrivateKey ) {
2917
+ throw new Error ( `Private key not found for address: ${ address } ` ) ;
2918
+ }
2919
+
2920
+ const transaction = this . hexToUint8Array ( tx . HEXRepresentation_unsigned ) ;
2846
2921
2847
2922
const witness = encode_witness (
2848
2923
SignatureHashType . ALL ,
@@ -2861,9 +2936,25 @@ export class TransactionSigner {
2861
2936
return signature ;
2862
2937
}
2863
2938
2939
+ private hexToUint8Array ( hex : string ) : Uint8Array {
2940
+ if ( hex . length % 2 !== 0 ) {
2941
+ throw new Error ( "Hex string must have an even length" ) ;
2942
+ }
2943
+
2944
+ const bytes = new Uint8Array ( hex . length / 2 ) ;
2945
+ for ( let i = 0 ; i < hex . length ; i += 2 ) {
2946
+ bytes [ i / 2 ] = parseInt ( hex . slice ( i , i + 2 ) , 16 ) ;
2947
+ }
2948
+ return bytes ;
2949
+ }
2950
+
2864
2951
private encodeSignedTransaction ( tx : Transaction , signature : Uint8Array ) : string {
2865
- const transaction_signed = encode_signed_transaction ( tx . HEXRepresentation_unsigned , signature ) ;
2866
- return transaction_signed ;
2952
+ const transaction_signed = encode_signed_transaction (
2953
+ this . hexToUint8Array ( tx . HEXRepresentation_unsigned ) ,
2954
+ signature
2955
+ ) ;
2956
+ const transaction_signed_hex = transaction_signed . reduce ( ( acc , byte ) => acc + byte . toString ( 16 ) . padStart ( 2 , '0' ) , '' ) ;
2957
+ return transaction_signed_hex ;
2867
2958
}
2868
2959
2869
2960
sign ( tx : Transaction ) : string {
0 commit comments