Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions docs/output-schemas-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -368,12 +368,22 @@ interface CommandOutputSpec {
"supplyType": "FINITE",
"transactionId": "0.0.123@1700000000.123456789",
"adminAccountId": "0.0.12345",
"adminPublicKey": "302a300506032b6570032100...",
"supplyAccountId": "0.0.12345",
"supplyPublicKey": "302a300506032b6570032100...",
"freezePublicKey": "302a300506032b6570032100...",
"wipePublicKey": "302a300506032b6570032100...",
"pausePublicKey": "302a300506032b6570032100...",
"kycPublicKey": "302a300506032b6570032100...",
"feeSchedulePublicKey": "302a300506032b6570032100...",
"metadataPublicKey": "302a300506032b6570032100...",
"alias": "my-nft",
"network": "testnet"
}
```

All key fields (`adminPublicKey`, `supplyPublicKey`, `freezePublicKey`, `wipePublicKey`, `pausePublicKey`, `kycPublicKey`, `feeSchedulePublicKey`, `metadataPublicKey`) are optional and only appear when the corresponding key was provided.

#### `token mint-ft`

**Output**:
Expand Down
7 changes: 6 additions & 1 deletion src/core/services/token/token-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,10 @@ export class TokenServiceImpl implements TokenService {
wipePublicKey,
kycPublicKey,
freezePublicKey,
freezeDefault,
pausePublicKey,
feeSchedulePublicKey,
metadataPublicKey,
freezeDefault,
customFees,
memo,
autoRenewPeriodSeconds,
Expand Down Expand Up @@ -189,6 +189,11 @@ export class TokenServiceImpl implements TokenService {
this.logger.debug(`[TOKEN SERVICE] Set metadata key`);
}

if (freezeDefault !== undefined) {
tokenCreateTx.setFreezeDefault(freezeDefault);
this.logger.debug(`[TOKEN SERVICE] Set freeze default: ${freezeDefault}`);
}

if (autoRenewPeriodSeconds && autoRenewAccountId) {
tokenCreateTx
.setAutoRenewAccountId(AccountId.fromString(autoRenewAccountId))
Expand Down
5 changes: 3 additions & 2 deletions src/core/types/token.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,12 @@ export interface TokenCreateParams {
pausePublicKey?: PublicKey;
feeSchedulePublicKey?: PublicKey;
metadataPublicKey?: PublicKey;
autoRenewPeriod?: number;
autoRenewAccountId?: string;
expirationTime?: Date;
customFees?: CustomFee[];
memo?: string;
autoRenewPeriodSeconds?: number;
autoRenewAccountId?: string;
expirationTime?: Date;
}

/**
Expand Down
166 changes: 164 additions & 2 deletions src/plugins/token/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,103 @@ hcli token create-ft \

**Batch support:** Pass `--batch <batch-name>` to add token creation to a batch instead of executing immediately. See the [Batch Support](#-batch-support) section.

### Token Create NFT

Create a new non-fungible token (NFT) collection with specified properties.

```bash
# Using account alias
hcli token create-nft \
--token-name "My NFT Collection" \
--symbol "MNFT" \
--treasury alice \
--supply-type FINITE \
--max-supply 1000 \
--admin-key alice \
--supply-key alice \
--freeze-key alice \
--wipe-key alice \
--name my-nft-collection

