@@ -16,10 +16,11 @@ import {
1616 ParsedTransaction ,
1717 ParseTransactionOptions ,
1818 promiseProps ,
19+ TokenEnablementConfig ,
1920 UnexpectedAddressError ,
2021 VerifyTransactionOptions ,
2122} from '@bitgo/sdk-core' ;
22- import { BaseCoin as StaticsBaseCoin } from '@bitgo/statics' ;
23+ import { BaseCoin as StaticsBaseCoin , coins , XrpCoin } from '@bitgo/statics' ;
2324import * as rippleBinaryCodec from 'ripple-binary-codec' ;
2425import * as rippleKeypairs from 'ripple-keypairs' ;
2526import * as xrpl from 'xrpl' ;
@@ -107,6 +108,13 @@ export class Xrp extends BaseCoin {
107108 return this . bitgo . get ( this . url ( '/public/feeinfo' ) ) . result ( ) ;
108109 }
109110
111+ public getTokenEnablementConfig ( ) : TokenEnablementConfig {
112+ return {
113+ requiresTokenEnablement : true ,
114+ supportsMultipleTokenEnablements : false ,
115+ } ;
116+ }
117+
110118 /**
111119 * Assemble keychain and half-sign prebuilt transaction
112120 * @param params
@@ -222,6 +230,35 @@ export class Xrp extends BaseCoin {
222230 setFlag : transaction . SetFlag ,
223231 } ,
224232 } ;
233+ } else if ( transaction . TransactionType === 'TrustSet' ) {
234+ return {
235+ displayOrder : [
236+ 'id' ,
237+ 'outputAmount' ,
238+ 'changeAmount' ,
239+ 'outputs' ,
240+ 'changeOutputs' ,
241+ 'fee' ,
242+ 'account' ,
243+ 'limitAmount' ,
244+ ] ,
245+ id : id ,
246+ changeOutputs : [ ] ,
247+ outputAmount : 0 ,
248+ changeAmount : 0 ,
249+ outputs : [ ] ,
250+ fee : {
251+ fee : transaction . Fee ,
252+ feeRate : undefined ,
253+ size : txHex . length / 2 ,
254+ } ,
255+ account : transaction . Account ,
256+ limitAmount : {
257+ currency : transaction . LimitAmount . currency ,
258+ issuer : transaction . LimitAmount . issuer ,
259+ value : transaction . LimitAmount . value ,
260+ } ,
261+ } ;
225262 }
226263
227264 const address =
@@ -254,6 +291,7 @@ export class Xrp extends BaseCoin {
254291 * @returns {boolean }
255292 */
256293 public async verifyTransaction ( { txParams, txPrebuild } : VerifyTransactionOptions ) : Promise < boolean > {
294+ const coinConfig = coins . get ( this . getChain ( ) ) as XrpCoin ;
257295 const explanation = await this . explainTransaction ( {
258296 txHex : txPrebuild . txHex ,
259297 } ) ;
@@ -270,10 +308,34 @@ export class Xrp extends BaseCoin {
270308 return amount1 . toFixed ( ) === amount2 . toFixed ( ) ;
271309 } ;
272310
273- if ( ! comparator ( output , expectedOutput ) ) {
311+ if ( ( txParams . type === undefined || txParams . type === 'payment' ) && ! comparator ( output , expectedOutput ) ) {
274312 throw new Error ( 'transaction prebuild does not match expected output' ) ;
275313 }
276314
315+ if ( txParams . type === 'enabletoken' ) {
316+ if ( txParams . recipients ?. length !== 1 ) {
317+ throw new Error ( 'Only one recipient is allowed.' ) ;
318+ }
319+ const recipient = txParams . recipients [ 0 ] ;
320+ if ( ! recipient . tokenName ) {
321+ throw new Error ( 'Recipient must include a token name.' ) ;
322+ }
323+ const recipientCurrency = utils . getXrpCurrencyFromTokenName ( recipient . tokenName ) . currency ;
324+ if ( coinConfig . isToken ) {
325+ if ( recipientCurrency !== coinConfig . currencyCode ) {
326+ throw new Error ( 'Incorrect token name specified in recipients' ) ;
327+ }
328+ }
329+ if ( ! ( 'account' in explanation ) || ! ( 'limitAmount' in explanation ) || ! explanation . limitAmount . currency ) {
330+ throw new Error ( 'Explanation is missing required keys (account or limitAmount with currency)' ) ;
331+ }
332+ const baseAddress = explanation . account ;
333+ const currency = explanation . limitAmount . currency ;
334+
335+ if ( recipient . address !== baseAddress || recipientCurrency !== currency ) {
336+ throw new Error ( 'Tx outputs does not match with expected txParams recipients' ) ;
337+ }
338+ }
277339 return true ;
278340 }
279341
0 commit comments