) => {
+ const { Asset, Asset2 } = data.tx
+
+ return (
+
+ ,
+ Asset2: (
+
+ ),
+ }}
+ />
+
+
+
+ )
+}
diff --git a/src/containers/shared/components/Transaction/AMMDelete/Simple.tsx b/src/containers/shared/components/Transaction/AMMDelete/Simple.tsx
new file mode 100644
index 000000000..c84f65b71
--- /dev/null
+++ b/src/containers/shared/components/Transaction/AMMDelete/Simple.tsx
@@ -0,0 +1,24 @@
+import { useTranslation } from 'react-i18next'
+
+import { type AMMDelete } from 'xrpl'
+import { SimpleRow } from '../SimpleRow'
+import { TransactionSimpleProps } from '../types'
+import Currency from '../../Currency'
+
+export const Simple = ({ data }: TransactionSimpleProps) => {
+ const { t } = useTranslation()
+ const { Asset, Asset2 } = data.instructions
+
+ return (
+ <>
+
+ {/* @ts-expect-error -- Fixed by https://github.com/XRPLF/xrpl.js/pull/2451 */}
+
+
+
+ {/* @ts-expect-error -- Fixed by https://github.com/XRPLF/xrpl.js/pull/2451 */}
+
+
+ >
+ )
+}
diff --git a/src/containers/shared/components/Transaction/AMMDelete/TableDetail.tsx b/src/containers/shared/components/Transaction/AMMDelete/TableDetail.tsx
new file mode 100644
index 000000000..afa29d03e
--- /dev/null
+++ b/src/containers/shared/components/Transaction/AMMDelete/TableDetail.tsx
@@ -0,0 +1,24 @@
+import { useTranslation } from 'react-i18next'
+import { type AMMDelete } from 'xrpl'
+import { TransactionTableDetailProps } from '../types'
+import Currency from '../../Currency'
+
+export const TableDetail = ({
+ instructions,
+}: TransactionTableDetailProps) => {
+ const { t } = useTranslation()
+ const { Asset, Asset2 } = instructions
+
+ return (
+
+
+ {t('asset')}
+
+
+
+ {t('asset2')}
+
+
+
+ )
+}
diff --git a/src/containers/shared/components/Transaction/AMMDelete/index.ts b/src/containers/shared/components/Transaction/AMMDelete/index.ts
new file mode 100644
index 000000000..ef0e659a1
--- /dev/null
+++ b/src/containers/shared/components/Transaction/AMMDelete/index.ts
@@ -0,0 +1,19 @@
+import { type AMMDelete } from 'xrpl'
+import {
+ TransactionAction,
+ TransactionCategory,
+ TransactionMapping,
+} from '../types'
+import { Description } from './Description'
+
+import { Simple } from './Simple'
+import { TableDetail } from './TableDetail'
+
+export const AMMDeleteTransaction: TransactionMapping = {
+ Description,
+ TableDetail,
+ Simple,
+ action: TransactionAction.CANCEL,
+ category: TransactionCategory.DEX,
+ parser: (tx: AMMDelete): AMMDelete => tx,
+}
diff --git a/src/containers/shared/components/Transaction/AMMDelete/test/AMMDeleteDescription.test.tsx b/src/containers/shared/components/Transaction/AMMDelete/test/AMMDeleteDescription.test.tsx
new file mode 100644
index 000000000..b1b5e5cb7
--- /dev/null
+++ b/src/containers/shared/components/Transaction/AMMDelete/test/AMMDeleteDescription.test.tsx
@@ -0,0 +1,22 @@
+import i18n from '../../../../../../i18n/testConfigEnglish'
+import mockAMMDelete from './mock_data/AMMDelete.json'
+import { Description } from '../Description'
+import { createDescriptionWrapperFactory } from '../../test'
+
+const createWrapper = createDescriptionWrapperFactory(Description, i18n)
+
+describe('AMMDelete: Description', () => {
+ it('renders description for AMMDelete transaction', () => {
+ const wrapper = createWrapper(mockAMMDelete)
+
+ expect(wrapper.find('[data-test="amm-delete-description"]')).toHaveText(
+ 'Attempted to delete the AMM for \uE900 XRP and FOO.rm5c42Crqpdch5fbuCdHmSMV1wrL9arV9.If there were more than 512 trustlines, this only removes 512 trustlines instead.',
+ )
+ expect(wrapper.find('a')).toHaveProp(
+ 'href',
+ '/token/FOO.rm5c42Crqpdch5fbuCdHmSMV1wrL9arV9',
+ )
+
+ wrapper.unmount()
+ })
+})
diff --git a/src/containers/shared/components/Transaction/AMMDelete/test/AMMDeleteSimple.test.tsx b/src/containers/shared/components/Transaction/AMMDelete/test/AMMDeleteSimple.test.tsx
new file mode 100644
index 000000000..b516be24a
--- /dev/null
+++ b/src/containers/shared/components/Transaction/AMMDelete/test/AMMDeleteSimple.test.tsx
@@ -0,0 +1,21 @@
+import i18n from '../../../../../../i18n/testConfigEnglish'
+import { expectSimpleRowText } from '../../test'
+
+import { createSimpleWrapperFactory } from '../../test/createWrapperFactory'
+import { Simple } from '../Simple'
+import mockAMMDelete from './mock_data/AMMDelete.json'
+
+const createWrapper = createSimpleWrapperFactory(Simple, i18n)
+
+describe('AMMDelete: Simple', () => {
+ it('renders', () => {
+ const wrapper = createWrapper(mockAMMDelete) // TOOD: - Make this look up asset 1 / asset 2 currency codes
+ expectSimpleRowText(wrapper, 'asset1', '\uE900 XRP')
+ expectSimpleRowText(
+ wrapper,
+ 'asset2',
+ 'FOO.rm5c42Crqpdch5fbuCdHmSMV1wrL9arV9',
+ )
+ wrapper.unmount()
+ })
+})
diff --git a/src/containers/shared/components/Transaction/AMMDelete/test/AMMDeleteTableDetail.test.tsx b/src/containers/shared/components/Transaction/AMMDelete/test/AMMDeleteTableDetail.test.tsx
new file mode 100644
index 000000000..07278226f
--- /dev/null
+++ b/src/containers/shared/components/Transaction/AMMDelete/test/AMMDeleteTableDetail.test.tsx
@@ -0,0 +1,18 @@
+import { TableDetail } from '../TableDetail'
+import mockAMMDelete from './mock_data/AMMDelete.json'
+import { createTableDetailWrapperFactory } from '../../test'
+import i18n from '../../../../../../i18n/testConfigEnglish'
+
+const createWrapper = createTableDetailWrapperFactory(TableDetail, i18n)
+
+describe('AMMDelete: TableDetail', () => {
+ it('renders with an expiration and offer', () => {
+ const wrapper = createWrapper(mockAMMDelete)
+
+ expect(wrapper.find('[data-test="asset"]')).toHaveText('asset\uE900 XRP')
+ expect(wrapper.find('[data-test="asset2"]')).toHaveText(
+ 'Asset 2FOO.rm5c42Crqpdch5fbuCdHmSMV1wrL9arV9',
+ )
+ wrapper.unmount()
+ })
+})
diff --git a/src/containers/shared/components/Transaction/AMMDelete/test/mock_data/AMMDelete.json b/src/containers/shared/components/Transaction/AMMDelete/test/mock_data/AMMDelete.json
new file mode 100644
index 000000000..36db32e27
--- /dev/null
+++ b/src/containers/shared/components/Transaction/AMMDelete/test/mock_data/AMMDelete.json
@@ -0,0 +1,48 @@
+{
+ "tx": {
+ "Account": "rm5c42Crqpdch5fbuCdHmSMV1wrL9arV9",
+ "Asset": {
+ "currency": "XRP"
+ },
+ "Asset2": {
+ "currency": "FOO",
+ "issuer": "rm5c42Crqpdch5fbuCdHmSMV1wrL9arV9"
+ },
+ "Fee": "12",
+ "Flags": 0,
+ "LastLedgerSequence": 372572,
+ "Sequence": 372548,
+ "SigningPubKey": "ED6784394D134E202BCCD957A1A3C5A66647092F3929D388A878A16D1910875435",
+ "TransactionType": "AMMDelete",
+ "TxnSignature": "F9AA459D8CE593E6E2E69BB6A6F723A4822FD5F40314F642FA9EC5187F7FD937FBD3E8A214119D04C74358A3478DCB6EAABE02EFAC1E6E125E15310E18A36D0D",
+ "date": 1693268101000
+ },
+ "meta": {
+ "AffectedNodes": [
+ {
+ "ModifiedNode": {
+ "FinalFields": {
+ "Account": "rm5c42Crqpdch5fbuCdHmSMV1wrL9arV9",
+ "Balance": "9997998976",
+ "Flags": 8388608,
+ "OwnerCount": 1,
+ "Sequence": 372549
+ },
+ "LedgerEntryType": "AccountRoot",
+ "LedgerIndex": "84CA74ECFDB34F014142013B4CD2FBE3942C7BA9BA7E1FC5A1CB1EF719173812",
+ "PreviousFields": {
+ "Balance": "9997998988",
+ "Sequence": 372548
+ },
+ "PreviousTxnID": "E5051DA09F143A719521D6ABBB3856EA3E2CA38EF1CFF0E7DF9FE1C31DD73B6D",
+ "PreviousTxnLgrSeq": 372552
+ }
+ }
+ ],
+ "TransactionIndex": 0,
+ "TransactionResult": "tecAMM_NOT_EMPTY"
+ },
+ "hash": "D159883D456646562F51F3E5A2754F7D880D39A6372EDF679A43A7DDB77F735C",
+ "ledger_index": 372554,
+ "date": 1693268101000
+}
diff --git a/src/containers/shared/components/Transaction/README.md b/src/containers/shared/components/Transaction/README.md
index 588605bfa..080721f14 100644
--- a/src/containers/shared/components/Transaction/README.md
+++ b/src/containers/shared/components/Transaction/README.md
@@ -7,7 +7,7 @@ Each transaction has its properties defined in `./{TransactionType}/index.ts`.
- **TableDetail**: A React component that defines the body of transaction on the account, ledger, token, or nft page.
- **action**: A TransactionCategory value used to determine shape color of the transaction.
- **category**: A TransactionCategory value used to determine the color of the transaction.
-- **parser**: A function which takes a transaction object and meta nodes. It returns additional properties to map onto a transaction.
+- **parser**: An optional function which takes a transaction object and meta nodes. It returns additional properties to map onto a transaction.
This is run when a transaction is received from the server and is useful for transforming complex properties derived from nodes.
This object is then provided in `./index.ts`
diff --git a/src/containers/shared/components/Transaction/index.ts b/src/containers/shared/components/Transaction/index.ts
index c6e2bdf9a..77c03ab3b 100644
--- a/src/containers/shared/components/Transaction/index.ts
+++ b/src/containers/shared/components/Transaction/index.ts
@@ -1,5 +1,6 @@
import { AMMCreate } from './AMMCreate'
import { AMMDeposit } from './AMMDeposit'
+import { AMMDeleteTransaction as AMMDelete } from './AMMDelete'
import { AMMWithdraw } from './AMMWithdraw'
import { AMMBid } from './AMMBid'
import { AMMVote } from './AMMVote'
@@ -81,6 +82,7 @@ export const transactionTypes: { [key: string]: TransactionMapping } = {
AMMDeposit,
AMMBid,
AMMVote,
+ AMMDelete,
TrustSet,
UNLModify,
Clawback,
diff --git a/src/containers/shared/types.ts b/src/containers/shared/types.ts
index 877de0c0b..4b847a730 100644
--- a/src/containers/shared/types.ts
+++ b/src/containers/shared/types.ts
@@ -8,6 +8,7 @@ export interface IssuedCurrency {
export interface XRP {
currency: 'XRP'
+ issuer: never
}
export type Currency = IssuedCurrency | XRP