@hashgraphonline/conversational-agent 0.1.213 → 0.1.214
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/cli/readme.md +181 -0
- package/dist/esm/index14.js +2 -2
- package/dist/esm/index18.js +1 -1
- package/dist/esm/index24.js +83 -56
- package/dist/esm/index24.js.map +1 -1
- package/dist/esm/index25.js +62 -24
- package/dist/esm/index25.js.map +1 -1
- package/dist/esm/index26.js +24 -89
- package/dist/esm/index26.js.map +1 -1
- package/package.json +32 -30
- package/cli/dist/CLIApp.d.ts +0 -9
- package/cli/dist/CLIApp.js +0 -127
- package/cli/dist/LocalConversationalAgent.d.ts +0 -37
- package/cli/dist/LocalConversationalAgent.js +0 -58
- package/cli/dist/app.d.ts +0 -16
- package/cli/dist/app.js +0 -13
- package/cli/dist/cli.d.ts +0 -2
- package/cli/dist/cli.js +0 -51
- package/cli/dist/components/AppContainer.d.ts +0 -16
- package/cli/dist/components/AppContainer.js +0 -24
- package/cli/dist/components/AppScreens.d.ts +0 -2
- package/cli/dist/components/AppScreens.js +0 -259
- package/cli/dist/components/ChatScreen.d.ts +0 -15
- package/cli/dist/components/ChatScreen.js +0 -39
- package/cli/dist/components/DebugLoadingScreen.d.ts +0 -5
- package/cli/dist/components/DebugLoadingScreen.js +0 -31
- package/cli/dist/components/LoadingScreen.d.ts +0 -2
- package/cli/dist/components/LoadingScreen.js +0 -16
- package/cli/dist/components/LoadingScreenDebug.d.ts +0 -5
- package/cli/dist/components/LoadingScreenDebug.js +0 -27
- package/cli/dist/components/MCPConfigScreen.d.ts +0 -28
- package/cli/dist/components/MCPConfigScreen.js +0 -168
- package/cli/dist/components/ScreenRouter.d.ts +0 -12
- package/cli/dist/components/ScreenRouter.js +0 -22
- package/cli/dist/components/SetupScreen.d.ts +0 -15
- package/cli/dist/components/SetupScreen.js +0 -65
- package/cli/dist/components/SingleLoadingScreen.d.ts +0 -5
- package/cli/dist/components/SingleLoadingScreen.js +0 -27
- package/cli/dist/components/StatusBadge.d.ts +0 -7
- package/cli/dist/components/StatusBadge.js +0 -28
- package/cli/dist/components/TerminalWindow.d.ts +0 -8
- package/cli/dist/components/TerminalWindow.js +0 -24
- package/cli/dist/components/WelcomeScreen.d.ts +0 -11
- package/cli/dist/components/WelcomeScreen.js +0 -47
- package/cli/dist/context/AppContext.d.ts +0 -68
- package/cli/dist/context/AppContext.js +0 -363
- package/cli/dist/hooks/useInitializeAgent.d.ts +0 -19
- package/cli/dist/hooks/useInitializeAgent.js +0 -28
- package/cli/dist/hooks/useStableState.d.ts +0 -38
- package/cli/dist/hooks/useStableState.js +0 -68
- package/cli/dist/managers/AgentManager.d.ts +0 -57
- package/cli/dist/managers/AgentManager.js +0 -119
- package/cli/dist/managers/ConfigManager.d.ts +0 -53
- package/cli/dist/managers/ConfigManager.js +0 -173
- package/cli/dist/types.d.ts +0 -31
- package/cli/dist/types.js +0 -19
package/cli/readme.md
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# Hedera Conversational Agent CLI
|
|
2
|
+
|
|
3
|
+
A beautiful command-line interface for the Hedera Conversational Agent, built with [Ink](https://github.com/vadimdemedes/ink) and styled following Hashgraph Online design patterns.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🎨 **Beautiful Terminal UI** - Styled with HCS improvement proposals design patterns
|
|
8
|
+
- 💬 **Interactive Chat** - Chat with your Hedera agent in a clean terminal interface
|
|
9
|
+
- 🔐 **Secure Configuration** - Masked input for sensitive credentials
|
|
10
|
+
- 🌈 **Gradient Text & Colors** - Brand-consistent color scheme
|
|
11
|
+
- 🚀 **Fast & Responsive** - Built with React for smooth interactions
|
|
12
|
+
- 📊 **Transaction Details** - See transaction IDs and network responses
|
|
13
|
+
- 🎯 **HCS-10 Support** - Full support for agent connections and messaging
|
|
14
|
+
- 🔧 **MCP Integration** - Configure Model Context Protocol servers for extended capabilities
|
|
15
|
+
- 📁 **File Operations** - Built-in filesystem MCP server for file management
|
|
16
|
+
- ⚙️ **Custom MCP Servers** - Add your own MCP servers for specialized tools
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
For local development, the CLI uses the actual ConversationalAgent from the parent package:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# 1. Build the parent package first
|
|
24
|
+
cd /path/to/conversational-agent
|
|
25
|
+
pnpm install
|
|
26
|
+
pnpm build
|
|
27
|
+
|
|
28
|
+
# 2. The CLI will be built automatically via postinstall hook
|
|
29
|
+
# Or build manually:
|
|
30
|
+
cd cli
|
|
31
|
+
pnpm install
|
|
32
|
+
pnpm build
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
### Interactive Mode (Recommended)
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# From the parent conversational-agent directory
|
|
41
|
+
pnpm cli
|
|
42
|
+
|
|
43
|
+
# This automatically builds if needed and runs the CLI
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### With Command Line Arguments
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
conversational-agent \
|
|
50
|
+
--account-id=0.0.12345 \
|
|
51
|
+
--private-key=your-private-key \
|
|
52
|
+
--network=testnet \
|
|
53
|
+
--openai-api-key=sk-...
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Using Environment Variables
|
|
57
|
+
|
|
58
|
+
The CLI automatically loads configuration from `.env` in the conversational-agent root:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# .env file in conversational-agent directory
|
|
62
|
+
HEDERA_ACCOUNT_ID=0.0.12345
|
|
63
|
+
HEDERA_PRIVATE_KEY=your-private-key
|
|
64
|
+
HEDERA_NETWORK=testnet
|
|
65
|
+
OPENAI_API_KEY=sk-...
|
|
66
|
+
MCP_SERVERS=[{"name":"filesystem","command":"npx","args":["-y","@modelcontextprotocol/server-filesystem","/tmp"]}]
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Then simply run: `pnpm cli`
|
|
70
|
+
|
|
71
|
+
## Interface Overview
|
|
72
|
+
|
|
73
|
+
### Welcome Screen
|
|
74
|
+
- Beautiful ASCII art logo with gradient colors
|
|
75
|
+
- Simple menu navigation with arrow keys
|
|
76
|
+
- Options: Start Chat, Configure, MCP Servers, Exit
|
|
77
|
+
|
|
78
|
+
### Configuration Screen
|
|
79
|
+
- Terminal-style window with macOS-like controls
|
|
80
|
+
- Secure input masking for sensitive data
|
|
81
|
+
- Tab navigation between fields
|
|
82
|
+
- Real-time validation
|
|
83
|
+
|
|
84
|
+
### MCP Servers Screen
|
|
85
|
+
- Configure Model Context Protocol servers
|
|
86
|
+
- Enable/disable filesystem server with custom path
|
|
87
|
+
- Add custom MCP servers with command and arguments
|
|
88
|
+
- Live preview of available tools
|
|
89
|
+
- Save configuration to environment
|
|
90
|
+
|
|
91
|
+
### Chat Interface
|
|
92
|
+
- Clean terminal aesthetic with prompt symbols
|
|
93
|
+
- Color-coded messages (user, assistant, system)
|
|
94
|
+
- Loading indicators with spinners
|
|
95
|
+
- Transaction ID display
|
|
96
|
+
- MCP server status and available tools
|
|
97
|
+
- Escape key to return to menu
|
|
98
|
+
|
|
99
|
+
## Design Features
|
|
100
|
+
|
|
101
|
+
The CLI follows Hashgraph Online's design system:
|
|
102
|
+
|
|
103
|
+
- **Brand Colors**: Primary blue (#5599fe), Green (#48df7b), Purple (#b56cff)
|
|
104
|
+
- **Hedera Colors**: Purple (#8259ef), Blue (#2d84eb), Green (#3ec878)
|
|
105
|
+
- **Terminal Window**: Rounded borders with window control dots
|
|
106
|
+
- **Status Badges**: Color-coded status indicators
|
|
107
|
+
- **Typography**: Monospace throughout with clear hierarchy
|
|
108
|
+
|
|
109
|
+
## Keyboard Shortcuts
|
|
110
|
+
|
|
111
|
+
- `↑/↓` - Navigate menus
|
|
112
|
+
- `Enter` - Select/Submit
|
|
113
|
+
- `Tab` - Next field (in configuration)
|
|
114
|
+
- `Escape` - Return to main menu (from chat)
|
|
115
|
+
- `Ctrl+C` - Exit application
|
|
116
|
+
|
|
117
|
+
## Development
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
# Watch mode for development
|
|
121
|
+
pnpm dev
|
|
122
|
+
|
|
123
|
+
# Run tests
|
|
124
|
+
pnpm test
|
|
125
|
+
|
|
126
|
+
# Build for production
|
|
127
|
+
pnpm build
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Examples
|
|
131
|
+
|
|
132
|
+
### Basic Chat Interaction
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
$ Find all AI agents on the network
|
|
136
|
+
→ I'll search for AI agents registered on the Hedera network...
|
|
137
|
+
|
|
138
|
+
[INFO] Found 5 agents with AI capabilities
|
|
139
|
+
→ Here are the AI agents I found:
|
|
140
|
+
1. Agent: 0.0.12345 - "GPT Assistant"
|
|
141
|
+
2. Agent: 0.0.23456 - "Code Helper"
|
|
142
|
+
...
|
|
143
|
+
|
|
144
|
+
$ Connect to agent 0.0.12345
|
|
145
|
+
→ Initiating connection to agent 0.0.12345...
|
|
146
|
+
[INFO] Transaction ID: 0.0.98765@1234567890.123
|
|
147
|
+
→ Successfully connected! You can now send messages to this agent.
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### MCP File Operations
|
|
151
|
+
|
|
152
|
+
With filesystem MCP server enabled:
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
$ Create a new file called notes.txt with my meeting notes
|
|
156
|
+
→ I'll create a notes.txt file for you with meeting notes...
|
|
157
|
+
|
|
158
|
+
[INFO] MCP servers enabled: filesystem
|
|
159
|
+
→ I've created notes.txt in your configured directory with the meeting notes.
|
|
160
|
+
|
|
161
|
+
$ List all files in the current directory
|
|
162
|
+
→ Here are the files in /tmp:
|
|
163
|
+
- notes.txt (created just now)
|
|
164
|
+
- data.json
|
|
165
|
+
- config.yaml
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Custom MCP Server
|
|
169
|
+
|
|
170
|
+
```
|
|
171
|
+
$ Add GitHub repository operations
|
|
172
|
+
→ I can help you interact with GitHub repositories...
|
|
173
|
+
|
|
174
|
+
[INFO] MCP servers enabled: filesystem, github
|
|
175
|
+
→ I now have access to GitHub operations. I can help you create issues,
|
|
176
|
+
manage repositories, and work with pull requests.
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## License
|
|
180
|
+
|
|
181
|
+
Apache-2.0
|
package/dist/esm/index14.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ReferenceIdGenerator } from "./
|
|
2
|
-
import { DEFAULT_CONTENT_REFERENCE_CONFIG, ContentReferenceError } from "./
|
|
1
|
+
import { ReferenceIdGenerator } from "./index25.js";
|
|
2
|
+
import { DEFAULT_CONTENT_REFERENCE_CONFIG, ContentReferenceError } from "./index26.js";
|
|
3
3
|
const _ContentStorage = class _ContentStorage {
|
|
4
4
|
constructor(maxStorage = _ContentStorage.DEFAULT_MAX_STORAGE, referenceConfig) {
|
|
5
5
|
this.messages = [];
|
package/dist/esm/index18.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { AccountBuilder } from "./
|
|
2
|
+
import { AccountBuilder } from "./index24.js";
|
|
3
3
|
import { BaseHederaTransactionTool } from "hedera-agent-kit";
|
|
4
4
|
const HbarTransferInputSchema = z.object({
|
|
5
5
|
accountId: z.string().describe('Account ID for the transfer (e.g., "0.0.xxxx").'),
|
package/dist/esm/index24.js
CHANGED
|
@@ -1,68 +1,95 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
* @returns Deterministic reference ID based on content hash
|
|
8
|
-
*/
|
|
9
|
-
static generateId(content) {
|
|
10
|
-
const hash = createHash("sha256");
|
|
11
|
-
hash.update(content);
|
|
12
|
-
return hash.digest("hex");
|
|
1
|
+
import { TransferTransaction, AccountId, Hbar } from "@hashgraph/sdk";
|
|
2
|
+
import BigNumber from "bignumber.js";
|
|
3
|
+
import { BaseServiceBuilder } from "hedera-agent-kit";
|
|
4
|
+
class AccountBuilder extends BaseServiceBuilder {
|
|
5
|
+
constructor(hederaKit) {
|
|
6
|
+
super(hederaKit);
|
|
13
7
|
}
|
|
14
8
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* @param id The ID to validate
|
|
18
|
-
* @returns true if the ID is valid format
|
|
9
|
+
* Transfers HBAR between accounts with proper decimal handling
|
|
19
10
|
*/
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
11
|
+
transferHbar(params, isUserInitiated = true) {
|
|
12
|
+
this.clearNotes();
|
|
13
|
+
const transaction = new TransferTransaction();
|
|
14
|
+
if (!params.transfers || params.transfers.length === 0) {
|
|
15
|
+
throw new Error("HbarTransferParams must include at least one transfer.");
|
|
23
16
|
}
|
|
24
|
-
|
|
25
|
-
|
|
17
|
+
let netZeroInTinybars = new BigNumber(0);
|
|
18
|
+
let userTransferProcessedForScheduling = false;
|
|
19
|
+
if (isUserInitiated && this.kit.userAccountId && this.kit.operationalMode === "provideBytes" && params.transfers.length === 1) {
|
|
20
|
+
const receiverTransfer = params.transfers[0];
|
|
21
|
+
const amountValue = typeof receiverTransfer.amount === "string" || typeof receiverTransfer.amount === "number" ? receiverTransfer.amount : receiverTransfer.amount.toString();
|
|
22
|
+
const amountBigNum = new BigNumber(amountValue);
|
|
23
|
+
if (amountBigNum.isPositive()) {
|
|
24
|
+
const recipientAccountId = typeof receiverTransfer.accountId === "string" ? AccountId.fromString(receiverTransfer.accountId) : receiverTransfer.accountId;
|
|
25
|
+
const roundedAmount = amountBigNum.toFixed(8, BigNumber.ROUND_DOWN);
|
|
26
|
+
const sdkHbarAmount = Hbar.fromString(roundedAmount);
|
|
27
|
+
this.logger.info(
|
|
28
|
+
`[AccountBuilder.transferHbar] Configuring user-initiated scheduled transfer: ${sdkHbarAmount.toString()} from ${this.kit.userAccountId} to ${recipientAccountId.toString()}`
|
|
29
|
+
);
|
|
30
|
+
this.addNote(
|
|
31
|
+
`Configured HBAR transfer from your account (${this.kit.userAccountId}) to ${recipientAccountId.toString()} for ${sdkHbarAmount.toString()}.`
|
|
32
|
+
);
|
|
33
|
+
transaction.addHbarTransfer(recipientAccountId, sdkHbarAmount);
|
|
34
|
+
transaction.addHbarTransfer(
|
|
35
|
+
AccountId.fromString(this.kit.userAccountId),
|
|
36
|
+
sdkHbarAmount.negated()
|
|
37
|
+
);
|
|
38
|
+
userTransferProcessedForScheduling = true;
|
|
39
|
+
}
|
|
26
40
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
41
|
+
if (!userTransferProcessedForScheduling) {
|
|
42
|
+
const processedTransfers = [];
|
|
43
|
+
for (const transferInput of params.transfers) {
|
|
44
|
+
const accountId = typeof transferInput.accountId === "string" ? AccountId.fromString(transferInput.accountId) : transferInput.accountId;
|
|
45
|
+
const amountValue = typeof transferInput.amount === "string" || typeof transferInput.amount === "number" ? transferInput.amount : transferInput.amount.toString();
|
|
46
|
+
const amountBigNum = new BigNumber(amountValue);
|
|
47
|
+
const roundedAmount = amountBigNum.toFixed(8, BigNumber.ROUND_DOWN);
|
|
48
|
+
this.logger.info(
|
|
49
|
+
`Processing transfer: ${amountValue} HBAR (rounded to ${roundedAmount}) for account ${accountId.toString()}`
|
|
50
|
+
);
|
|
51
|
+
const sdkHbarAmount = Hbar.fromString(roundedAmount);
|
|
52
|
+
processedTransfers.push({
|
|
53
|
+
accountId,
|
|
54
|
+
amount: amountBigNum,
|
|
55
|
+
hbar: sdkHbarAmount
|
|
56
|
+
});
|
|
57
|
+
const tinybarsContribution = sdkHbarAmount.toTinybars();
|
|
58
|
+
netZeroInTinybars = netZeroInTinybars.plus(
|
|
59
|
+
tinybarsContribution.toString()
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
if (!netZeroInTinybars.isZero()) {
|
|
63
|
+
this.logger.warn(
|
|
64
|
+
`Transfer sum not zero: ${netZeroInTinybars.toString()} tinybars off. Adjusting last transfer.`
|
|
65
|
+
);
|
|
66
|
+
if (processedTransfers.length > 0) {
|
|
67
|
+
const lastTransfer = processedTransfers[processedTransfers.length - 1];
|
|
68
|
+
const adjustment = netZeroInTinybars.dividedBy(-1e8);
|
|
69
|
+
const adjustedAmount = lastTransfer.amount.plus(adjustment);
|
|
70
|
+
const adjustedRounded = adjustedAmount.toFixed(8, BigNumber.ROUND_DOWN);
|
|
71
|
+
lastTransfer.hbar = Hbar.fromString(adjustedRounded);
|
|
72
|
+
this.logger.info(
|
|
73
|
+
`Adjusted last transfer for ${lastTransfer.accountId.toString()} to ${adjustedRounded} HBAR`
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
for (const transfer of processedTransfers) {
|
|
78
|
+
transaction.addHbarTransfer(transfer.accountId, transfer.hbar);
|
|
79
|
+
}
|
|
38
80
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
81
|
+
if (typeof params.memo !== "undefined") {
|
|
82
|
+
if (params.memo === null) {
|
|
83
|
+
this.logger.warn("Received null for memo in transferHbar.");
|
|
84
|
+
} else {
|
|
85
|
+
transaction.setTransactionMemo(params.memo);
|
|
86
|
+
}
|
|
42
87
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Format a reference ID in the standard ref:// format
|
|
47
|
-
*
|
|
48
|
-
* @param referenceId The reference ID to format
|
|
49
|
-
* @returns Formatted reference string
|
|
50
|
-
*/
|
|
51
|
-
static formatReference(referenceId) {
|
|
52
|
-
return `ref://${referenceId}`;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Generate a test reference ID (for testing purposes only)
|
|
56
|
-
*
|
|
57
|
-
* @param testSeed A test seed to generate a fake but valid ID format
|
|
58
|
-
* @returns A valid format reference ID for testing
|
|
59
|
-
*/
|
|
60
|
-
static generateTestId(testSeed) {
|
|
61
|
-
const content = Buffer.from(`test-${testSeed}-${Date.now()}`);
|
|
62
|
-
return this.generateId(content);
|
|
88
|
+
this.setCurrentTransaction(transaction);
|
|
89
|
+
return this;
|
|
63
90
|
}
|
|
64
91
|
}
|
|
65
92
|
export {
|
|
66
|
-
|
|
93
|
+
AccountBuilder
|
|
67
94
|
};
|
|
68
95
|
//# sourceMappingURL=index24.js.map
|
package/dist/esm/index24.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index24.js","sources":["../../src/
|
|
1
|
+
{"version":3,"file":"index24.js","sources":["../../src/plugins/hbar/AccountBuilder.ts"],"sourcesContent":["import {\n AccountId,\n Hbar,\n TransferTransaction,\n} from '@hashgraph/sdk';\nimport BigNumber from 'bignumber.js';\nimport { HederaAgentKit, BaseServiceBuilder } from 'hedera-agent-kit';\nimport { HbarTransferParams } from './types';\n\n/**\n * Custom AccountBuilder that properly handles HBAR decimal conversion\n */\nexport class AccountBuilder extends BaseServiceBuilder {\n constructor(hederaKit: HederaAgentKit) {\n super(hederaKit);\n }\n\n /**\n * Transfers HBAR between accounts with proper decimal handling\n */\n public transferHbar(\n params: HbarTransferParams,\n isUserInitiated: boolean = true\n ): this {\n this.clearNotes();\n const transaction = new TransferTransaction();\n \n if (!params.transfers || params.transfers.length === 0) {\n throw new Error('HbarTransferParams must include at least one transfer.');\n }\n\n let netZeroInTinybars = new BigNumber(0);\n let userTransferProcessedForScheduling = false;\n\n if (\n isUserInitiated &&\n this.kit.userAccountId &&\n (this.kit.operationalMode as string) === 'provideBytes' &&\n params.transfers.length === 1\n ) {\n const receiverTransfer = params.transfers[0];\n const amountValue =\n typeof receiverTransfer.amount === 'string' ||\n typeof receiverTransfer.amount === 'number'\n ? receiverTransfer.amount\n : receiverTransfer.amount.toString();\n\n const amountBigNum = new BigNumber(amountValue);\n\n if (amountBigNum.isPositive()) {\n const recipientAccountId =\n typeof receiverTransfer.accountId === 'string'\n ? AccountId.fromString(receiverTransfer.accountId)\n : receiverTransfer.accountId;\n\n const roundedAmount = amountBigNum.toFixed(8, BigNumber.ROUND_DOWN);\n const sdkHbarAmount = Hbar.fromString(roundedAmount);\n\n this.logger.info(\n `[AccountBuilder.transferHbar] Configuring user-initiated scheduled transfer: ${sdkHbarAmount.toString()} from ${\n this.kit.userAccountId\n } to ${recipientAccountId.toString()}`\n );\n \n this.addNote(\n `Configured HBAR transfer from your account (${\n this.kit.userAccountId\n }) to ${recipientAccountId.toString()} for ${sdkHbarAmount.toString()}.`\n );\n\n transaction.addHbarTransfer(recipientAccountId, sdkHbarAmount);\n transaction.addHbarTransfer(\n AccountId.fromString(this.kit.userAccountId),\n sdkHbarAmount.negated()\n );\n\n userTransferProcessedForScheduling = true;\n }\n }\n\n if (!userTransferProcessedForScheduling) {\n const processedTransfers: Array<{\n accountId: AccountId;\n amount: BigNumber;\n hbar: Hbar;\n }> = [];\n \n for (const transferInput of params.transfers) {\n const accountId =\n typeof transferInput.accountId === 'string'\n ? AccountId.fromString(transferInput.accountId)\n : transferInput.accountId;\n\n const amountValue =\n typeof transferInput.amount === 'string' ||\n typeof transferInput.amount === 'number'\n ? transferInput.amount\n : transferInput.amount.toString();\n\n const amountBigNum = new BigNumber(amountValue);\n const roundedAmount = amountBigNum.toFixed(8, BigNumber.ROUND_DOWN);\n \n this.logger.info(\n `Processing transfer: ${amountValue} HBAR (rounded to ${roundedAmount}) for account ${accountId.toString()}`\n );\n\n const sdkHbarAmount = Hbar.fromString(roundedAmount);\n processedTransfers.push({\n accountId,\n amount: amountBigNum,\n hbar: sdkHbarAmount\n });\n\n const tinybarsContribution = sdkHbarAmount.toTinybars();\n netZeroInTinybars = netZeroInTinybars.plus(\n tinybarsContribution.toString()\n );\n }\n\n if (!netZeroInTinybars.isZero()) {\n this.logger.warn(\n `Transfer sum not zero: ${netZeroInTinybars.toString()} tinybars off. Adjusting last transfer.`\n );\n \n if (processedTransfers.length > 0) {\n const lastTransfer = processedTransfers[processedTransfers.length - 1];\n const adjustment = netZeroInTinybars.dividedBy(-100000000);\n const adjustedAmount = lastTransfer.amount.plus(adjustment);\n const adjustedRounded = adjustedAmount.toFixed(8, BigNumber.ROUND_DOWN);\n lastTransfer.hbar = Hbar.fromString(adjustedRounded);\n \n this.logger.info(\n `Adjusted last transfer for ${lastTransfer.accountId.toString()} to ${adjustedRounded} HBAR`\n );\n }\n }\n \n for (const transfer of processedTransfers) {\n transaction.addHbarTransfer(transfer.accountId, transfer.hbar);\n }\n }\n\n if (typeof params.memo !== 'undefined') {\n if (params.memo === null) {\n this.logger.warn('Received null for memo in transferHbar.');\n } else {\n transaction.setTransactionMemo(params.memo);\n }\n }\n\n this.setCurrentTransaction(transaction);\n return this;\n }\n}"],"names":[],"mappings":"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"}
|
package/dist/esm/index25.js
CHANGED
|
@@ -1,30 +1,68 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
agentGenerated: { maxAgeMs: 60 * 60 * 1e3, priority: 3 },
|
|
14
|
-
default: { maxAgeMs: 60 * 60 * 1e3, priority: 4 }
|
|
1
|
+
import { createHash } from "crypto";
|
|
2
|
+
class ReferenceIdGenerator {
|
|
3
|
+
/**
|
|
4
|
+
* Generate a content-based reference ID using SHA-256 hashing
|
|
5
|
+
*
|
|
6
|
+
* @param content The content to generate a reference ID for
|
|
7
|
+
* @returns Deterministic reference ID based on content hash
|
|
8
|
+
*/
|
|
9
|
+
static generateId(content) {
|
|
10
|
+
const hash = createHash("sha256");
|
|
11
|
+
hash.update(content);
|
|
12
|
+
return hash.digest("hex");
|
|
15
13
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Validate that a string is a properly formatted reference ID
|
|
16
|
+
*
|
|
17
|
+
* @param id The ID to validate
|
|
18
|
+
* @returns true if the ID is valid format
|
|
19
|
+
*/
|
|
20
|
+
static isValidReferenceId(id) {
|
|
21
|
+
if (!id || typeof id !== "string") {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
if (id.length !== 64) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
return /^[a-f0-9]+$/.test(id);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Extract reference ID from ref:// format
|
|
31
|
+
*
|
|
32
|
+
* @param input Input string that may contain a reference ID
|
|
33
|
+
* @returns Extracted reference ID or null if not found
|
|
34
|
+
*/
|
|
35
|
+
static extractReferenceId(input) {
|
|
36
|
+
if (!input || typeof input !== "string") {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
const refFormatMatch = input.match(/^ref:\/\/([a-f0-9]{64})$/);
|
|
40
|
+
if (refFormatMatch) {
|
|
41
|
+
return refFormatMatch[1];
|
|
42
|
+
}
|
|
43
|
+
return this.isValidReferenceId(input) ? input : null;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Format a reference ID in the standard ref:// format
|
|
47
|
+
*
|
|
48
|
+
* @param referenceId The reference ID to format
|
|
49
|
+
* @returns Formatted reference string
|
|
50
|
+
*/
|
|
51
|
+
static formatReference(referenceId) {
|
|
52
|
+
return `ref://${referenceId}`;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Generate a test reference ID (for testing purposes only)
|
|
56
|
+
*
|
|
57
|
+
* @param testSeed A test seed to generate a fake but valid ID format
|
|
58
|
+
* @returns A valid format reference ID for testing
|
|
59
|
+
*/
|
|
60
|
+
static generateTestId(testSeed) {
|
|
61
|
+
const content = Buffer.from(`test-${testSeed}-${Date.now()}`);
|
|
62
|
+
return this.generateId(content);
|
|
24
63
|
}
|
|
25
64
|
}
|
|
26
65
|
export {
|
|
27
|
-
|
|
28
|
-
DEFAULT_CONTENT_REFERENCE_CONFIG
|
|
66
|
+
ReferenceIdGenerator
|
|
29
67
|
};
|
|
30
68
|
//# sourceMappingURL=index25.js.map
|
package/dist/esm/index25.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index25.js","sources":["../../src/
|
|
1
|
+
{"version":3,"file":"index25.js","sources":["../../src/memory/ReferenceIdGenerator.ts"],"sourcesContent":["import { createHash } from 'crypto';\nimport { ReferenceId } from '../types/content-reference';\n\n/**\n * Content-based reference ID generator using SHA-256 (HCS-1 style)\n * \n * Generates deterministic reference IDs based on content hashing.\n * Same content always produces the same reference ID.\n */\nexport class ReferenceIdGenerator {\n /**\n * Generate a content-based reference ID using SHA-256 hashing\n * \n * @param content The content to generate a reference ID for\n * @returns Deterministic reference ID based on content hash\n */\n static generateId(content: Buffer): ReferenceId {\n const hash = createHash('sha256');\n hash.update(content);\n return hash.digest('hex');\n }\n \n /**\n * Validate that a string is a properly formatted reference ID\n * \n * @param id The ID to validate\n * @returns true if the ID is valid format\n */\n static isValidReferenceId(id: string): id is ReferenceId {\n if (!id || typeof id !== 'string') {\n return false;\n }\n \n if (id.length !== 64) {\n return false;\n }\n \n return /^[a-f0-9]+$/.test(id);\n }\n \n /**\n * Extract reference ID from ref:// format\n * \n * @param input Input string that may contain a reference ID\n * @returns Extracted reference ID or null if not found\n */\n static extractReferenceId(input: string): ReferenceId | null {\n if (!input || typeof input !== 'string') {\n return null;\n }\n \n const refFormatMatch = input.match(/^ref:\\/\\/([a-f0-9]{64})$/);\n if (refFormatMatch) {\n return refFormatMatch[1] as ReferenceId;\n }\n \n return this.isValidReferenceId(input) ? input : null;\n }\n \n /**\n * Format a reference ID in the standard ref:// format\n * \n * @param referenceId The reference ID to format\n * @returns Formatted reference string\n */\n static formatReference(referenceId: ReferenceId): string {\n return `ref://${referenceId}`;\n }\n \n /**\n * Generate a test reference ID (for testing purposes only)\n * \n * @param testSeed A test seed to generate a fake but valid ID format\n * @returns A valid format reference ID for testing\n */\n static generateTestId(testSeed: string): ReferenceId {\n const content = Buffer.from(`test-${testSeed}-${Date.now()}`);\n return this.generateId(content);\n }\n}"],"names":[],"mappings":";AASO,MAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOhC,OAAO,WAAW,SAA8B;AAC9C,UAAM,OAAO,WAAW,QAAQ;AAChC,SAAK,OAAO,OAAO;AACnB,WAAO,KAAK,OAAO,KAAK;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,mBAAmB,IAA+B;AACvD,QAAI,CAAC,MAAM,OAAO,OAAO,UAAU;AACjC,aAAO;AAAA,IACT;AAEA,QAAI,GAAG,WAAW,IAAI;AACpB,aAAO;AAAA,IACT;AAEA,WAAO,cAAc,KAAK,EAAE;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,mBAAmB,OAAmC;AAC3D,QAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,aAAO;AAAA,IACT;AAEA,UAAM,iBAAiB,MAAM,MAAM,0BAA0B;AAC7D,QAAI,gBAAgB;AAClB,aAAO,eAAe,CAAC;AAAA,IACzB;AAEA,WAAO,KAAK,mBAAmB,KAAK,IAAI,QAAQ;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,gBAAgB,aAAkC;AACvD,WAAO,SAAS,WAAW;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,eAAe,UAA+B;AACnD,UAAM,UAAU,OAAO,KAAK,QAAQ,QAAQ,IAAI,KAAK,IAAA,CAAK,EAAE;AAC5D,WAAO,KAAK,WAAW,OAAO;AAAA,EAChC;AACF;"}
|