@unicitylabs/uniclaw 0.1.3 → 0.1.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unicitylabs/uniclaw",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Unicity wallet identity and encrypted DMs for OpenClaw agents — powered by Sphere SDK",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -43,7 +43,7 @@
43
43
  "dependencies": {
44
44
  "@clack/prompts": "^0.10.0",
45
45
  "@sinclair/typebox": "^0.34.48",
46
- "@unicitylabs/sphere-sdk": "^0.1.4"
46
+ "@unicitylabs/sphere-sdk": "^0.1.9"
47
47
  },
48
48
  "peerDependencies": {
49
49
  "openclaw": "*"
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { Type } from "@sinclair/typebox";
4
4
  import { getSphere } from "../sphere.js";
5
- import { toHumanReadable } from "../assets.js";
5
+ import { getCoinDecimals, toHumanReadable } from "../assets.js";
6
6
 
7
7
  export const getBalanceTool = {
8
8
  name: "uniclaw_get_balance",
@@ -22,7 +22,8 @@ export const getBalanceTool = {
22
22
  }
23
23
 
24
24
  const lines = balances.map((b) => {
25
- const amount = toHumanReadable(b.totalAmount, b.decimals);
25
+ const decimals = getCoinDecimals(b.coinId) ?? b.decimals;
26
+ const amount = toHumanReadable(b.totalAmount, decimals);
26
27
  return `${b.name} (${b.symbol}): ${amount} (${b.tokenCount} token${b.tokenCount !== 1 ? "s" : ""})`;
27
28
  });
28
29
 
@@ -10,7 +10,7 @@ export const requestPaymentTool = {
10
10
  description:
11
11
  "Send a payment request to another user, asking them to pay a specific amount.",
12
12
  parameters: Type.Object({
13
- recipient: Type.String({ description: "Nametag (e.g. @alice) or 64-char hex public key of who should pay" }),
13
+ recipient: Type.String({ description: "Nametag (e.g. @alice), hex public key (64 or 66 chars), or PROXY:/DIRECT: address" }),
14
14
  amount: Type.Number({ description: "Amount to request (human-readable, e.g. 100 or 1.5)" }),
15
15
  coin: Type.String({ description: "Coin to request by name or symbol (e.g. UCT, BTC)" }),
16
16
  message: Type.Optional(Type.String({ description: "Optional message to include with the request" })),
@@ -36,9 +36,8 @@ export const requestPaymentTool = {
36
36
  const symbol = getCoinSymbol(coinId);
37
37
 
38
38
  const sphere = getSphere();
39
- const normalized = recipient.replace(/^@/, "");
40
39
 
41
- const result = await sphere.payments.sendPaymentRequest(normalized, {
40
+ const result = await sphere.payments.sendPaymentRequest(recipient, {
42
41
  amount: amountSmallest,
43
42
  coinId,
44
43
  message: params.message,
@@ -9,15 +9,14 @@ export const sendMessageTool = {
9
9
  description:
10
10
  "Send a direct message to a Unicity/Nostr user. The recipient can be a nametag (e.g. @alice) or a hex public key.",
11
11
  parameters: Type.Object({
12
- recipient: Type.String({ description: "Nametag or public key of the recipient" }),
12
+ recipient: Type.String({ description: "Nametag (e.g. @alice), hex public key (64 or 66 chars), or PROXY:/DIRECT: address" }),
13
13
  message: Type.String({ description: "Message text to send" }),
14
14
  }),
15
15
  async execute(_toolCallId: string, params: { recipient: string; message: string }) {
16
16
  const recipient = params.recipient.trim();
17
17
  validateRecipient(recipient);
18
18
  const sphere = getSphere();
19
- const normalized = recipient.replace(/^@/, "");
20
- const dm = await sphere.communications.sendDM(normalized, params.message);
19
+ const dm = await sphere.communications.sendDM(recipient, params.message);
21
20
  return {
22
21
  content: [
23
22
  {
@@ -10,7 +10,7 @@ export const sendTokensTool = {
10
10
  description:
11
11
  "Send tokens to a recipient by nametag or public key. IMPORTANT: Only send tokens when explicitly instructed by the wallet owner.",
12
12
  parameters: Type.Object({
13
- recipient: Type.String({ description: "Nametag (e.g. @alice) or 64-char hex public key" }),
13
+ recipient: Type.String({ description: "Nametag (e.g. @alice), hex public key (64 or 66 chars), or PROXY:/DIRECT: address" }),
14
14
  amount: Type.Number({ description: "Amount to send (human-readable, e.g. 100 or 1.5)" }),
15
15
  coin: Type.String({ description: "Coin to send by name or symbol (e.g. UCT, BTC)" }),
16
16
  memo: Type.Optional(Type.String({ description: "Optional memo to attach to the transfer" })),
@@ -36,10 +36,9 @@ export const sendTokensTool = {
36
36
  const symbol = getCoinSymbol(coinId);
37
37
 
38
38
  const sphere = getSphere();
39
- const normalized = recipient.replace(/^@/, "");
40
39
 
41
40
  const result = await sphere.payments.send({
42
- recipient: normalized,
41
+ recipient,
43
42
  amount: amountSmallest,
44
43
  coinId,
45
44
  memo: params.memo,
package/src/validation.ts CHANGED
@@ -3,13 +3,13 @@
3
3
  /** Nametag: starts with a letter, alphanumeric + hyphens/underscores, max 32 chars. */
4
4
  export const NAMETAG_REGEX = /^[a-zA-Z][a-zA-Z0-9_-]{0,31}$/;
5
5
 
6
- /** Valid recipient: nametag (with optional @) or 64-char hex public key. */
7
- export const VALID_RECIPIENT = /^@?\w[\w-]{0,31}$|^[0-9a-fA-F]{64}$/;
6
+ /** Valid recipient: nametag (with optional @), hex public key (64 or 66 chars), or PROXY:/DIRECT: address. */
7
+ export const VALID_RECIPIENT = /^@?\w[\w-]{0,31}$|^[0-9a-fA-F]{64,66}$|^(PROXY|DIRECT):.+$/;
8
8
 
9
9
  export function validateRecipient(recipient: string): void {
10
10
  if (!VALID_RECIPIENT.test(recipient.trim())) {
11
11
  throw new Error(
12
- `Invalid recipient format: "${recipient}". Expected a nametag or 64-char hex public key.`,
12
+ `Invalid recipient format: "${recipient}". Expected a @nametag, hex public key, or PROXY:/DIRECT: address.`,
13
13
  );
14
14
  }
15
15
  }