@@ -6,10 +6,10 @@ import {
6
6
Signature ,
7
7
TransactionType as BitGoTransactionType ,
8
8
} from '@bitgo/sdk-core' ;
9
- import { SuiProgrammableTransaction , SuiTransaction , SuiTransactionType , TxData } from './iface' ;
9
+ import { SuiProgrammableTransaction , SuiTransaction , SuiTransactionType , TxData , GasData } from './iface' ;
10
10
import { BaseCoin as CoinConfig } from '@bitgo/statics' ;
11
11
import utils , { AppId , Intent , IntentScope , IntentVersion , isImmOrOwnedObj } from './utils' ;
12
- import { GasData , normalizeSuiAddress , normalizeSuiObjectId , SuiObjectRef } from './mystenlab/types' ;
12
+ import { normalizeSuiAddress , normalizeSuiObjectId , SuiObjectRef } from './mystenlab/types' ;
13
13
import { SIGNATURE_SCHEME_BYTES } from './constants' ;
14
14
import { Buffer } from 'buffer' ;
15
15
import { fromB64 , toB64 } from '@mysten/bcs' ;
@@ -23,7 +23,9 @@ import { hashTypedData } from './mystenlab/cryptography/hash';
23
23
export abstract class Transaction < T > extends BaseTransaction {
24
24
protected _suiTransaction : SuiTransaction < T > ;
25
25
protected _signature : Signature ;
26
+ protected _feePayerSignature : Signature ;
26
27
private _serializedSig : Uint8Array ;
28
+ private _serializedFeePayerSig : Uint8Array ;
27
29
28
30
protected constructor ( _coinConfig : Readonly < CoinConfig > ) {
29
31
super ( _coinConfig ) ;
@@ -48,17 +50,31 @@ export abstract class Transaction<T> extends BaseTransaction {
48
50
addSignature ( publicKey : BasePublicKey , signature : Buffer ) : void {
49
51
this . _signatures . push ( signature . toString ( 'hex' ) ) ;
50
52
this . _signature = { publicKey, signature } ;
53
+ this . setSerializedSig ( publicKey , signature ) ;
51
54
this . serialize ( ) ;
52
55
}
53
56
57
+ addFeePayerSignature ( publicKey : BasePublicKey , signature : Buffer ) : void {
58
+ this . _feePayerSignature = { publicKey, signature } ;
59
+ this . setSerializedFeePayerSig ( publicKey , signature ) ;
60
+ }
61
+
54
62
get suiSignature ( ) : Signature {
55
63
return this . _signature ;
56
64
}
57
65
66
+ get feePayerSignature ( ) : Signature {
67
+ return this . _feePayerSignature ;
68
+ }
69
+
58
70
get serializedSig ( ) : Uint8Array {
59
71
return this . _serializedSig ;
60
72
}
61
73
74
+ get serializedFeePayerSig ( ) : Uint8Array {
75
+ return this . _serializedFeePayerSig ;
76
+ }
77
+
62
78
setSerializedSig ( publicKey : BasePublicKey , signature : Buffer ) : void {
63
79
const pubKey = Buffer . from ( publicKey . pub , 'hex' ) ;
64
80
const serialized_sig = new Uint8Array ( 1 + signature . length + pubKey . length ) ;
@@ -68,6 +84,15 @@ export abstract class Transaction<T> extends BaseTransaction {
68
84
this . _serializedSig = serialized_sig ;
69
85
}
70
86
87
+ setSerializedFeePayerSig ( publicKey : BasePublicKey , signature : Buffer ) : void {
88
+ const pubKey = Buffer . from ( publicKey . pub , 'hex' ) ;
89
+ const serialized_sig = new Uint8Array ( 1 + signature . length + pubKey . length ) ;
90
+ serialized_sig . set ( SIGNATURE_SCHEME_BYTES ) ;
91
+ serialized_sig . set ( signature , 1 ) ;
92
+ serialized_sig . set ( pubKey , 1 + signature . length ) ;
93
+ this . _serializedFeePayerSig = serialized_sig ;
94
+ }
95
+
71
96
/** @inheritdoc */
72
97
canSign ( key : BaseKey ) : boolean {
73
98
return true ;
@@ -78,7 +103,6 @@ export abstract class Transaction<T> extends BaseTransaction {
78
103
*
79
104
* @param {KeyPair } signer key
80
105
*/
81
-
82
106
sign ( signer : KeyPair ) : void {
83
107
if ( ! this . _suiTransaction ) {
84
108
throw new InvalidTransactionError ( 'empty transaction to sign' ) ;
@@ -87,10 +111,29 @@ export abstract class Transaction<T> extends BaseTransaction {
87
111
const intentMessage = this . signablePayload ;
88
112
const signature = signer . signMessageinUint8Array ( intentMessage ) ;
89
113
90
- this . setSerializedSig ( { pub : signer . getKeys ( ) . pub } , Buffer . from ( signature ) ) ;
91
114
this . addSignature ( { pub : signer . getKeys ( ) . pub } , Buffer . from ( signature ) ) ;
92
115
}
93
116
117
+ /**
118
+ * Sign this transaction as a fee payer
119
+ *
120
+ * @param {KeyPair } signer key
121
+ */
122
+ signFeePayer ( signer : KeyPair ) : void {
123
+ if ( ! this . _suiTransaction ) {
124
+ throw new InvalidTransactionError ( 'empty transaction to sign' ) ;
125
+ }
126
+
127
+ if ( ! this . _suiTransaction . gasData . sponsor ) {
128
+ throw new InvalidTransactionError ( 'transaction does not have a fee payer' ) ;
129
+ }
130
+
131
+ const intentMessage = this . signablePayload ;
132
+ const signature = signer . signMessageinUint8Array ( intentMessage ) ;
133
+
134
+ this . addFeePayerSignature ( { pub : signer . getKeys ( ) . pub } , Buffer . from ( signature ) ) ;
135
+ }
136
+
94
137
/** @inheritdoc */
95
138
toBroadcastFormat ( ) : string {
96
139
if ( ! this . _suiTransaction ) {
@@ -178,6 +221,9 @@ export abstract class Transaction<T> extends BaseTransaction {
178
221
owner : normalizeSuiAddress ( transactionBlock . gasConfig . owner ! ) ,
179
222
price : Number ( transactionBlock . gasConfig . price as string ) ,
180
223
budget : Number ( transactionBlock . gasConfig . budget as string ) ,
224
+ ...( transactionBlock . gasConfig . sponsor && {
225
+ sponsor : normalizeSuiAddress ( transactionBlock . gasConfig . sponsor ) ,
226
+ } ) ,
181
227
} ,
182
228
} ;
183
229
}
@@ -213,12 +259,20 @@ export abstract class Transaction<T> extends BaseTransaction {
213
259
}
214
260
215
261
static getProperGasData ( k : any ) : GasData {
216
- return {
217
- payment : [ this . normalizeSuiObjectRef ( k . gasData . payment ) ] ,
262
+ const gasData : GasData = {
263
+ payment : Array . isArray ( k . gasData . payment )
264
+ ? k . gasData . payment . map ( ( p : any ) => this . normalizeSuiObjectRef ( p ) )
265
+ : [ this . normalizeSuiObjectRef ( k . gasData . payment ) ] ,
218
266
owner : utils . normalizeHexId ( k . gasData . owner ) ,
219
267
price : Number ( k . gasData . price ) ,
220
268
budget : Number ( k . gasData . budget ) ,
221
269
} ;
270
+
271
+ if ( k . gasData . sponsor ) {
272
+ gasData . sponsor = utils . normalizeHexId ( k . gasData . sponsor ) ;
273
+ }
274
+
275
+ return gasData ;
222
276
}
223
277
224
278
private static normalizeCoins ( coins : any [ ] ) : SuiObjectRef [ ] {
@@ -267,4 +321,15 @@ export abstract class Transaction<T> extends BaseTransaction {
267
321
268
322
return inputGasPaymentObjects ;
269
323
}
324
+
325
+ hasFeePayerSig ( ) : boolean {
326
+ return ! ! this . _feePayerSignature ;
327
+ }
328
+
329
+ getFeePayerPubKey ( ) : string | undefined {
330
+ if ( ! this . _feePayerSignature || ! this . _feePayerSignature . publicKey ) {
331
+ return undefined ;
332
+ }
333
+ return this . _feePayerSignature . publicKey . pub ;
334
+ }
270
335
}
0 commit comments