@needmoretruth/nmts-cli 0.34.4 → 0.36.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +11 -12
- package/CHANGELOG.md +43 -0
- package/README.ko.md +33 -35
- package/README.md +21 -22
- package/dist/account.js +2 -1
- package/dist/arg-options.d.ts +169 -0
- package/dist/arg-options.js +10 -0
- package/dist/args.d.ts +2 -157
- package/dist/args.js +2 -0
- package/dist/artifact-about.d.ts +1 -1
- package/dist/autonomy.d.ts +3 -10
- package/dist/autonomy.js +15 -17
- package/dist/bytes.d.ts +15 -0
- package/dist/bytes.js +63 -0
- package/dist/collision.d.ts +5 -5
- package/dist/collision.js +19 -22
- package/dist/commands/delete-account.js +1 -1
- package/dist/commands/erase.js +1 -1
- package/dist/commands/extend.d.ts +2 -0
- package/dist/commands/extend.js +8 -1
- package/dist/commands/get.js +1 -1
- package/dist/commands/listfile.js +1 -1
- package/dist/commands/mcp.js +5 -1
- package/dist/commands/mode.js +2 -2
- package/dist/commands/on-collision.d.ts +1 -1
- package/dist/commands/on-collision.js +3 -3
- package/dist/commands/platform.d.ts +9 -0
- package/dist/commands/platform.js +124 -0
- package/dist/commands/pull.js +1 -1
- package/dist/commands/push-wallet.js +8 -1
- package/dist/commands/push.d.ts +2 -0
- package/dist/commands/push.js +6 -4
- package/dist/commands/put-payer.d.ts +8 -0
- package/dist/commands/put-payer.js +41 -0
- package/dist/commands/put-wallet.d.ts +9 -3
- package/dist/commands/put-wallet.js +108 -186
- package/dist/commands/put.d.ts +5 -7
- package/dist/commands/put.js +11 -31
- package/dist/commands/receive.js +1 -1
- package/dist/commands/settings.js +1 -1
- package/dist/commands/support.js +3 -3
- package/dist/commands/unlock.js +2 -2
- package/dist/commands/wallet-donate.d.ts +3 -0
- package/dist/commands/wallet-donate.js +6 -2
- package/dist/commands/wallet-hall.d.ts +4 -1
- package/dist/commands/wallet-hall.js +16 -8
- package/dist/commands/wallet-list.d.ts +18 -0
- package/dist/commands/wallet-list.js +116 -0
- package/dist/commands/wallet-send.d.ts +4 -0
- package/dist/commands/wallet-send.js +6 -2
- package/dist/commands/wallet-storage-ops.d.ts +4 -1
- package/dist/commands/wallet-storage-ops.js +7 -2
- package/dist/commands/wallet-swap.d.ts +3 -0
- package/dist/commands/wallet-swap.js +8 -4
- package/dist/commands/wallet-use.d.ts +7 -0
- package/dist/commands/wallet-use.js +55 -0
- package/dist/commands/wallet.d.ts +4 -0
- package/dist/commands/wallet.js +20 -8
- package/dist/crypto.d.ts +8 -5
- package/dist/crypto.js +15 -61
- package/dist/download-sink-node.d.ts +49 -0
- package/dist/download-sink-node.js +204 -0
- package/dist/download-sink.d.ts +0 -48
- package/dist/download-sink.js +6 -199
- package/dist/download.js +5 -4
- package/dist/engine-node.d.ts +19 -0
- package/dist/engine-node.js +77 -0
- package/dist/env-vars.d.ts +20 -0
- package/dist/env-vars.js +27 -0
- package/dist/extend-plan.d.ts +2 -0
- package/dist/gate.js +1 -1
- package/dist/help.js +12 -5
- package/dist/host-contract.d.ts +7 -0
- package/dist/host-contract.js +95 -0
- package/dist/host-node.d.ts +27 -0
- package/dist/host-node.js +192 -0
- package/dist/host.d.ts +99 -0
- package/dist/host.js +59 -0
- package/dist/index.d.ts +6 -40
- package/dist/index.js +20 -32
- package/dist/main.js +11 -10
- package/dist/manifest-chunk-cache.d.ts +3 -3
- package/dist/manifest-chunk-cache.js +39 -44
- package/dist/manifest-chunk-flow.js +15 -14
- package/dist/manifest-write.js +1 -1
- package/dist/manifest.d.ts +2 -2
- package/dist/manifest.js +37 -34
- package/dist/mcp-tools/tiers.js +1 -1
- package/dist/network.d.ts +1 -1
- package/dist/network.js +6 -2
- package/dist/platform-sign.d.ts +143 -0
- package/dist/platform-sign.js +220 -0
- package/dist/portable.d.ts +59 -0
- package/dist/portable.js +82 -0
- package/dist/product.d.ts +1 -1
- package/dist/product.js +1 -1
- package/dist/progress-node.d.ts +2 -0
- package/dist/progress-node.js +14 -0
- package/dist/progress.d.ts +0 -1
- package/dist/progress.js +4 -8
- package/dist/redact.js +3 -2
- package/dist/registration.js +5 -2
- package/dist/risk.d.ts +11 -0
- package/dist/risk.js +16 -0
- package/dist/run-log.d.ts +4 -4
- package/dist/run-log.js +29 -36
- package/dist/seal.js +5 -4
- package/dist/server.d.ts +1 -1
- package/dist/server.js +6 -2
- package/dist/setup-questions.js +2 -2
- package/dist/shared/lib/drive/manifest-ops.d.ts +8 -30
- package/dist/shared/lib/drive/manifest-ops.js +7 -39
- package/dist/shared/lib/drive/manifest-settings-patch.d.ts +52 -0
- package/dist/shared/lib/drive/manifest-settings-patch.js +110 -0
- package/dist/shared/lib/drive/manifest-settings.d.ts +55 -4
- package/dist/shared/lib/drive/manifest-settings.js +66 -28
- package/dist/shared/lib/wallet/discover.d.ts +54 -0
- package/dist/shared/lib/wallet/discover.js +66 -0
- package/dist/standing-tip.d.ts +3 -0
- package/dist/standing-tip.js +1 -0
- package/dist/upload-file-node.d.ts +3 -0
- package/dist/upload-file-node.js +38 -0
- package/dist/upload-file.d.ts +2 -2
- package/dist/upload-file.js +15 -45
- package/dist/upload-price-node.d.ts +8 -0
- package/dist/upload-price-node.js +37 -0
- package/dist/upload-price.d.ts +0 -8
- package/dist/upload-price.js +4 -33
- package/dist/upload-steps.js +3 -3
- package/dist/upload-store.d.ts +14 -14
- package/dist/upload-store.js +68 -75
- package/dist/upload-wallet-chain.js +3 -2
- package/dist/upload-wallet-put.d.ts +118 -0
- package/dist/upload-wallet-put.js +221 -0
- package/dist/upload-wallet.d.ts +3 -0
- package/dist/upload-wallet.js +18 -15
- package/dist/upload.js +16 -15
- package/dist/wallet-list-chain.d.ts +4 -0
- package/dist/wallet-list-chain.js +21 -0
- package/dist/wallet-pay-index.d.ts +21 -0
- package/dist/wallet-pay-index.js +68 -0
- package/dist/wallet-sign-seams.d.ts +69 -0
- package/dist/wallet-sign-seams.js +16 -0
- package/dist/wallet-sign.d.ts +3 -53
- package/dist/wallet-sign.js +22 -18
- package/dist/wallet.d.ts +13 -13
- package/dist/wallet.js +15 -15
- package/dist/walrus-write.js +3 -2
- package/dist/walrus.d.ts +1 -16
- package/dist/walrus.js +11 -22
- package/docs/commands/credits.md +1 -1
- package/docs/commands/platform.md +14 -0
- package/docs/commands/support.md +1 -1
- package/docs/commands/trash.md +1 -1
- package/docs/commands/wallet.md +26 -8
- package/package.json +13 -2
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { StorageOpShape } from "./storage-control-chain.ts";
|
|
2
|
+
import type { SwapShape } from "./wallet-swap-chain.ts";
|
|
3
|
+
import type { TransferShape } from "./wallet-send-chain.ts";
|
|
4
|
+
import type { RegisterShape } from "./upload-wallet-plan.ts";
|
|
5
|
+
import type { Certificate } from "./upload-wire.ts";
|
|
6
|
+
import type { Network } from "./network.ts";
|
|
7
|
+
/** The seam `commands/wallet-hall.ts` signs through. Returns the base64 signature, nothing else. */
|
|
8
|
+
export type SignMessage = (input: {
|
|
9
|
+
/** ⛔ The NMTS key. It never leaves this machine: it derives the wallet and nothing else. */
|
|
10
|
+
code: string;
|
|
11
|
+
/**
|
|
12
|
+
* Which of this key's wallets proves the name.
|
|
13
|
+
*
|
|
14
|
+
* ⛔ IT IS THE PAYING WALLET BECAUSE THAT IS THE WALLET THE GIFT CAME FROM. A hall entry is an
|
|
15
|
+
* address, and `wallet donate` sends from the account's own number; signing with any other
|
|
16
|
+
* wallet would offer the server a name for an address that has never given anything.
|
|
17
|
+
*/
|
|
18
|
+
wallet: number;
|
|
19
|
+
message: string;
|
|
20
|
+
}) => Promise<string>;
|
|
21
|
+
/** The seam `commands/wallet-send.ts` signs through. Returns the transaction digest. */
|
|
22
|
+
export type SignTransfer = (input: {
|
|
23
|
+
network: string;
|
|
24
|
+
/** ⛔ The NMTS key. It never leaves this machine: it derives the wallet and nothing else. */
|
|
25
|
+
code: string;
|
|
26
|
+
/** Which of this key's wallets pays — the account's own number (`wallet-pay-index.ts`). */
|
|
27
|
+
wallet: number;
|
|
28
|
+
shape: TransferShape;
|
|
29
|
+
}) => Promise<string>;
|
|
30
|
+
/** The seam `commands/wallet-swap.ts` signs through. Returns the transaction digest. */
|
|
31
|
+
export type SignSwap = (input: {
|
|
32
|
+
network: Network;
|
|
33
|
+
/** ⛔ The NMTS key. It never leaves this machine: it derives the wallet and nothing else. */
|
|
34
|
+
code: string;
|
|
35
|
+
/** Which of this key's wallets swaps — the account's own number (`wallet-pay-index.ts`). */
|
|
36
|
+
wallet: number;
|
|
37
|
+
shape: SwapShape;
|
|
38
|
+
}) => Promise<string>;
|
|
39
|
+
/** The seam the wallet rail registers through. */
|
|
40
|
+
export type SignBlobRegister = (input: {
|
|
41
|
+
network: Network;
|
|
42
|
+
code: string;
|
|
43
|
+
wallet: number;
|
|
44
|
+
relayUrl: string;
|
|
45
|
+
} & RegisterShape) => Promise<{
|
|
46
|
+
digest: string;
|
|
47
|
+
blobObjectId: string;
|
|
48
|
+
endEpoch: number;
|
|
49
|
+
}>;
|
|
50
|
+
/** The seam the wallet rail certifies through. Returns the transaction digest. */
|
|
51
|
+
export type SignBlobCertify = (input: {
|
|
52
|
+
network: Network;
|
|
53
|
+
code: string;
|
|
54
|
+
/** The same wallet that registered the part — it is the one that owns the blob object. */
|
|
55
|
+
wallet: number;
|
|
56
|
+
relayUrl: string;
|
|
57
|
+
blobId: string;
|
|
58
|
+
blobObjectId: string;
|
|
59
|
+
certificate: Certificate;
|
|
60
|
+
}) => Promise<string>;
|
|
61
|
+
/** How a storage-resource operation is signed; the shape carries what the review priced. */
|
|
62
|
+
export type SignStorageOp = (input: {
|
|
63
|
+
network: Network;
|
|
64
|
+
code: string;
|
|
65
|
+
/** Which of this key's wallets holds the resource — the account's own number. */
|
|
66
|
+
wallet: number;
|
|
67
|
+
shape: StorageOpShape;
|
|
68
|
+
walrusPackageId: string;
|
|
69
|
+
}) => Promise<string>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// The shapes the signing module is reached through — one per thing this tool can sign.
|
|
2
|
+
//
|
|
3
|
+
// ⛔ THEY ARE SEAMS BECAUSE A TEST MUST BE ABLE TO PROVE THAT NOTHING SIGNED. Every command that
|
|
4
|
+
// spends prints a review first and stops there without `--yes`; handing it a function that
|
|
5
|
+
// fails the test if it is ever called is the only way to hold that promise, and a signature
|
|
6
|
+
// that reached a chain in a test would cost money every time the suite ran.
|
|
7
|
+
//
|
|
8
|
+
// ⛔ EACH ONE CARRIES **WHICH WALLET** WHERE THE MONEY COMES FROM IT (2026-09-16). One
|
|
9
|
+
// NMTS key opens a wallet at every index and the account says which one pays (`activeWallet`
|
|
10
|
+
// in the sealed file list); the command resolves that number BEFORE it prices anything, so the
|
|
11
|
+
// address in the review is the address that signs. A seam that let the number be omitted would
|
|
12
|
+
// let a review be printed for one wallet and a transaction signed by another.
|
|
13
|
+
//
|
|
14
|
+
// ⚠ They moved out of `wallet-sign.ts` on 2026-09-16 — that file is what signs, and it has a
|
|
15
|
+
// ceiling. Re-exported from there, so no caller spells a new path.
|
|
16
|
+
export {};
|
package/dist/wallet-sign.d.ts
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import type { SignExtension } from "./extend-plan.ts";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
import { type SwapShape } from "./wallet-swap-chain.ts";
|
|
5
|
-
import type { Network } from "./network.ts";
|
|
6
|
-
import type { RegisterShape } from "./upload-wallet-plan.ts";
|
|
7
|
-
import type { Certificate } from "./upload-wire.ts";
|
|
2
|
+
import type { SignBlobCertify, SignBlobRegister, SignMessage, SignStorageOp, SignSwap, SignTransfer } from "./wallet-sign-seams.ts";
|
|
3
|
+
export type { SignBlobCertify, SignBlobRegister, SignMessage, SignStorageOp, SignSwap, SignTransfer, } from "./wallet-sign-seams.ts";
|
|
8
4
|
/**
|
|
9
5
|
* The address this tool would sign as.
|
|
10
6
|
*
|
|
@@ -14,7 +10,7 @@ import type { Certificate } from "./upload-wire.ts";
|
|
|
14
10
|
* part is silent — a signature from an address with nothing in it, or worse, money sent to an
|
|
15
11
|
* address that signs nothing. A test compares them, offline, for free.
|
|
16
12
|
*/
|
|
17
|
-
export declare function signerAddress(code: string): Promise<string>;
|
|
13
|
+
export declare function signerAddress(code: string, index?: number): Promise<string>;
|
|
18
14
|
/**
|
|
19
15
|
* Extend every listed blob by `epochs`, in ONE transaction, signed by the account's own wallet.
|
|
20
16
|
*
|
|
@@ -50,19 +46,6 @@ export declare const signTransfer: SignTransfer;
|
|
|
50
46
|
* signed text from ever being read as a transaction this wallet authorised.
|
|
51
47
|
*/
|
|
52
48
|
export declare const signMessage: SignMessage;
|
|
53
|
-
/** The seam `commands/wallet-hall.ts` signs through. Returns the base64 signature, nothing else. */
|
|
54
|
-
export type SignMessage = (input: {
|
|
55
|
-
/** ⛔ The NMTS key. It never leaves this machine: it derives the wallet and nothing else. */
|
|
56
|
-
code: string;
|
|
57
|
-
message: string;
|
|
58
|
-
}) => Promise<string>;
|
|
59
|
-
/** The seam `commands/wallet-send.ts` signs through. Returns the transaction digest. */
|
|
60
|
-
export type SignTransfer = (input: {
|
|
61
|
-
network: string;
|
|
62
|
-
/** ⛔ The NMTS key. It never leaves this machine: it derives the wallet and nothing else. */
|
|
63
|
-
code: string;
|
|
64
|
-
shape: TransferShape;
|
|
65
|
-
}) => Promise<string>;
|
|
66
49
|
/**
|
|
67
50
|
* Swap SUI for WAL or WAL for SUI on the named venue, in ONE transaction, signed by the account's
|
|
68
51
|
* own wallet. Every output goes back to the signer — DeepBook's three coins are sent there by this
|
|
@@ -75,13 +58,6 @@ export type SignTransfer = (input: {
|
|
|
75
58
|
* ⚠ A FAILURE HERE IS NOT PROOF THAT NOTHING HAPPENED — the same words as the extension above.
|
|
76
59
|
*/
|
|
77
60
|
export declare const signSwap: SignSwap;
|
|
78
|
-
/** The seam `commands/wallet-swap.ts` signs through. Returns the transaction digest. */
|
|
79
|
-
export type SignSwap = (input: {
|
|
80
|
-
network: Network;
|
|
81
|
-
/** ⛔ The NMTS key. It never leaves this machine: it derives the wallet and nothing else. */
|
|
82
|
-
code: string;
|
|
83
|
-
shape: SwapShape;
|
|
84
|
-
}) => Promise<string>;
|
|
85
61
|
/**
|
|
86
62
|
* Register ONE part's blob, signed by the account's own wallet: the relay's tip, then the storage
|
|
87
63
|
* — bought for `epochs`, or a resource the wallet already holds, cut to fit first if asked.
|
|
@@ -97,32 +73,6 @@ export type SignSwap = (input: {
|
|
|
97
73
|
export declare const signBlobRegister: SignBlobRegister;
|
|
98
74
|
/** Certify ONE registered part from the relay's certificate. Gas only; nothing else leaves the wallet. */
|
|
99
75
|
export declare const signBlobCertify: SignBlobCertify;
|
|
100
|
-
/** The seam the wallet rail registers through. */
|
|
101
|
-
export type SignBlobRegister = (input: {
|
|
102
|
-
network: Network;
|
|
103
|
-
code: string;
|
|
104
|
-
relayUrl: string;
|
|
105
|
-
} & RegisterShape) => Promise<{
|
|
106
|
-
digest: string;
|
|
107
|
-
blobObjectId: string;
|
|
108
|
-
endEpoch: number;
|
|
109
|
-
}>;
|
|
110
|
-
/** The seam the wallet rail certifies through. Returns the transaction digest. */
|
|
111
|
-
export type SignBlobCertify = (input: {
|
|
112
|
-
network: Network;
|
|
113
|
-
code: string;
|
|
114
|
-
relayUrl: string;
|
|
115
|
-
blobId: string;
|
|
116
|
-
blobObjectId: string;
|
|
117
|
-
certificate: Certificate;
|
|
118
|
-
}) => Promise<string>;
|
|
119
|
-
/** How a storage-resource operation is signed; the shape carries what the review priced. */
|
|
120
|
-
export type SignStorageOp = (input: {
|
|
121
|
-
network: Network;
|
|
122
|
-
code: string;
|
|
123
|
-
shape: StorageOpShape;
|
|
124
|
-
walrusPackageId: string;
|
|
125
|
-
}) => Promise<string>;
|
|
126
76
|
/**
|
|
127
77
|
* Cut, join or hand over a storage resource, in ONE transaction, signed by the account's own wallet.
|
|
128
78
|
*
|
package/dist/wallet-sign.js
CHANGED
|
@@ -45,7 +45,7 @@ import { BUILT_IN_WALLET_INDEX } from "./wallet.js";
|
|
|
45
45
|
* ⛔ NOT EXPORTED. A caller that could hold this could sign anything, and the whole of this tool's
|
|
46
46
|
* story about the wallet is that one command signs one shape of transaction.
|
|
47
47
|
*/
|
|
48
|
-
async function keypairFor(code) {
|
|
48
|
+
async function keypairFor(code, index) {
|
|
49
49
|
// The one refusal text for a malformed code lives in `account.ts`, so a typo fails here the same
|
|
50
50
|
// way it fails everywhere else in this tool rather than as an engine error.
|
|
51
51
|
await assertUsableCode(code);
|
|
@@ -61,7 +61,7 @@ async function keypairFor(code) {
|
|
|
61
61
|
derived = glue.kdf_derive(bytes);
|
|
62
62
|
const [from, to] = DERIVED.walletRoot;
|
|
63
63
|
root = derived.slice(from, to);
|
|
64
|
-
seed = glue.wallet_seed_for(root,
|
|
64
|
+
seed = glue.wallet_seed_for(root, index);
|
|
65
65
|
return Ed25519Keypair.fromSecretKey(seed);
|
|
66
66
|
}
|
|
67
67
|
catch (error) {
|
|
@@ -86,8 +86,8 @@ async function keypairFor(code) {
|
|
|
86
86
|
* part is silent — a signature from an address with nothing in it, or worse, money sent to an
|
|
87
87
|
* address that signs nothing. A test compares them, offline, for free.
|
|
88
88
|
*/
|
|
89
|
-
export async function signerAddress(code) {
|
|
90
|
-
return (await keypairFor(code)).toSuiAddress();
|
|
89
|
+
export async function signerAddress(code, index = BUILT_IN_WALLET_INDEX) {
|
|
90
|
+
return (await keypairFor(code, index)).toSuiAddress();
|
|
91
91
|
}
|
|
92
92
|
/**
|
|
93
93
|
* Extend every listed blob by `epochs`, in ONE transaction, signed by the account's own wallet.
|
|
@@ -104,7 +104,7 @@ export async function signerAddress(code) {
|
|
|
104
104
|
* was executed. The caller re-reads the chain rather than offering a second attempt against
|
|
105
105
|
* numbers it read before.
|
|
106
106
|
*/
|
|
107
|
-
export const signExtension = async ({ network, code, objectIds, epochs }) => {
|
|
107
|
+
export const signExtension = async ({ network, code, wallet, objectIds, epochs }) => {
|
|
108
108
|
const unique = [...new Set(objectIds)];
|
|
109
109
|
if (unique.length === 0) {
|
|
110
110
|
throw new NmtsError("There is nothing on this file that can be extended.", { exitCode: 4 });
|
|
@@ -113,7 +113,7 @@ export const signExtension = async ({ network, code, objectIds, epochs }) => {
|
|
|
113
113
|
throw new NmtsError("An extension must be a positive whole number of epochs.", { exitCode: 2 });
|
|
114
114
|
}
|
|
115
115
|
const client = walrusClient(network);
|
|
116
|
-
const keypair = await keypairFor(code);
|
|
116
|
+
const keypair = await keypairFor(code, wallet);
|
|
117
117
|
const tx = new Transaction();
|
|
118
118
|
// The sender must be set before the fragments resolve: paying with the SDK's default coin
|
|
119
119
|
// selection picks the WAL coins from the sender's own address.
|
|
@@ -158,9 +158,9 @@ export const signExtension = async ({ network, code, objectIds, epochs }) => {
|
|
|
158
158
|
*
|
|
159
159
|
* ⚠ A FAILURE HERE IS NOT PROOF THAT NOTHING HAPPENED — the same words as the extension above.
|
|
160
160
|
*/
|
|
161
|
-
export const signTransfer = async ({ network, code, shape }) => {
|
|
161
|
+
export const signTransfer = async ({ network, code, wallet, shape }) => {
|
|
162
162
|
const client = walrusClient(network);
|
|
163
|
-
const keypair = await keypairFor(code);
|
|
163
|
+
const keypair = await keypairFor(code, wallet);
|
|
164
164
|
const tx = transferTransaction({ ...shape, sender: keypair.toSuiAddress() });
|
|
165
165
|
const result = await client.signAndExecuteTransaction({
|
|
166
166
|
transaction: tx,
|
|
@@ -189,8 +189,10 @@ export const signTransfer = async ({ network, code, shape }) => {
|
|
|
189
189
|
* makes. `signPersonalMessage` and not `sign`: that intent is the domain separator which stops
|
|
190
190
|
* signed text from ever being read as a transaction this wallet authorised.
|
|
191
191
|
*/
|
|
192
|
-
export const signMessage = async ({ code, message }) => {
|
|
193
|
-
|
|
192
|
+
export const signMessage = async ({ code, wallet, message }) => {
|
|
193
|
+
// The wallet the caller resolved signs it: the hall entry is that wallet's address, and it is
|
|
194
|
+
// the wallet a gift left from, so any other one would name an address that gave nothing.
|
|
195
|
+
const keypair = await keypairFor(code, wallet);
|
|
194
196
|
const { signature } = await keypair.signPersonalMessage(new TextEncoder().encode(message));
|
|
195
197
|
return signature;
|
|
196
198
|
};
|
|
@@ -205,9 +207,9 @@ export const signMessage = async ({ code, message }) => {
|
|
|
205
207
|
*
|
|
206
208
|
* ⚠ A FAILURE HERE IS NOT PROOF THAT NOTHING HAPPENED — the same words as the extension above.
|
|
207
209
|
*/
|
|
208
|
-
export const signSwap = async ({ network, code, shape }) => {
|
|
210
|
+
export const signSwap = async ({ network, code, wallet, shape }) => {
|
|
209
211
|
const client = walrusClient(network);
|
|
210
|
-
const keypair = await keypairFor(code);
|
|
212
|
+
const keypair = await keypairFor(code, wallet);
|
|
211
213
|
const tx = swapTransaction({ ...shape, network, sender: keypair.toSuiAddress() });
|
|
212
214
|
const result = await client.signAndExecuteTransaction({
|
|
213
215
|
transaction: tx,
|
|
@@ -247,9 +249,9 @@ function refusedBecause(result) {
|
|
|
247
249
|
* ⚠ A FAILURE HERE IS NOT PROOF THAT NOTHING HAPPENED — the same words as the extension above.
|
|
248
250
|
* The caller keeps its record and re-reads it rather than registering again.
|
|
249
251
|
*/
|
|
250
|
-
export const signBlobRegister = async ({ network, code, relayUrl, ...shape }) => {
|
|
252
|
+
export const signBlobRegister = async ({ network, code, wallet, relayUrl, ...shape }) => {
|
|
251
253
|
const client = payingClient(network, relayUrl);
|
|
252
|
-
const keypair = await keypairFor(code);
|
|
254
|
+
const keypair = await keypairFor(code, wallet);
|
|
253
255
|
const tx = await registerTransaction(client, network, { ...shape, sender: keypair.toSuiAddress() });
|
|
254
256
|
const result = await client.signAndExecuteTransaction({
|
|
255
257
|
transaction: tx,
|
|
@@ -270,9 +272,9 @@ export const signBlobRegister = async ({ network, code, relayUrl, ...shape }) =>
|
|
|
270
272
|
return { digest: result.digest, ...blob };
|
|
271
273
|
};
|
|
272
274
|
/** Certify ONE registered part from the relay's certificate. Gas only; nothing else leaves the wallet. */
|
|
273
|
-
export const signBlobCertify = async ({ network, code, relayUrl, ...shape }) => {
|
|
275
|
+
export const signBlobCertify = async ({ network, code, wallet, relayUrl, ...shape }) => {
|
|
274
276
|
const client = payingClient(network, relayUrl);
|
|
275
|
-
const keypair = await keypairFor(code);
|
|
277
|
+
const keypair = await keypairFor(code, wallet);
|
|
276
278
|
const tx = certifyTransaction(client, shape);
|
|
277
279
|
tx.setSender(keypair.toSuiAddress());
|
|
278
280
|
const result = await client.signAndExecuteTransaction({
|
|
@@ -298,9 +300,11 @@ export const signBlobCertify = async ({ network, code, relayUrl, ...shape }) =>
|
|
|
298
300
|
* so what is signed is what was reviewed. A failed execution still has a digest and still
|
|
299
301
|
* spent its gas, so the status is read and a failure is said as one.
|
|
300
302
|
*/
|
|
301
|
-
export const signStorageOp = async ({ network, code, shape, walrusPackageId }) => {
|
|
303
|
+
export const signStorageOp = async ({ network, code, wallet, shape, walrusPackageId }) => {
|
|
302
304
|
const client = walrusClient(network);
|
|
303
|
-
|
|
305
|
+
// The resource the review named was read from this wallet's address, so this wallet is the one
|
|
306
|
+
// that can reshape or hand it over.
|
|
307
|
+
const keypair = await keypairFor(code, wallet);
|
|
304
308
|
const tx = storageOpTransaction(shape, { walrusPackageId, sender: keypair.toSuiAddress() });
|
|
305
309
|
const result = await client.signAndExecuteTransaction({ transaction: tx, signer: keypair, options: { showEffects: true } });
|
|
306
310
|
const effects = result.effects;
|
package/dist/wallet.d.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { type CryptoGlue } from "./crypto.ts";
|
|
2
2
|
import type { Network } from "./network.ts";
|
|
3
3
|
/**
|
|
4
|
-
* The wallet this NMTS key opens by itself.
|
|
4
|
+
* The wallet this NMTS key opens by itself, when nobody has said which one.
|
|
5
5
|
*
|
|
6
|
-
* ⛔ IT IS WALLET 0 BECAUSE THAT IS THE ONE
|
|
7
|
-
* comes out of `wallet_seed_for` — there is no special case for the first — so the index is
|
|
8
|
-
* whole of the difference between
|
|
6
|
+
* ⛔ IT IS WALLET 0 BECAUSE THAT IS THE ONE EVERY ACCOUNT STARTS WITH. Every wallet, including this
|
|
7
|
+
* one, comes out of `wallet_seed_for` — there is no special case for the first — so the index is
|
|
8
|
+
* the whole of the difference between one wallet of this key and another.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
10
|
+
* ⚠ IT IS THE OFFLINE ANSWER, NOT THE PAYING ONE (2026-09-16). `nmts wallet address` asks
|
|
11
|
+
* nothing of anybody and so cannot know which wallet the account pays from; every command that
|
|
12
|
+
* SPENDS reads that number out of the sealed file list first (`wallet-pay-index.ts`) and refuses
|
|
13
|
+
* rather than falling back here — paying from the wrong wallet is not a thing to guess at.
|
|
14
14
|
*/
|
|
15
15
|
export declare const BUILT_IN_WALLET_INDEX = 0;
|
|
16
16
|
/** The chain's own coin. Its type is fixed by the chain itself and takes no network. */
|
|
@@ -50,12 +50,12 @@ export declare function walCoinType(network: Network): string;
|
|
|
50
50
|
*/
|
|
51
51
|
export declare function addressFromSeed(seed: Uint8Array): string;
|
|
52
52
|
/**
|
|
53
|
-
* The address of the
|
|
53
|
+
* The address of one of the wallets this NMTS key derives. Offline: nothing is asked of anybody.
|
|
54
54
|
*
|
|
55
|
-
* The same address on every network —
|
|
56
|
-
* on is a separate question from what it is called.
|
|
55
|
+
* The same address on every network — a wallet is the same wallet on every chain, and which chain
|
|
56
|
+
* it is looked up on is a separate question from what it is called.
|
|
57
57
|
*/
|
|
58
|
-
export declare function walletAddress(code: string): Promise<string>;
|
|
58
|
+
export declare function walletAddress(code: string, index?: number): Promise<string>;
|
|
59
59
|
/**
|
|
60
60
|
* The engine functions this module uses. Narrowed to the one it actually calls.
|
|
61
61
|
*
|
|
@@ -73,7 +73,7 @@ export type WalletGlue = Pick<CryptoGlue, "wallet_seed_for">;
|
|
|
73
73
|
* engine expands from it — are wiped before it returns, on the failing path as well as the
|
|
74
74
|
* good one. Neither one leaves.
|
|
75
75
|
*/
|
|
76
|
-
export declare function addressFromDerived(glue: WalletGlue, derived: Uint8Array): string;
|
|
76
|
+
export declare function addressFromDerived(glue: WalletGlue, derived: Uint8Array, index?: number): string;
|
|
77
77
|
/**
|
|
78
78
|
* How much of one coin an address holds, exactly as the chain reported it — or why nobody knows.
|
|
79
79
|
*
|
package/dist/wallet.js
CHANGED
|
@@ -19,16 +19,16 @@ import { assertUsableCode } from "./account.js";
|
|
|
19
19
|
import { DERIVED, loadCrypto } from "./crypto.js";
|
|
20
20
|
import { NmtsError } from "./errors.js";
|
|
21
21
|
/**
|
|
22
|
-
* The wallet this NMTS key opens by itself.
|
|
22
|
+
* The wallet this NMTS key opens by itself, when nobody has said which one.
|
|
23
23
|
*
|
|
24
|
-
* ⛔ IT IS WALLET 0 BECAUSE THAT IS THE ONE
|
|
25
|
-
* comes out of `wallet_seed_for` — there is no special case for the first — so the index is
|
|
26
|
-
* whole of the difference between
|
|
24
|
+
* ⛔ IT IS WALLET 0 BECAUSE THAT IS THE ONE EVERY ACCOUNT STARTS WITH. Every wallet, including this
|
|
25
|
+
* one, comes out of `wallet_seed_for` — there is no special case for the first — so the index is
|
|
26
|
+
* the whole of the difference between one wallet of this key and another.
|
|
27
27
|
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
28
|
+
* ⚠ IT IS THE OFFLINE ANSWER, NOT THE PAYING ONE (2026-09-16). `nmts wallet address` asks
|
|
29
|
+
* nothing of anybody and so cannot know which wallet the account pays from; every command that
|
|
30
|
+
* SPENDS reads that number out of the sealed file list first (`wallet-pay-index.ts`) and refuses
|
|
31
|
+
* rather than falling back here — paying from the wrong wallet is not a thing to guess at.
|
|
32
32
|
*/
|
|
33
33
|
export const BUILT_IN_WALLET_INDEX = 0;
|
|
34
34
|
/**
|
|
@@ -83,12 +83,12 @@ export function addressFromSeed(seed) {
|
|
|
83
83
|
return Ed25519Keypair.fromSecretKey(seed).toSuiAddress();
|
|
84
84
|
}
|
|
85
85
|
/**
|
|
86
|
-
* The address of the
|
|
86
|
+
* The address of one of the wallets this NMTS key derives. Offline: nothing is asked of anybody.
|
|
87
87
|
*
|
|
88
|
-
* The same address on every network —
|
|
89
|
-
* on is a separate question from what it is called.
|
|
88
|
+
* The same address on every network — a wallet is the same wallet on every chain, and which chain
|
|
89
|
+
* it is looked up on is a separate question from what it is called.
|
|
90
90
|
*/
|
|
91
|
-
export async function walletAddress(code) {
|
|
91
|
+
export async function walletAddress(code, index = BUILT_IN_WALLET_INDEX) {
|
|
92
92
|
// ⛔ The one refusal text for a malformed code lives in `account.ts`. Checking here means a typo
|
|
93
93
|
// fails the same way it fails everywhere else in this tool rather than as an engine error.
|
|
94
94
|
await assertUsableCode(code);
|
|
@@ -108,7 +108,7 @@ export async function walletAddress(code) {
|
|
|
108
108
|
// everything sliced out of it, on the failing paths as well as the good one.
|
|
109
109
|
const derived = glue.kdf_derive(bytes);
|
|
110
110
|
try {
|
|
111
|
-
return addressFromDerived(glue, derived);
|
|
111
|
+
return addressFromDerived(glue, derived, index);
|
|
112
112
|
}
|
|
113
113
|
finally {
|
|
114
114
|
derived.fill(0);
|
|
@@ -123,12 +123,12 @@ export async function walletAddress(code) {
|
|
|
123
123
|
* engine expands from it — are wiped before it returns, on the failing path as well as the
|
|
124
124
|
* good one. Neither one leaves.
|
|
125
125
|
*/
|
|
126
|
-
export function addressFromDerived(glue, derived) {
|
|
126
|
+
export function addressFromDerived(glue, derived, index = BUILT_IN_WALLET_INDEX) {
|
|
127
127
|
const [from, to] = DERIVED.walletRoot;
|
|
128
128
|
const root = derived.slice(from, to);
|
|
129
129
|
let seed = null;
|
|
130
130
|
try {
|
|
131
|
-
seed = glue.wallet_seed_for(root,
|
|
131
|
+
seed = glue.wallet_seed_for(root, index);
|
|
132
132
|
return addressFromSeed(seed);
|
|
133
133
|
}
|
|
134
134
|
finally {
|
package/dist/walrus-write.js
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
// transaction paid — see the note on `sendTip` below, which is not what its name suggests.
|
|
11
11
|
import { SuiJsonRpcClient } from "@mysten/sui/jsonRpc";
|
|
12
12
|
import { walrus } from "@mysten/walrus";
|
|
13
|
+
import { toBase64Url } from "./bytes.js";
|
|
13
14
|
import { epochClock } from "./expiry.js";
|
|
14
15
|
// ⛔ The re-export below is what callers use; this local name is the same function,
|
|
15
16
|
// imported so the reader above can call it without importing from itself.
|
|
@@ -112,8 +113,8 @@ export function createBlobProtocol(network, bodyBytes, onSent) {
|
|
|
112
113
|
.catch((error) => fail("The upload relay refused the bytes", error));
|
|
113
114
|
return {
|
|
114
115
|
signers: certificate.signers,
|
|
115
|
-
serialized_message_b64:
|
|
116
|
-
signature_b64:
|
|
116
|
+
serialized_message_b64: toBase64Url(certificate.serializedMessage),
|
|
117
|
+
signature_b64: toBase64Url(certificate.signature),
|
|
117
118
|
};
|
|
118
119
|
},
|
|
119
120
|
};
|
package/dist/walrus.d.ts
CHANGED
|
@@ -28,22 +28,7 @@ export declare const RELAY_HOSTS: Readonly<Record<string, readonly string[]>>;
|
|
|
28
28
|
export declare const SUI_RPC_HOSTS: Readonly<Record<string, readonly string[]>>;
|
|
29
29
|
/** How long one host gets before the next is tried. A read that stalls is a read that failed. */
|
|
30
30
|
export declare const READ_TIMEOUT_MS = 60000;
|
|
31
|
-
|
|
32
|
-
* Point reads at somebody else's aggregator, or at a development stack.
|
|
33
|
-
*
|
|
34
|
-
* ⚠ It replaces the list rather than adding to it, and that is deliberate: a run should read from
|
|
35
|
-
* where it was told to read, not from there AND the public hosts. Comma-separated for more
|
|
36
|
-
* than one, tried in the order given.
|
|
37
|
-
*/
|
|
38
|
-
export declare const AGGREGATOR_ENV_VAR = "NMTS_AGGREGATOR";
|
|
39
|
-
/**
|
|
40
|
-
* Push writes through somebody else's relay, or through a development stack.
|
|
41
|
-
*
|
|
42
|
-
* ⚠ ONE host, not a list. Unlike reads there is nothing to fail over to — see `RELAY_HOSTS`.
|
|
43
|
-
*/
|
|
44
|
-
export declare const RELAY_ENV_VAR = "NMTS_RELAY";
|
|
45
|
-
/** Ask a different Sui JSON-RPC node the shard-count question. */
|
|
46
|
-
export declare const SUI_RPC_ENV_VAR = "NMTS_SUI_RPC";
|
|
31
|
+
export { AGGREGATOR_ENV_VAR, RELAY_ENV_VAR, SUI_RPC_ENV_VAR } from "./env-vars.ts";
|
|
47
32
|
/** The relay this run writes through: the environment's if it named one, else the network's. */
|
|
48
33
|
export declare function relayHost(network: string): string;
|
|
49
34
|
/**
|
package/dist/walrus.js
CHANGED
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
// them: here, the browser build, and the standalone recovery tool. One copy going stale shows
|
|
11
11
|
// up as "file not found", which reads as "the file is gone" — so the machine holds them level
|
|
12
12
|
// rather than a person remembering to.
|
|
13
|
+
import { AGGREGATOR_ENV_VAR, RELAY_ENV_VAR, SUI_RPC_ENV_VAR } from "./env-vars.js";
|
|
13
14
|
import { NmtsError } from "./errors.js";
|
|
15
|
+
import { host as runtime } from "./host.js";
|
|
14
16
|
/** Curated Walrus aggregator (read) endpoints per network, preference order. */
|
|
15
17
|
export const AGGREGATOR_HOSTS = {
|
|
16
18
|
testnet: ["https://aggregator.walrus-testnet.walrus.space"],
|
|
@@ -50,34 +52,21 @@ export const SUI_RPC_HOSTS = {
|
|
|
50
52
|
};
|
|
51
53
|
/** How long one host gets before the next is tried. A read that stalls is a read that failed. */
|
|
52
54
|
export const READ_TIMEOUT_MS = 60_000;
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
* ⚠ It replaces the list rather than adding to it, and that is deliberate: a run should read from
|
|
57
|
-
* where it was told to read, not from there AND the public hosts. Comma-separated for more
|
|
58
|
-
* than one, tried in the order given.
|
|
59
|
-
*/
|
|
60
|
-
export const AGGREGATOR_ENV_VAR = "NMTS_AGGREGATOR";
|
|
61
|
-
/**
|
|
62
|
-
* Push writes through somebody else's relay, or through a development stack.
|
|
63
|
-
*
|
|
64
|
-
* ⚠ ONE host, not a list. Unlike reads there is nothing to fail over to — see `RELAY_HOSTS`.
|
|
65
|
-
*/
|
|
66
|
-
export const RELAY_ENV_VAR = "NMTS_RELAY";
|
|
67
|
-
/** Ask a different Sui JSON-RPC node the shard-count question. */
|
|
68
|
-
export const SUI_RPC_ENV_VAR = "NMTS_SUI_RPC";
|
|
55
|
+
// Re-exported so every caller still finds them here; the names themselves live in a module with no
|
|
56
|
+
// imports, because `nmts --help` prints them (`env-vars.ts`).
|
|
57
|
+
export { AGGREGATOR_ENV_VAR, RELAY_ENV_VAR, SUI_RPC_ENV_VAR } from "./env-vars.js";
|
|
69
58
|
/** The relay this run writes through: the environment's if it named one, else the network's. */
|
|
70
59
|
export function relayHost(network) {
|
|
71
|
-
const named =
|
|
60
|
+
const named = runtime().env(RELAY_ENV_VAR)?.trim();
|
|
72
61
|
if (named)
|
|
73
62
|
return named;
|
|
74
|
-
const
|
|
75
|
-
if (
|
|
63
|
+
const known = RELAY_HOSTS[network]?.[0];
|
|
64
|
+
if (known === undefined) {
|
|
76
65
|
throw new NmtsError(`No upload relay is known for the ${network} storage network.`, {
|
|
77
66
|
nextStep: `Name one in ${RELAY_ENV_VAR} to upload anyway.`,
|
|
78
67
|
});
|
|
79
68
|
}
|
|
80
|
-
return
|
|
69
|
+
return known;
|
|
81
70
|
}
|
|
82
71
|
/**
|
|
83
72
|
* Every Sui JSON-RPC node this run may ask, in order.
|
|
@@ -88,7 +77,7 @@ export function relayHost(network) {
|
|
|
88
77
|
* they did not choose.
|
|
89
78
|
*/
|
|
90
79
|
export function suiRpcHosts(network) {
|
|
91
|
-
const named =
|
|
80
|
+
const named = runtime().env(SUI_RPC_ENV_VAR)?.trim();
|
|
92
81
|
if (named)
|
|
93
82
|
return [named];
|
|
94
83
|
const hosts = SUI_RPC_HOSTS[network];
|
|
@@ -104,7 +93,7 @@ export function suiRpcHost(network) {
|
|
|
104
93
|
return suiRpcHosts(network)[0] ?? "";
|
|
105
94
|
}
|
|
106
95
|
function fromEnvironment() {
|
|
107
|
-
const raw =
|
|
96
|
+
const raw = runtime().env(AGGREGATOR_ENV_VAR);
|
|
108
97
|
if (raw === undefined)
|
|
109
98
|
return null;
|
|
110
99
|
const hosts = raw.split(",").map((h) => h.trim()).filter((h) => h !== "");
|
package/docs/commands/credits.md
CHANGED
|
@@ -27,7 +27,7 @@ is spent by moving credits, and running the same command the other way puts them
|
|
|
27
27
|
The credits keep the expiry they already had. The move drains the soonest-expiring lots first, so
|
|
28
28
|
sending 100 may arrive as several grants with different dates, and moving them never renews them.
|
|
29
29
|
|
|
30
|
-
Four refusals,
|
|
30
|
+
Four refusals, none of them worth retrying:
|
|
31
31
|
`CREDIT_TRANSFER_OUTSIDE_FAMILY` (name an account of your own) · `CREDIT_TRANSFER_SELF` (that is
|
|
32
32
|
the account sending) · `CREDIT_TRANSFER_INSUFFICIENT` (send less — the refusal carries what was
|
|
33
33
|
needed and what the account can spend) · `CREDIT_TRANSFER_ZERO` (send some). Nothing is moved and
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# nmts platform — the key pair a business signs with
|
|
2
|
+
|
|
3
|
+
Commands: platform
|
|
4
|
+
Tiers: platform=none · platform.keygen=medium
|
|
5
|
+
|
|
6
|
+
`platform keygen` makes an Ed25519 key pair and writes both halves to `nmts-business-key.json`, or
|
|
7
|
+
to `--out <file>`, with mode 0600 (Windows applies no file mode, and the command says so). It
|
|
8
|
+
refuses a name that already exists, whatever `--force` says, and prints only the public half.
|
|
9
|
+
`platform register` cannot register it: that needs a signed-in browser session at nmts.me, under
|
|
10
|
+
Settings › Developer › Platform, and the command prints that path and exits 2.
|
|
11
|
+
|
|
12
|
+
The private half is what signs every request a business makes and every delegation token it mints
|
|
13
|
+
for one of its users. Nothing can derive it again, and replacing the registered key invalidates every
|
|
14
|
+
token the old one signed.
|
package/docs/commands/support.md
CHANGED
|
@@ -13,4 +13,4 @@ English. One report per problem.
|
|
|
13
13
|
|
|
14
14
|
In the default mode it prints what it would send and asks (or takes `--yes`); in an auto mode it
|
|
15
15
|
sends after printing. Replies arrive in the thread: `support list`, `support show <code>`,
|
|
16
|
-
`support reply <code> --message`. If the CLI itself cannot run,
|
|
16
|
+
`support reply <code> --message`. If the CLI itself cannot run, write to nmts@nmts.me.
|
package/docs/commands/trash.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# nmts rm, restore, sweep, erase — the trash, and
|
|
1
|
+
# nmts rm, restore, sweep, erase — the trash, and erasing for good
|
|
2
2
|
|
|
3
3
|
Commands: rm, restore, sweep, erase
|
|
4
4
|
Tiers: rm=low · restore=low · sweep=medium · erase=ultra-high · erase.release=ultra-high(release-storage)
|
package/docs/commands/wallet.md
CHANGED
|
@@ -1,12 +1,28 @@
|
|
|
1
1
|
# nmts wallet — the wallet your NMTS key derives
|
|
2
2
|
|
|
3
3
|
Commands: wallet
|
|
4
|
-
Tiers: wallet=none · wallet.send=high(wallet) · wallet.swap=high(wallet) · wallet.donate=high(donate) · wallet.storage.reshape=high(wallet) · wallet.storage.give=high(wallet) · wallet.hall=none · wallet.hall.set=medium
|
|
4
|
+
Tiers: wallet=none · wallet.use=low · wallet.send=high(wallet) · wallet.swap=high(wallet) · wallet.donate=high(donate) · wallet.storage.reshape=high(wallet) · wallet.storage.give=high(wallet) · wallet.hall=none · wallet.hall.set=medium
|
|
5
5
|
|
|
6
6
|
`wallet` shows the address and its SUI and WAL balances; `wallet address` derives the address
|
|
7
|
-
offline (`--qr` draws it
|
|
8
|
-
proves it; `wallet storage` lists storage
|
|
9
|
-
these signs.
|
|
7
|
+
offline (`--qr` draws it, `--index N` derives another of this key's wallets); `wallet activity`
|
|
8
|
+
lists recent transactions, named only where the chain proves it; `wallet storage` lists storage
|
|
9
|
+
resources (size × time) held outside any file. None of these signs.
|
|
10
|
+
|
|
11
|
+
## One key, many wallets
|
|
12
|
+
|
|
13
|
+
Your NMTS key derives a wallet at every number from 0 upwards, and one of them pays. `wallet list`
|
|
14
|
+
walks them — it shows each number, its address and its balances, marks the one that pays, and stops
|
|
15
|
+
after twenty unused wallets in a row. `wallet use <number>` moves which one pays: the number is
|
|
16
|
+
kept inside your sealed file list, so the browser, this tool and every other device agree on it.
|
|
17
|
+
Numbers come from the key, so a wallet cannot be deleted, and a wallet you leave keeps whatever is
|
|
18
|
+
in it.
|
|
19
|
+
|
|
20
|
+
`put`, `push`, `extend`, `wallet send` and `wallet donate` all pay from that wallet. The same
|
|
21
|
+
number decides the rest: `wallet swap` swaps its coins, `wallet storage split|merge|transfer`
|
|
22
|
+
reshapes the resources it holds, and `wallet hall --name` signs as its address. Each takes
|
|
23
|
+
`--wallet <number>` to use a different one for that run only, without changing the setting.
|
|
24
|
+
⛔ If the file list cannot be read, they refuse rather than falling back to wallet 0 — signing with
|
|
25
|
+
a wallet nobody chose is not a thing to guess at.
|
|
10
26
|
|
|
11
27
|
## Where SUI comes from, and why it is SUI
|
|
12
28
|
|
|
@@ -14,8 +30,8 @@ You can store without any coin here: credits pay the network for you (the weekly
|
|
|
14
30
|
nmts.me, or credits somebody gave you), and `nmts balance` shows them. The wallet matters only when
|
|
15
31
|
you pay the network yourself.
|
|
16
32
|
|
|
17
|
-
The files live on Walrus, and Walrus is paid on the Sui chain in WAL, with gas in SUI
|
|
18
|
-
this wallet holds SUI and WAL and nothing else
|
|
33
|
+
The files live on Walrus, and Walrus is paid on the Sui chain in WAL, with gas in SUI, so
|
|
34
|
+
this wallet holds SUI and WAL and nothing else.
|
|
19
35
|
Fiat is not taken because taking it would make NMTS hold your money, which it never does.
|
|
20
36
|
|
|
21
37
|
Getting SUI (as of 2026-09-06): buy it on an exchange that lists it (Binance and Upbit did on that
|
|
@@ -63,5 +79,7 @@ One more reads the gifts back, and one flag on it publishes a name:
|
|
|
63
79
|
- `wallet hall` prints the gift hall of fame — the developer, then the ten largest senders as read
|
|
64
80
|
from the public chain, with the rest of the list at nmts.me/hall; reading it signs nothing and
|
|
65
81
|
needs no NMTS key. `--name <name>` (1 to 24 characters, no links, not an address) signs a
|
|
66
|
-
short message with this account
|
|
67
|
-
`--remove` puts the entry back to a shortened
|
|
82
|
+
short message with the wallet this account pays from — the wallet a gift left from — so the
|
|
83
|
+
server shows that name beside its address, and `--remove` puts the entry back to a shortened
|
|
84
|
+
address. Reading which wallet that is opens the file list, so naming yourself needs an API key
|
|
85
|
+
where reading the hall needs none.
|