Skip to content

Commit 65381b3

Browse files
committed
feat(cli): add set-token xrpl subcommand
1 parent 0d37df1 commit 65381b3

4 files changed

Lines changed: 125 additions & 2 deletions

File tree

cli/src/commands/xrpl/README.md

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ An MPT is `create-mpt` (issuer) + `authorize-mpt` (each holder).
3636
| Command | Signed by | XRPL transaction | Purpose |
3737
| ----------------- | --------------- | --------------------------------- | ------------------------------------------------------------- |
3838
| `set-manager` || _(none — writes deployment.json)_ | Record the custody account so later commands don't re-pass it |
39+
| `set-token` || _(none — writes deployment.json)_ | Record the NTT token address + decimals |
3940
| `fund` | source / faucet | `Payment` / faucet | Fund the account for a signer list + tickets |
4041
| `reserve-tickets` | custody | `TicketCreate` | Pre-allocate tickets |
4142
| `init` | custody | `Payment` + onboarding memo | Onboard the account to the Wormhole Core |
@@ -128,6 +129,24 @@ other custody commands can default `--account` to it. No XRPL transaction.
128129
ntt xrpl set-manager --account r9qA...
129130
```
130131

132+
### `set-token`
133+
134+
Records the deployment's NTT token in the deployment file (`xrpl.token` +
135+
`xrpl.decimals`). Native XRP is recorded as `"native"`; IOU/MPT identifiers are
136+
validated and normalized with the Wormhole SDK's XRPL address conventions
137+
(`XrplAddress` from `@wormhole-foundation/sdk-xrpl`). No XRPL transaction.
138+
139+
- `--token` (required) — `native` for native XRP, an IOU `CODE.rIssuer`, or a
140+
48-char hex MPT issuance id
141+
- `--decimals` (required) — token decimals on XRPL (e.g. `6` for XRP), `0``255`
142+
- `--path` — deployment file (default `deployment.json`)
143+
144+
```
145+
ntt xrpl set-token --token native --decimals 6 # native XRP
146+
ntt xrpl set-token --token FOO.rBa2jdUu8S2ZzaCJv8y1Lx9Pdrns51hJj --decimals 9 # IOU
147+
ntt xrpl set-token --token 00EE5E8C9F... --decimals 9 # MPT
148+
```
149+
131150
### `fund`
132151

133152
Funds the custody account with enough XRP to cover the reserve for a signer list
@@ -316,11 +335,17 @@ ntt xrpl rotate-admin -n Testnet --new-admin r9qA... --admin-seed sEd7...
316335
(kept out of `chains`, which expects a full NTT config):
317336

318337
```json
319-
{ "network": "Testnet", "chains": { }, "xrpl": { "manager": "r9qA..." } }
338+
{
339+
"network": "Testnet",
340+
"chains": { },
341+
"xrpl": { "manager": "r9qA...", "token": "native", "decimals": 6 }
342+
}
320343
```
321344

322345
`fund`, `reserve-tickets`, and `set-signer-list` read `xrpl.manager` as the
323-
default account when `--account` is omitted.
346+
default account when `--account` is omitted. `set-token` records the optional
347+
`token` and `decimals` — the token (`"native"` for native XRP, an IOU
348+
`CODE.rIssuer`, or a 48-char hex MPT issuance id) and its decimals on XRPL.
324349

325350
## Common options
326351

cli/src/commands/xrpl/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { createEnableRipplingCommand } from "./enable-rippling";
88
import { createTrustSetCommand } from "./trust-set";
99
import { createXrplInitCommand } from "./init";
1010
import { createXrplSetManagerCommand } from "./set-manager";
11+
import { createXrplSetTokenCommand } from "./set-token";
1112
import { createXrplFundCommand } from "./fund";
1213
import { createXrplReserveTicketsCommand } from "./reserve-tickets";
1314
import { createXrplSetSignerListCommand } from "./set-signer-list";
@@ -29,6 +30,7 @@ import { createXrplRotateAdminCommand } from "./rotate-admin";
2930
*
3031
* Custody-account setup (run in order, while you still hold the account key):
3132
* set-manager — record the custody account in the deployment file
33+
* set-token — record the NTT token (address + decimals) in the deployment file
3234
* fund — fund the account for a signer list + tickets
3335
* reserve-tickets — pre-allocate tickets (TicketCreate)
3436
* init — send the XRPLAppOnboarding message
@@ -54,6 +56,7 @@ export function createXrplCommand(overrides: WormholeConfigOverrides<Network>) {
5456
.command(createCreateMptCommand(overrides))
5557
.command(createAuthorizeMptCommand(overrides))
5658
.command(createXrplSetManagerCommand(overrides))
59+
.command(createXrplSetTokenCommand(overrides))
5760
.command(createXrplFundCommand(overrides))
5861
.command(createXrplReserveTicketsCommand(overrides))
5962
.command(createXrplInitCommand(overrides))

cli/src/commands/xrpl/set-token.ts

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import fs from "fs";
2+
import type {
3+
Network,
4+
WormholeConfigOverrides,
5+
} from "@wormhole-foundation/sdk-connect";
6+
import { colors } from "../../colors.js";
7+
import { loadConfig } from "../../deployments";
8+
import { runXrpl } from "../../xrpl/helpers";
9+
import { XrplAddress, XrplZeroAddress } from "@wormhole-foundation/sdk-xrpl";
10+
import { options } from "../shared";
11+
12+
const XRP_DECIMALS = 6;
13+
14+
export function createXrplSetTokenCommand(
15+
_overrides: WormholeConfigOverrides<Network>
16+
) {
17+
return {
18+
command: "set-token",
19+
describe:
20+
"Record the XRPL NTT token (address + decimals) in the deployment file",
21+
builder: (yargs: any) =>
22+
yargs
23+
.option("token", {
24+
describe:
25+
'Token: "native" for native XRP, an IOU "CODE.rIssuer", or a ' +
26+
"48-char hex MPT issuance id (IOU/MPT validated via the Wormhole " +
27+
"SDK XRPL address conventions)",
28+
type: "string",
29+
demandOption: true,
30+
})
31+
.option("decimals", {
32+
describe: "Token decimals on XRPL (e.g. 6 for XRP); 0-255",
33+
type: "number",
34+
demandOption: true,
35+
})
36+
.option("path", options.deploymentPath)
37+
.example(
38+
"$0 xrpl set-token --token native --decimals 6",
39+
"Record native XRP"
40+
)
41+
.example(
42+
"$0 xrpl set-token --token FOO.rBa2jdUu8S2ZzaCJv8y1Lx9Pdrns51hJj --decimals 9",
43+
"Record an IOU token"
44+
)
45+
.example(
46+
"$0 xrpl set-token --token 00EE5E8C9F... --decimals 9",
47+
"Record an MPT token (48-char hex issuance id)"
48+
),
49+
handler: (argv: any) =>
50+
runXrpl(async () => {
51+
const path = argv.path;
52+
const config = loadConfig(path);
53+
54+
// Native XRP is recorded as the literal "native" (the zero/black-hole
55+
// account is also accepted and normalized to it). IOU/MPT identifiers
56+
// are validated + normalized via the SDK's XRPL address conventions.
57+
const raw = String(argv.token);
58+
const token =
59+
raw.toLowerCase() === "native" || raw === XrplZeroAddress
60+
? "native"
61+
: new XrplAddress(raw).toString();
62+
63+
const decimals = argv.decimals;
64+
if (!Number.isInteger(decimals) || decimals < 0 || decimals > 255) {
65+
throw new Error(
66+
`--decimals must be an integer between 0 and 255, got ${decimals}`
67+
);
68+
}
69+
70+
if (token === "native" && decimals != XRP_DECIMALS) {
71+
throw new Error(
72+
`--decimals must be 6 if the token is XRP, got ${decimals}`
73+
);
74+
}
75+
76+
config.xrpl = { ...config.xrpl, token, decimals };
77+
fs.writeFileSync(path, JSON.stringify(config, null, 2));
78+
79+
console.log(
80+
colors.green(
81+
`✅ Recorded XRPL token: ${colors.yellow(token)} (${decimals} decimals)`
82+
)
83+
);
84+
console.log(` ${path} → xrpl.token, xrpl.decimals`);
85+
}),
86+
};
87+
}

cli/src/deployments.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@ export type HyperCoreConfig = {
3333
// the full ChainConfig shape.
3434
export type XrplConfig = {
3535
manager?: string;
36+
// The NTT token: "native" for native XRP, otherwise the Wormhole SDK XRPL
37+
// platform address (`XrplAddress` from `@wormhole-foundation/sdk-xrpl`) — an
38+
// IOU "CODE.rIssuer" or a 48-char hex MPT issuance id. Recorded by
39+
// `ntt xrpl set-token`.
40+
token?: string;
41+
// Token decimals on XRPL (e.g. 6 for XRP, the MPT AssetScale, or the chosen
42+
// precision for an IOU). Recorded by `ntt xrpl set-token`.
43+
decimals?: number;
3644
};
3745

3846
export type Config = {

0 commit comments

Comments
 (0)