# With additional optional keys and settings
hcli token create-nft \
--token-name "My Collection" \
--symbol "MC" \
--treasury 0.0.123456:302e020100300506032b657004220420... \
--supply-type INFINITE \
--admin-key alice \
--supply-key alice \
--kyc-key alice \
--pause-key alice \
--fee-schedule-key alice \
--metadata-key alice \
--auto-renew-period 7776000 \
--auto-renew-account-id 0.0.123456 \
--freeze-default false \
--name my-collection
```

**Parameters:**

- `--token-name` / `-T`: Token name - **Required**
- `--symbol` / `-s`: Token symbol/ticker - **Required**
- `--treasury`: Treasury account for the NFT collection - **Optional** (defaults to operator)
- Account alias: `alice`
- Account with key: `0.0.123456:private-key`
- `--supply-type`: Supply type - **Optional** (defaults to `INFINITE`)
- `INFINITE` - Unlimited supply
- `FINITE` - Fixed maximum supply (requires `--max-supply`)
- `--max-supply`: Maximum number of NFTs in collection (required for FINITE) - **Optional**
- `--admin-key`: Admin key for administrative operations - **Optional**
- `--supply-key`: Supply key for minting NFTs - **Optional**
- `--freeze-key`: Freeze key to freeze token transfers for accounts - **Optional**
- `--wipe-key`: Wipe key to wipe token balances - **Optional**
- `--kyc-key`: KYC key to grant/revoke KYC status - **Optional**
- `--pause-key`: Pause key to pause all token transfers - **Optional**
- `--fee-schedule-key`: Fee schedule key to modify custom fees - **Optional**
- `--metadata-key`: Metadata key to update token metadata - **Optional**
- `--freeze-default`: Default freeze status for new associations (requires `--freeze-key`) - **Optional** (defaults to false)
- `--auto-renew-period`: Token auto-renewal period in seconds (e.g., 7776000 for 90 days) - **Optional**
- `--auto-renew-account-id`: Account ID that pays for token auto-renewal fees - **Optional**
- `--expiration-time`: Token expiration time in ISO 8601 format (e.g., 2027-01-01T00:00:00Z) - **Optional**
- `--name`: Token alias to register - **Optional**
- `--key-manager`: Key manager type - **Optional** (defaults to config setting)
- `local` or `local_encrypted`
- `--memo`: Optional memo for the token (max 100 characters) - **Optional**
- `--batch`: Add to batch instead of executing immediately - **Optional**

**Output:**

```json
{
"tokenId": "0.0.123456",
"name": "My NFT Collection",
"symbol": "MNFT",
"treasuryId": "0.0.111",
"supplyType": "FINITE",
"transactionId": "0.0.123@1700000000.123456789",
"adminPublicKey": "302e020100300506032b657004220420...",
"supplyPublicKey": "302e020100300506032b657004220420...",
"freezePublicKey": "302e020100300506032b657004220420...",
"wipePublicKey": "302e020100300506032b657004220420...",
"kycPublicKey": "302e020100300506032b657004220420...",
"pausePublicKey": "302e020100300506032b657004220420...",
"feeSchedulePublicKey": "302e020100300506032b657004220420...",
"metadataPublicKey": "302e020100300506032b657004220420...",
"network": "testnet"
}
```

**Notes:**

- NFTs are non-fungible, meaning each NFT is unique and tracked by serial number
- No decimals field applies to NFTs
- Use `mint-nft` command to mint individual NFTs to the collection
- Token name is automatically registered as an alias after successful creation
- Freeze default requires freeze key to be set

**Batch support:** Pass `--batch <batch-name>` to add NFT collection creation to a batch instead of executing immediately. See the [Batch Support](#-batch-support) section.

### Token Mint FT

Mint additional fungible tokens to increase supply. Tokens are minted to the token's treasury account.
Expand Down Expand Up @@ -600,6 +697,11 @@ The token file supports aliases and raw keys with optional key type prefixes:
"freezeKey": "<alias or accountId:privateKey>",
"pauseKey": "<alias or accountId:privateKey>",
"feeScheduleKey": "<alias or accountId:privateKey>",
"metadataKey": "<alias or accountId:privateKey>",
"freezeDefault": false,
"autoRenewPeriod": 7776000,
"autoRenewAccountId": "<accountId>",
"expirationTime": "2027-01-01T00:00:00Z",
"memo": "Optional token memo",
"autoRenewPeriod": "86400",
"autoRenewAccount": "<alias or accountId:privateKey>",
Expand Down Expand Up @@ -667,6 +769,11 @@ The NFT file supports aliases and raw keys with optional key type prefixes:
"freezeKey": "<alias or accountId:privateKey>",
"pauseKey": "<alias or accountId:privateKey>",
"feeScheduleKey": "<alias or accountId:privateKey>",
"metadataKey": "<alias or accountId:privateKey>",
"freezeDefault": false,
"autoRenewPeriod": 7776000,
"autoRenewAccountId": "<accountId>",
"expirationTime": "2027-01-01T00:00:00Z",
"memo": "Optional NFT collection memo",
"associations": ["<alias or accountId:privateKey>", "..."]
}
Expand Down Expand Up @@ -794,14 +901,36 @@ interface TokenData {
supplyType: SupplyType;
maxSupply: number;
memo?: string;
adminPublicKey?: string;
supplyPublicKey?: string;
wipePublicKey?: string;
kycPublicKey?: string;
freezePublicKey?: string;
pausePublicKey?: string;
feeSchedulePublicKey?: string;
metadataPublicKey?: string;
keys: TokenKeys;
network: 'mainnet' | 'testnet' | 'previewnet' | 'localnet';
associations: TokenAssociation[];
customFees: CustomFee[];
}
```

