diff --git a/cli/src/__tests__/xrpl-onboarding.test.ts b/cli/src/__tests__/xrpl-onboarding.test.ts index 38a895440..832e02ea7 100644 --- a/cli/src/__tests__/xrpl-onboarding.test.ts +++ b/cli/src/__tests__/xrpl-onboarding.test.ts @@ -33,27 +33,25 @@ describe("buildInitData", () => { expect(buildInitData(8, { type: "xrp" })).toBe("08"); }); - test("iou: decimals + 0x01 + currency + issuer, right-padded to 43 bytes total", () => { + test("iou: decimals + 0x01 + currency + issuer = 42 bytes total (no padding)", () => { const out = buildInitData(9, { type: "iou", currency: FOO_CURRENCY, issuer: ADMIN, }); const issuerHex = Buffer.from(decodeAccountID(ADMIN)).toString("hex"); - // 1 (decimals) + 42 (token_id padded) = 43 bytes => 86 hex chars - expect(out.length).toBe(86); - expect( - out.startsWith("09" + "01" + FOO_CURRENCY.toLowerCase() + issuerHex) - ).toBe(true); - // trailing byte is zero padding (41 bytes of data -> padded to 42) - expect(out.endsWith("00")).toBe(true); + // 1 (decimals) + 41 (token_id) = 42 bytes => 84 hex chars + expect(out.length).toBe(84); + // IOU token_id fills all 41 bytes (1 + 20 + 20) with no trailing padding. + expect(out).toBe("09" + "01" + FOO_CURRENCY.toLowerCase() + issuerHex); }); - test("mpt: decimals + 0x02 + mpt_id, right-padded to 43 bytes total", () => { + test("mpt: decimals + 0x02 + mpt_id, right-padded to 42 bytes total", () => { const out = buildInitData(9, { type: "mpt", mptId: MPT_ID }); - expect(out.length).toBe(86); + // 1 (decimals) + 41 (token_id: 0x02 + 24-byte id, padded from 25 to 41) = 42 bytes => 84 hex chars + expect(out.length).toBe(84); expect(out.startsWith("09" + "02" + MPT_ID)).toBe(true); - // 1 + 2 + 48 = 51 hex of data, padded to 84 -> ends in zeros + // 1 + 24 = 25 bytes of data in the 41-byte token_id -> 16 trailing zero bytes expect(out.endsWith("0000")).toBe(true); }); @@ -95,7 +93,7 @@ describe("buildOnboardingPayload", () => { expect(out.length).toBe(146); }); - test("full form (iou) is 115 bytes", () => { + test("full form (iou) is 114 bytes", () => { const initData = buildInitData(8, { type: "iou", currency: FOO_CURRENCY, @@ -108,8 +106,8 @@ describe("buildOnboardingPayload", () => { ticketCount: 2n, initData, }); - // 72 (fixed) + 43 (init_data) = 115 bytes => 230 hex chars - expect(out.length).toBe(230); + // 72 (fixed) + 42 (init_data) = 114 bytes => 228 hex chars + expect(out.length).toBe(228); }); }); diff --git a/cli/src/commands/xrpl/fund.ts b/cli/src/commands/xrpl/fund.ts index 7c20b0f13..05b82b1ba 100644 --- a/cli/src/commands/xrpl/fund.ts +++ b/cli/src/commands/xrpl/fund.ts @@ -44,7 +44,7 @@ export function createXrplFundCommand( .option("tickets", { describe: "Ticket count to size the reserve for", type: "number", - default: 200, + default: 150, }) .option("faucet", { describe: "Use the testnet/devnet faucet to fund --account", diff --git a/cli/src/commands/xrpl/reserve-tickets.ts b/cli/src/commands/xrpl/reserve-tickets.ts index 1847d9f33..608043c26 100644 --- a/cli/src/commands/xrpl/reserve-tickets.ts +++ b/cli/src/commands/xrpl/reserve-tickets.ts @@ -13,8 +13,8 @@ import { } from "../../xrpl/helpers"; import { withCommon } from "./common"; -// XRPL caps an account at 250 tickets. -const MAX_TICKETS = 250; +// XRPL caps an account at 170 tickets. +const MAX_TICKETS = 170; export function createXrplReserveTicketsCommand( overrides: WormholeConfigOverrides @@ -27,15 +27,15 @@ export function createXrplReserveTicketsCommand( .option("count", { describe: `Number of tickets to create (1-${MAX_TICKETS})`, type: "number", - default: 200, + default: 150, }) .option("issuer-seed", { describe: "Custody account seed (or env ISSUER_SEED)", type: "string", }) .example( - "$0 xrpl reserve-tickets -n Testnet --count 200 --issuer-seed sEd7...", - "Reserve 200 tickets on the custody account" + "$0 xrpl reserve-tickets -n Testnet --count 150 --issuer-seed sEd7...", + "Reserve 150 tickets on the custody account" ), handler: (argv: any) => runXrpl(async () => { diff --git a/cli/src/commands/xrpl/transfer.ts b/cli/src/commands/xrpl/transfer.ts index 50c29d581..ba9518bdc 100644 --- a/cli/src/commands/xrpl/transfer.ts +++ b/cli/src/commands/xrpl/transfer.ts @@ -277,7 +277,7 @@ export async function runTransfer( if (!argv.relay) { console.log( colors.dim( - `\nRelay later with:\n ntt xrpl relay -n ${network} --request-type ern1 \\\n --tx-hash ${txHash} --dst-chain ${argv["dst-chain"]} \\\n --dst-addr ${argv.recipient} --manager ${custody} --executor --seed ` + `\nRelay later with:\n ntt xrpl relay -n ${network} --request-type ERN1 \\\n --tx-hash ${txHash} --dst-chain ${argv["dst-chain"]} \\\n --dst-addr ${argv.recipient} --manager ${custody} --executor --seed ` ) ); return; @@ -287,10 +287,10 @@ export async function runTransfer( throw new Error("--executor is required to relay (or pass --no-relay)"); } - // Hand off to the existing relay flow: it re-derives the ern1 transceiver + // Hand off to the existing relay flow: it re-derives the ERN1 transceiver // emitter + sequence from the tx, polls the VAA, and sends the executor memo. // `--manager custody` lets relay derive the source NTT manager emitter. - console.log(colors.blue("\n↪ Relaying transfer (ern1)...")); + console.log(colors.blue("\n↪ Relaying transfer (ERN1)...")); await runRelay( { network, @@ -298,7 +298,7 @@ export async function runTransfer( algorithm: argv.algorithm, "tx-hash": txHash, "dst-chain": argv["dst-chain"], - "request-type": "ern1", + "request-type": "ERN1", "dst-addr": argv.recipient, manager: custody, "src-manager": argv["src-manager"], diff --git a/cli/src/xrpl/onboarding.ts b/cli/src/xrpl/onboarding.ts index f325d9dfb..ca6d8b4d7 100644 --- a/cli/src/xrpl/onboarding.ts +++ b/cli/src/xrpl/onboarding.ts @@ -38,7 +38,9 @@ const TOKEN_TYPE_IOU = "01"; const TOKEN_TYPE_MPT = "02"; // Size (in bytes) the token_id portion of init_data is right-padded to. -const TOKEN_ID_PADDED_BYTES = 42; +// Must match the Sequencer's `XrplTokenId::STORAGE_SIZE` (41 bytes: +// 1 discriminant + 20 currency + 20 issuer for the largest, IOU, variant). +const TOKEN_ID_PADDED_BYTES = 41; export type TokenInit = | { type: "xrp" } @@ -110,8 +112,8 @@ export function currencyToHex40(currency: string): string { /** * Build the NTT/WTT `init_data` tail (hex, no 0x prefix): * - xrp: short form — just the decimals byte. - * - iou: decimals byte + (0x01 + currency[20] + issuer[20]) right-padded to 42 bytes. - * - mpt: decimals byte + (0x02 + mpt_issuance_id[24]) right-padded to 42 bytes. + * - iou: decimals byte + (0x01 + currency[20] + issuer[20]) = 41 bytes (no padding). + * - mpt: decimals byte + (0x02 + mpt_issuance_id[24]) right-padded to 41 bytes. */ export function buildInitData(decimals: number, token: TokenInit): string { const dec = u8Hex(decimals);