diff --git a/.ci-config/rippled.cfg b/.ci-config/rippled.cfg index 673c1e3505..80878e01c2 100644 --- a/.ci-config/rippled.cfg +++ b/.ci-config/rippled.cfg @@ -188,3 +188,4 @@ fixNFTokenPageLinks fixInnerObjTemplate2 fixEnforceNFTokenTrustline fixReducedOffersV2 +DeepFreeze diff --git a/packages/xrpl/HISTORY.md b/packages/xrpl/HISTORY.md index b834707f69..90a5b6c267 100644 --- a/packages/xrpl/HISTORY.md +++ b/packages/xrpl/HISTORY.md @@ -4,6 +4,9 @@ Subscribe to [the **xrpl-announce** mailing list](https://groups.google.com/g/xr ## Unreleased Changes +### Added +* Support for XLS-77d Deep-Freeze amendment + ## 4.1.0 (2024-12-23) ### Added diff --git a/packages/xrpl/src/models/ledger/RippleState.ts b/packages/xrpl/src/models/ledger/RippleState.ts index 907907e010..0250e63c13 100644 --- a/packages/xrpl/src/models/ledger/RippleState.ts +++ b/packages/xrpl/src/models/ledger/RippleState.ts @@ -77,4 +77,8 @@ export enum RippleStateFlags { lsfHighFreeze = 0x00800000, // True, trust line to AMM. Used by client apps to identify payments via AMM. lsfAMMNode = 0x01000000, + // True, low side has set deep freeze flag + lsfLowDeepFreeze = 0x02000000, + // True, high side has set deep freeze flag + lsfHighDeepFreeze = 0x04000000, } diff --git a/packages/xrpl/src/models/transactions/trustSet.ts b/packages/xrpl/src/models/transactions/trustSet.ts index f584261af3..e27ca43306 100644 --- a/packages/xrpl/src/models/transactions/trustSet.ts +++ b/packages/xrpl/src/models/transactions/trustSet.ts @@ -30,6 +30,10 @@ export enum TrustSetFlags { tfSetFreeze = 0x00100000, /** Unfreeze the trust line. */ tfClearFreeze = 0x00200000, + /** Deep-Freeze the trust line -- disallow sending and recieving the said IssuedCurrency */ + tfSetDeepFreeze = 0x00400000, + /** Clear a Deep-Frozen trust line */ + tfClearDeepFreeze = 0x00800000, } /** @@ -89,6 +93,10 @@ export interface TrustSetFlagsInterface extends GlobalFlags { tfSetFreeze?: boolean /** Unfreeze the trust line. */ tfClearFreeze?: boolean + /** Deep-Freeze the trust line -- disallow sending and recieving the said IssuedCurrency */ + tfSetDeepFreeze?: boolean + /** Clear a Deep-Frozen trust line */ + tfClearDeepFreeze?: boolean } /** diff --git a/packages/xrpl/test/integration/transactions/offerCreate.test.ts b/packages/xrpl/test/integration/transactions/offerCreate.test.ts index 7d7bf0f2bf..86b5a8cda6 100644 --- a/packages/xrpl/test/integration/transactions/offerCreate.test.ts +++ b/packages/xrpl/test/integration/transactions/offerCreate.test.ts @@ -1,24 +1,36 @@ import { assert } from 'chai' -import { OfferCreate } from '../../../src' +import { OfferCreate, TrustSet, Wallet } from '../../../src' import serverUrl from '../serverUrl' import { setupClient, teardownClient, type XrplIntegrationTestContext, } from '../setup' -import { testTransaction } from '../utils' +import { + testTransaction, + generateFundedWallet, + submitTransaction, +} from '../utils' // how long before each test case times out const TIMEOUT = 20000 describe('OfferCreate', function () { let testContext: XrplIntegrationTestContext + let wallet_deep_freeze_trustline: Wallet | undefined - beforeEach(async () => { + beforeAll(async () => { testContext = await setupClient(serverUrl) + if (!wallet_deep_freeze_trustline) { + // eslint-disable-next-line require-atomic-updates -- race condition doesn't really matter + wallet_deep_freeze_trustline = await generateFundedWallet( + testContext.client, + ) + } }) - afterEach(async () => teardownClient(testContext)) + + afterAll(async () => teardownClient(testContext)) it( 'base', @@ -49,4 +61,52 @@ describe('OfferCreate', function () { }, TIMEOUT, ) + + it( + 'OfferCreate with Deep-Frozen trust-line must fail', + async () => { + assert(wallet_deep_freeze_trustline != null) + + // deep-freeze the trust line + const trust_set_tx: TrustSet = { + TransactionType: 'TrustSet', + Account: testContext.wallet.classicAddress, + LimitAmount: { + currency: 'USD', + issuer: wallet_deep_freeze_trustline.classicAddress, + value: '10', + }, + Flags: { + tfSetFreeze: true, + tfSetDeepFreeze: true, + }, + } + + await testTransaction( + testContext.client, + trust_set_tx, + testContext.wallet, + ) + + const offer_create_tx: OfferCreate = { + TransactionType: 'OfferCreate', + Account: testContext.wallet.classicAddress, + TakerGets: '13100000', + TakerPays: { + currency: 'USD', + issuer: wallet_deep_freeze_trustline.classicAddress, + value: '10', + }, + } + + const response = await submitTransaction({ + client: testContext.client, + transaction: offer_create_tx, + wallet: testContext.wallet, + }) + + assert.equal(response.result.engine_result, 'tecFROZEN') + }, + TIMEOUT, + ) }) diff --git a/packages/xrpl/test/integration/transactions/trustSet.test.ts b/packages/xrpl/test/integration/transactions/trustSet.test.ts index 7736d0d107..f44311fba0 100644 --- a/packages/xrpl/test/integration/transactions/trustSet.test.ts +++ b/packages/xrpl/test/integration/transactions/trustSet.test.ts @@ -85,4 +85,45 @@ describe('TrustSet', function () { }, TIMEOUT, ) + + it( + 'Create a Deep-Frozen trust line', + async () => { + assert(wallet2 != null) + // preemptively deep-freeze a trust line with the specified counter-party/currency-code + const tx: TrustSet = { + TransactionType: 'TrustSet', + Account: testContext.wallet.classicAddress, + LimitAmount: { + currency: 'USD', + issuer: wallet2.classicAddress, + value: '10', + }, + Flags: { + tfSetFreeze: true, + tfSetDeepFreeze: true, + }, + } + + const response = await testTransaction( + testContext.client, + tx, + testContext.wallet, + ) + assert.equal(response.result.engine_result, 'tesSUCCESS') + + // assert that the trust line is deep-frozen + const trustLine = await testContext.client.request({ + command: 'account_lines', + account: testContext.wallet.classicAddress, + }) + + // assert that the TrustLine is deep-frozen + assert.equal(trustLine.result.lines[0].freeze, true) + + // Keshava: ensure that account_lines RPC response contains a deep_freeze flag + // assert.equal(trustLine.result.lines[0].deep_freeze, true) + }, + TIMEOUT, + ) }) diff --git a/packages/xrpl/test/models/trustSet.test.ts b/packages/xrpl/test/models/trustSet.test.ts index ce1b05ebcd..b634cc04da 100644 --- a/packages/xrpl/test/models/trustSet.test.ts +++ b/packages/xrpl/test/models/trustSet.test.ts @@ -22,6 +22,11 @@ describe('TrustSet', function () { }, QualityIn: 1234, QualityOut: 4321, + // an example of deep-frozen trust line + Flags: { + tfSetFreeze: true, + tfSetDeepFreeze: true, + }, } as any })