The `tokenType` field discriminates fungible tokens (`FUNGIBLE_COMMON`) from NFT collections (`NON_FUNGIBLE_UNIQUE`). NFT tokens use zero for `decimals` and `initialSupply`; minted NFTs are tracked by serial number on the ledger. The schema is validated using Zod (`TokenDataSchema`) and stored as JSON Schema in the plugin manifest for runtime validation.
**Field Descriptions:**

- `tokenType`: Discriminates fungible tokens (`FUNGIBLE_COMMON`) from NFT collections (`NON_FUNGIBLE_UNIQUE`)
- `decimals`: Number of decimal places for fungible tokens; zero for NFTs
- `initialSupply`: Initial supply amount; zero for NFTs
- `adminPublicKey`: Public key with admin privileges for token operations
- `supplyPublicKey`: Public key authorized to mint/burn tokens
- `wipePublicKey`: Public key authorized to wipe token balances
- `kycPublicKey`: Public key authorized to grant/revoke KYC status
- `freezePublicKey`: Public key authorized to freeze token transfers
- `pausePublicKey`: Public key authorized to pause all token transfers
- `feeSchedulePublicKey`: Public key authorized to update custom fees
- `metadataPublicKey`: Public key authorized to update token metadata

NFT tokens use zero for `decimals` and `initialSupply`; minted NFTs are tracked by serial number on the ledger. The schema is validated using Zod (`TokenDataSchema`) and stored as JSON Schema in the plugin manifest for runtime validation.

## 🧪 Testing

Expand Down Expand Up @@ -840,7 +969,7 @@ All commands support multiple output formats:

### Human-Readable (Default)

**Token Create:**
**Fungible Token Create:**

```
✅ Token created successfully: 0.0.12345
Expand All @@ -853,6 +982,17 @@ All commands support multiple output formats:
Transaction ID: 0.0.123@1700000000.123456789
```

**Non-Fungible Token Create:**

```
✅ NFT created successfully: 0.0.123456
Name: My NFT Collection (MNFT)
Treasury: 0.0.111
Supply Type: FINITE
Network: testnet
Transaction ID: 0.0.123@1700000000.123456789
```

**FT Mint:**

```
Expand Down Expand Up @@ -889,6 +1029,28 @@ All commands support multiple output formats:
}
```

**Non-Fungible Token Create:**

```json
{
"tokenId": "0.0.123456",
"name": "My NFT Collection",
"symbol": "MNFT",
"treasuryId": "0.0.111",
"supplyType": "FINITE",
"transactionId": "0.0.123@1700000000.123456789",
"adminPublicKey": "302e020100300506032b657004220420...",
"supplyPublicKey": "302e020100300506032b657004220420...",
"freezePublicKey": "302e020100300506032b657004220420...",
"wipePublicKey": "302e020100300506032b657004220420...",
"kycPublicKey": "302e020100300506032b657004220420...",
"pausePublicKey": "302e020100300506032b657004220420...",
"feeSchedulePublicKey": "302e020100300506032b657004220420...",
"metadataPublicKey": "302e020100300506032b657004220420...",
"network": "testnet"
}
```

**FT Mint:**

```json
Expand Down
Loading
Loading