Skip to content

Commit

Permalink
fix(sdk-coin-xrp): support recovery using issuer address and currency…
Browse files Browse the repository at this point in the history
… code

TICKET: WIN-3813
  • Loading branch information
nvrakesh06 committed Nov 25, 2024
1 parent 31e4aeb commit 0123e85
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 11 deletions.
3 changes: 2 additions & 1 deletion modules/sdk-coin-xrp/src/lib/iface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ export interface RecoveryOptions {
bitgoKey?: string;
walletPassphrase: string;
krsProvider?: string;
tokenName?: string;
issuerAddress?: string;
currencyCode?: string;
}

export interface HalfSignedTransaction {
Expand Down
26 changes: 25 additions & 1 deletion modules/sdk-coin-xrp/src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
UnsupportedTokenError,
UtilsError,
} from '@bitgo/sdk-core';
import { coins, XrpCoin } from '@bitgo/statics';
import { BaseCoin, coins, XrpCoin } from '@bitgo/statics';
import * as querystring from 'querystring';
import * as rippleKeypairs from 'ripple-keypairs';
import * as url from 'url';
Expand All @@ -14,6 +14,7 @@ import { Amount, IssuedCurrencyAmount } from 'xrpl';
import { VALID_ACCOUNT_SET_FLAGS } from './constants';
import { Address, SignerDetails } from './iface';
import { KeyPair as XrpKeyPair } from './keyPair';
import assert from 'assert';

class Utils implements BaseUtils {
isValidAddress(address: string): boolean {
Expand Down Expand Up @@ -267,6 +268,29 @@ class Utils implements BaseUtils {
throw new Error(`Failed to decode transaction: ${error.message}`);
}
}

/**
* Get the statics coin object matching a given Xrp token issuer address and currency code if it exists
*
* @param issuerAddress The token issuer address to match against
* @param currencyCode The token currency code to match against
* @returns statics BaseCoin object for the matching token
*/
public getXrpToken(issuerAddress, currencyCode): Readonly<BaseCoin> | undefined {
const tokens = coins.filter((coin) => {
if (coin instanceof XrpCoin) {
return coin.issuerAddress === issuerAddress && coin.currencyCode === currencyCode;
}
return false;
});
const tokensArray = tokens.map((token) => token);
if (tokensArray.length >= 1) {
// there should never be two tokens with the same issuer address and currency code, so we assert that here
assert(tokensArray.length === 1);
return tokensArray[0];
}
return undefined;
}
}

const utils = new Utils();
Expand Down
15 changes: 9 additions & 6 deletions modules/sdk-coin-xrp/src/xrp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -524,8 +524,9 @@ export class Xrp extends BaseCoin {
);
}

const tokenName = params?.tokenName;
if (!!tokenName) {
const issuer = params?.issuerAddress;
const currency = params?.currencyCode;
if (!!issuer && !!currency) {
const tokenParams = {
recoveryDestination: params.recoveryDestination,
recoverableBalance,
Expand All @@ -538,9 +539,11 @@ export class Xrp extends BaseCoin {
isUnsignedSweep,
userAddress,
backupAddress,
issuer,
currency,
};

return this.recoverXrpToken(params, tokenName, tokenParams);
return this.recoverXrpToken(params, tokenParams);
}

const factory = new TransactionBuilderFactory(coins.get(this.getChain()));
Expand Down Expand Up @@ -596,9 +599,9 @@ export class Xrp extends BaseCoin {
return transactionExplanation;
}

public async recoverXrpToken(params, tokenName, tokenParams) {
const { currency, issuer } = utils.getXrpCurrencyFromTokenName(tokenName);

public async recoverXrpToken(params, tokenParams) {
const { currency, issuer } = tokenParams;
const tokenName = (utils.getXrpToken(issuer, currency) as XrpCoin).name;
const lines = tokenParams.accountLines.body.result.lines;

let amount;
Expand Down
7 changes: 4 additions & 3 deletions modules/sdk-coin-xrp/test/unit/xrp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,6 @@ describe('XRP:', function () {

describe('Recover Token Transactions', () => {
const sandBox = sinon.createSandbox();
const tokenName = 'txrp:rlusd';
const destination = 'raBSn6ipeWXYe7rNbNafZSx9dV2fU3zRyP?dt=12345';
const passPhrase = '#Bondiola1234';
let xrplStub;
Expand Down Expand Up @@ -286,7 +285,8 @@ describe('XRP:', function () {
rootAddress: testData.keys.rootAddress,
recoveryDestination: destination,
walletPassphrase: passPhrase,
tokenName: tokenName,
issuerAddress: 'rQhWct2fv4Vc4KRjRgMrxa8xPN9Zx9iLKV',
currencyCode: '524C555344000000000000000000000000000000',
});

res.should.not.be.empty();
Expand Down Expand Up @@ -351,7 +351,8 @@ describe('XRP:', function () {
rootAddress: 'raGZWRkRBUWdQJsKYEzwXJNbCZMTqX56aA',
recoveryDestination: destination,
walletPassphrase: TestBitGo.V2.TEST_WALLET1_PASSCODE,
tokenName: tokenName,
issuerAddress: 'rQhWct2fv4Vc4KRjRgMrxa8xPN9Zx9iLKV',
currencyCode: '524C555344000000000000000000000000000000',
});

res.should.not.be.empty();
Expand Down

0 comments on commit 0123e85

Please sign in to comment.