-
Notifications
You must be signed in to change notification settings - Fork 68
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: support Clawback transaction (#764)
If the tx is a success, the _actual_ amount that was clawed back is returned and shown in all components. If the tx failed, the _attempted_ amount is shown in all components. ### Context of Change Clawback transaction. See https://github.com/XRPLF/XRPL-Standards/pull/104/files?short_path=cb82c33#diff-cb82c337d579659136224b35dbbaac97d0ffaa3cfaa79981f1bebf4f4888feb5
- Loading branch information
1 parent
345de6a
commit a8b5944
Showing
16 changed files
with
415 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 33 additions & 0 deletions
33
src/containers/shared/components/Transaction/Clawback/Description.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { Trans } from 'react-i18next' | ||
import { TransactionDescriptionProps } from '../types' | ||
import { Amount } from '../../Amount' | ||
import { Account } from '../../Account' | ||
import { formatAmount } from '../../../../../rippled/lib/txSummary/formatAmount' | ||
|
||
export const Description = ({ data }: TransactionDescriptionProps) => { | ||
const issuer = data.tx.Account | ||
const holder = data.tx.Amount.issuer | ||
const amount = data.tx.Amount | ||
amount.issuer = issuer | ||
return ( | ||
<> | ||
<div data-test="from-to-line"> | ||
<Trans | ||
i18nKey="claws_back_from" | ||
components={{ | ||
source: <Account account={issuer} />, | ||
destination: <Account account={holder} />, | ||
}} | ||
/> | ||
</div> | ||
<div data-test="amount-line"> | ||
<Trans | ||
i18nKey="instruct_to_claw" | ||
components={{ | ||
amount: <Amount value={formatAmount(amount)} />, | ||
}} | ||
/> | ||
</div> | ||
</> | ||
) | ||
} |
28 changes: 28 additions & 0 deletions
28
src/containers/shared/components/Transaction/Clawback/Simple.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { useTranslation } from 'react-i18next' | ||
import { SimpleRow } from '../SimpleRow' | ||
import { TransactionSimpleComponent, TransactionSimpleProps } from '../types' | ||
import { ClawbackInstructions } from './types' | ||
import { Account } from '../../Account' | ||
import { Amount } from '../../Amount' | ||
|
||
export const Simple: TransactionSimpleComponent = ({ | ||
data, | ||
}: TransactionSimpleProps<ClawbackInstructions>) => { | ||
const { amount, holder } = data.instructions | ||
const { t } = useTranslation() | ||
|
||
return ( | ||
<> | ||
{holder && ( | ||
<SimpleRow label={t('holder')} data-test="holder"> | ||
<Account account={holder} /> | ||
</SimpleRow> | ||
)} | ||
{amount && ( | ||
<SimpleRow label={t('amount')} data-test="amount"> | ||
<Amount value={amount} displayIssuer /> | ||
</SimpleRow> | ||
)} | ||
</> | ||
) | ||
} |
27 changes: 27 additions & 0 deletions
27
src/containers/shared/components/Transaction/Clawback/TableDetail.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { useTranslation, Trans } from 'react-i18next' | ||
import { Amount } from '../../Amount' | ||
import { TransactionTableDetailProps } from '../types' | ||
import { ClawbackInstructions } from './types' | ||
import { Account } from '../../Account' | ||
|
||
export const TableDetail = ({ | ||
instructions, | ||
}: TransactionTableDetailProps<ClawbackInstructions>) => { | ||
const { t } = useTranslation() | ||
const { amount, holder } = instructions | ||
|
||
return ( | ||
<div> | ||
{amount && holder && ( | ||
<div className="clawback"> | ||
<Trans i18nKey="action_from"> | ||
<span className="label">{t('claws_back')}</span> | ||
<Amount value={amount} displayIssuer /> | ||
from | ||
<Account account={holder} /> | ||
</Trans> | ||
</div> | ||
)} | ||
</div> | ||
) | ||
} |
19 changes: 19 additions & 0 deletions
19
src/containers/shared/components/Transaction/Clawback/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { | ||
TransactionAction, | ||
TransactionCategory, | ||
TransactionMapping, | ||
} from '../types' | ||
|
||
import { Simple } from './Simple' | ||
import { parser } from './parser' | ||
import { TableDetail } from './TableDetail' | ||
import { Description } from './Description' | ||
|
||
export const ClawbackTransaction: TransactionMapping = { | ||
Simple, | ||
TableDetail, | ||
Description, | ||
action: TransactionAction.CANCEL, | ||
category: TransactionCategory.PAYMENT, | ||
parser, | ||
} |
46 changes: 46 additions & 0 deletions
46
src/containers/shared/components/Transaction/Clawback/parser.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { Clawback, ClawbackInstructions } from './types' | ||
import { TransactionParser } from '../types' | ||
import { formatAmount } from '../../../../../rippled/lib/txSummary/formatAmount' | ||
import { computeBalanceChange } from '../../../utils' | ||
|
||
export const parser: TransactionParser<Clawback, ClawbackInstructions> = ( | ||
tx, | ||
meta, | ||
) => { | ||
const account = tx.Account | ||
const amount = formatAmount(tx.Amount) | ||
const holder = amount.issuer | ||
amount.issuer = account | ||
|
||
// At this point, we need to get the ACTUAL balance change as a | ||
// result of Clawback. If the issuer tries to claw back more than | ||
// what holder has, only the max available balance is clawed. | ||
const trustlineNode = meta.AffectedNodes.filter( | ||
(node: any) => | ||
node.DeletedNode?.LedgerEntryType === 'RippleState' || | ||
node.ModifiedNode?.LedgerEntryType === 'RippleState', | ||
) | ||
|
||
// If no trustline is modified, it means the tx failed. | ||
// We just return the amount that was attempted to claw. | ||
if (!trustlineNode || trustlineNode.length !== 1) | ||
return { | ||
amount, | ||
account, | ||
holder, | ||
} | ||
|
||
const { change } = computeBalanceChange( | ||
trustlineNode[0].ModifiedNode ?? trustlineNode[0].DeletedNode, | ||
) | ||
|
||
// Update the amount that was actually clawed back | ||
// (could be different from what was submitted) | ||
amount.amount = Math.abs(change) | ||
|
||
return { | ||
account, | ||
amount, | ||
holder, | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
src/containers/shared/components/Transaction/Clawback/test/ClawbackDescription.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { createDescriptionWrapperFactory } from '../../test' | ||
import { Description } from '../Description' | ||
import transaction from './mock_data/Clawback.json' | ||
import i18n from '../../../../../../i18n/testConfigEnglish' | ||
|
||
const createWrapper = createDescriptionWrapperFactory(Description, i18n) | ||
|
||
describe('Clawback', () => { | ||
it('handles Clawback Description ', () => { | ||
const wrapper = createWrapper(transaction) | ||
expect(wrapper.find('[data-test="from-to-line"]')).toHaveText( | ||
`rDZ713igKfedN4hhY6SjQse4Mv3ZrBxnn9 claws back from rscBWQpyZEmQvupeB1quu7Ky8YX4f5CHDP`, | ||
) | ||
expect(wrapper.find('[data-test="amount-line"]')).toHaveText( | ||
`The max clawback amount is 4,840.00 FOO.rDZ713igKfedN4hhY6SjQse4Mv3ZrBxnn9`, | ||
) | ||
wrapper.unmount() | ||
}) | ||
}) |
30 changes: 30 additions & 0 deletions
30
src/containers/shared/components/Transaction/Clawback/test/ClawbackSimple.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { createSimpleWrapperFactory, expectSimpleRowText } from '../../test' | ||
import { Simple } from '../Simple' | ||
import transaction from './mock_data/Clawback.json' | ||
import transactionFailure from './mock_data/Clawback_Failure.json' | ||
|
||
const createWrapper = createSimpleWrapperFactory(Simple) | ||
|
||
describe('Clawback', () => { | ||
it('handles Clawback simple view ', () => { | ||
const wrapper = createWrapper(transaction) | ||
expectSimpleRowText(wrapper, 'holder', 'rscBWQpyZEmQvupeB1quu7Ky8YX4f5CHDP') | ||
expectSimpleRowText( | ||
wrapper, | ||
'amount', | ||
'3,840.00 FOO.rDZ713igKfedN4hhY6SjQse4Mv3ZrBxnn9', | ||
) | ||
wrapper.unmount() | ||
}) | ||
|
||
it('handles failed Clawback simple view ', () => { | ||
const wrapper = createWrapper(transactionFailure) | ||
expectSimpleRowText(wrapper, 'holder', 'rDZ713igKfedN4hhY6SjQse4Mv3ZrBxnn9') | ||
expectSimpleRowText( | ||
wrapper, | ||
'amount', | ||
'4,840.00 FOO.rscBWQpyZEmQvupeB1quu7Ky8YX4f5CHDP', | ||
) | ||
wrapper.unmount() | ||
}) | ||
}) |
15 changes: 15 additions & 0 deletions
15
src/containers/shared/components/Transaction/Clawback/test/ClawbackTableDetail.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { createTableDetailWrapperFactory } from '../../test' | ||
import { TableDetail } from '../TableDetail' | ||
import transaction from './mock_data/Clawback.json' | ||
|
||
const createWrapper = createTableDetailWrapperFactory(TableDetail) | ||
|
||
describe('Clawback', () => { | ||
it('handles Clawback TableDetail ', () => { | ||
const wrapper = createWrapper(transaction) | ||
expect(wrapper.find('.clawback')).toHaveText( | ||
`claws_back3,840.00 FOO.rDZ713igKfedN4hhY6SjQse4Mv3ZrBxnn9fromrscBWQpyZEmQvupeB1quu7Ky8YX4f5CHDP`, | ||
) | ||
wrapper.unmount() | ||
}) | ||
}) |
81 changes: 81 additions & 0 deletions
81
src/containers/shared/components/Transaction/Clawback/test/mock_data/Clawback.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
{ | ||
"tx": { | ||
"Account": "rDZ713igKfedN4hhY6SjQse4Mv3ZrBxnn9", | ||
"Amount": { | ||
"currency": "FOO", | ||
"issuer": "rscBWQpyZEmQvupeB1quu7Ky8YX4f5CHDP", | ||
"value": "4840" | ||
}, | ||
"Fee": "10", | ||
"Flags": 0, | ||
"LastLedgerSequence": 515, | ||
"Sequence": 492, | ||
"SigningPubKey": "ED4B74169976E689D549ED4A50BF06C1174115D363CF9E14031030D2BB5CAA274D", | ||
"TransactionType": "Clawback", | ||
"TxnSignature": "E3C2138CA0C09DD4243DB47B562BDE334CFADFDFF39B50DE7E2A3D6FBCB1ADD89CCAF19A7DE08C3C295974492C3FC7E7CD71FB040A582154EC26DB09D1AEF800", | ||
"date": 1688136937000 | ||
}, | ||
"meta": { | ||
"AffectedNodes": [ | ||
{ | ||
"ModifiedNode": { | ||
"FinalFields": { | ||
"Account": "rDZ713igKfedN4hhY6SjQse4Mv3ZrBxnn9", | ||
"Balance": "99999999960", | ||
"Flags": 2155872256, | ||
"OwnerCount": 0, | ||
"Sequence": 493 | ||
}, | ||
"LedgerEntryType": "AccountRoot", | ||
"LedgerIndex": "057A552C60FE5AC6C77FC70C28209BB4D33C60C6A350DACEF609C48FE12A4387", | ||
"PreviousFields": { | ||
"Balance": "99999999970", | ||
"Sequence": 492 | ||
}, | ||
"PreviousTxnID": "E6EF19434F7FF87AB6EE7127A19D9FBC822B3E8E7C26264A902703424AB1F188", | ||
"PreviousTxnLgrSeq": 493 | ||
} | ||
}, | ||
{ | ||
"ModifiedNode": { | ||
"FinalFields": { | ||
"Balance": { | ||
"currency": "FOO", | ||
"issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", | ||
"value": "0" | ||
}, | ||
"Flags": 65536, | ||
"HighLimit": { | ||
"currency": "FOO", | ||
"issuer": "rDZ713igKfedN4hhY6SjQse4Mv3ZrBxnn9", | ||
"value": "0" | ||
}, | ||
"HighNode": "0", | ||
"LowLimit": { | ||
"currency": "FOO", | ||
"issuer": "rscBWQpyZEmQvupeB1quu7Ky8YX4f5CHDP", | ||
"value": "0" | ||
}, | ||
"LowNode": "0" | ||
}, | ||
"LedgerEntryType": "RippleState", | ||
"LedgerIndex": "907573E62311BAC99A985BBBB38DAB09D89B0C47167AB6E280DD2B309CFAF31B", | ||
"PreviousFields": { | ||
"Balance": { | ||
"currency": "FOO", | ||
"issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", | ||
"value": "3840" | ||
} | ||
}, | ||
"PreviousTxnID": "FEF8B23EB453ECC8BE0D4104CEB0B481E029213848EC1BD11470F8B8C3E6B424", | ||
"PreviousTxnLgrSeq": 494 | ||
} | ||
} | ||
], | ||
"TransactionIndex": 0, | ||
"TransactionResult": "tesSUCCESS" | ||
}, | ||
"hash": "0E09D8C61C799AF206D66F81561EC5B52641B439EEA47CB4F5637A918FB51536", | ||
"ledger_index": 496, | ||
"date": 1688136937000 | ||
} |
Oops, something went wrong.