@@ -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,25 @@ export class Xrp extends BaseCoin {
222230 setFlag : transaction . SetFlag ,
223231 } ,
224232 } ;
233+ } else if ( transaction . TransactionType === 'TrustSet' ) {
234+ return {
235+ displayOrder : [ 'id' , 'outputAmount' , 'changeAmount' , 'outputs' , 'changeOutputs' , 'fee' , 'limitAmount' ] ,
236+ id : id ,
237+ changeOutputs : [ ] ,
238+ outputAmount : 0 ,
239+ changeAmount : 0 ,
240+ outputs : [ ] ,
241+ fee : {
242+ fee : transaction . Fee ,
243+ feeRate : undefined ,
244+ size : txHex . length / 2 ,
245+ } ,
246+ limitAmount : {
247+ tokenName : transaction . LimitAmount . currency ,
248+ address : transaction . LimitAmount . issuer ,
249+ amount : transaction . LimitAmount . value ,
250+ } ,
251+ } ;
225252 }
226253
227254 const address =
@@ -254,6 +281,7 @@ export class Xrp extends BaseCoin {
254281 * @returns {boolean }
255282 */
256283 public async verifyTransaction ( { txParams, txPrebuild } : VerifyTransactionOptions ) : Promise < boolean > {
284+ const coinConfig = coins . get ( this . getChain ( ) ) as XrpCoin ;
257285 const explanation = await this . explainTransaction ( {
258286 txHex : txPrebuild . txHex ,
259287 } ) ;
@@ -270,8 +298,34 @@ export class Xrp extends BaseCoin {
270298 return amount1 . toFixed ( ) === amount2 . toFixed ( ) ;
271299 } ;
272300
273- if ( ! comparator ( output , expectedOutput ) ) {
274- throw new Error ( 'transaction prebuild does not match expected output' ) ;
301+ if ( txParams . recipients ) {
302+ // for enabletoken, recipient output amount is 0
303+ const recipients = txParams . recipients . map ( ( recipient ) => ( {
304+ ...recipient ,
305+ } ) ) ;
306+ if ( coinConfig . isToken ) {
307+ recipients . forEach ( ( recipient ) => {
308+ if (
309+ recipient . tokenName !== undefined &&
310+ utils . getXrpCurrencyFromTokenName ( recipient . tokenName ) . currency !== coinConfig . currencyCode
311+ ) {
312+ throw new Error ( 'Incorrect token name specified in recipients' ) ;
313+ }
314+ recipient . tokenName = coinConfig . currencyCode ;
315+ } ) ;
316+ }
317+
318+ // verify recipients from params and explainedTx
319+ const filteredRecipients = recipients ?. map ( ( recipient ) => _ . pick ( recipient , [ 'address' , 'amount' , 'tokenName' ] ) ) ;
320+ const filteredOutputs = 'limitAmount' in explanation ? [ explanation . limitAmount ] : [ ] ;
321+
322+ if ( ! _ . isEqual ( filteredOutputs , filteredRecipients ) ) {
323+ throw new Error ( 'Tx outputs does not match with expected txParams recipients' ) ;
324+ }
325+ } else {
326+ if ( ! comparator ( output , expectedOutput ) ) {
327+ throw new Error ( 'transaction prebuild does not match expected output' ) ;
328+ }
275329 }
276330
277331 return true ;
0 commit comments