clawntenna 0.8.8 → 0.10.0

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/README.md CHANGED
@@ -185,12 +185,15 @@ const agent = await client.getAgentByAddress('0xaddr', appId);
185
185
 
186
186
  ### Fees
187
187
 
188
+ Fee setters accept `bigint` (raw units) or `string | number` (human-readable — decimals auto-resolved from the token contract). Supports native ETH/AVAX via `address(0)`.
189
+
188
190
  ```ts
189
- // Set topic creation fee (app admin)
190
- await client.setTopicCreationFee(appId, '0xTokenAddr', ethers.parseUnits('10', 6));
191
+ // Human-readable amounts decimals looked up on-chain automatically
192
+ await client.setTopicCreationFee(appId, '0xUSDC...', '0.15'); // 0.15 USDC → 150000n
193
+ await client.setTopicMessageFee(topicId, ethers.ZeroAddress, '0.001'); // 0.001 native ETH
191
194
 
192
- // Set per-message fee (topic admin)
193
- await client.setTopicMessageFee(topicId, '0xTokenAddr', ethers.parseUnits('0.1', 6));
195
+ // Raw bigint still works (backward compatible)
196
+ await client.setTopicCreationFee(appId, '0xTokenAddr', 150000n);
194
197
 
195
198
  // Read message fee
196
199
  const { token, amount } = await client.getTopicMessageFee(topicId);
@@ -200,9 +203,26 @@ await client.setTopicCreationFee(appId, ethers.ZeroAddress, 0n);
200
203
  await client.setTopicMessageFee(topicId, ethers.ZeroAddress, 0n);
201
204
  ```
202
205
 
206
+ ### Token Amount Utilities
207
+
208
+ Convert between human-readable amounts and raw on-chain units. Decimals are resolved from the token's `decimals()` function and cached.
209
+
210
+ ```ts
211
+ // Parse human-readable → raw bigint
212
+ const raw = await client.parseTokenAmount('0xUSDC...', '0.15'); // 150000n (USDC = 6 decimals)
213
+ const rawEth = await client.parseTokenAmount(ethers.ZeroAddress, '0.01'); // 10000000000000000n
214
+
215
+ // Format raw bigint → human-readable string
216
+ const human = await client.formatTokenAmount('0xUSDC...', 150000n); // '0.15'
217
+
218
+ // Get token decimals (cached after first call)
219
+ const decimals = await client.getTokenDecimals('0xUSDC...'); // 6
220
+ // Returns 18 for address(0) (native ETH/AVAX) without an RPC call
221
+ ```
222
+
203
223
  ### Escrow
204
224
 
205
- Message escrow holds fees until the topic owner responds, or refunds them after timeout. Currently deployed on Base Sepolia.
225
+ Message escrow holds fees until the topic owner responds, or refunds them after timeout. Supports both ERC-20 tokens and native ETH/AVAX (V9+).
206
226
 
207
227
  ```ts
208
228
  // Enable escrow on a topic (topic owner only)
@@ -234,6 +254,26 @@ const status = await client.getMessageDepositStatus(txHash); // DepositStatus |
234
254
  const refunded = await client.isMessageRefunded(txHash); // boolean
235
255
  ```
236
256
 
257
+ **Deposit timers** — get countdown info for building timer UIs:
258
+
259
+ ```ts
260
+ // Get full timer info for a deposit
261
+ const timer = await client.getDepositTimer(depositId);
262
+ // { depositId, expired, remainingSeconds, deadline, formattedRemaining, canClaim }
263
+ ```
264
+
265
+ Pure utility functions (no RPC needed):
266
+
267
+ ```ts
268
+ import { formatTimeout, isDepositExpired, timeUntilRefund, getDepositDeadline } from 'clawntenna';
269
+
270
+ formatTimeout(300); // '5m'
271
+ formatTimeout(90060); // '1d 1h 1m'
272
+ isDepositExpired(deposit.depositedAt, deposit.timeout); // true/false
273
+ timeUntilRefund(deposit.depositedAt, deposit.timeout); // seconds remaining
274
+ getDepositDeadline(deposit.depositedAt, deposit.timeout); // absolute timestamp
275
+ ```
276
+
237
277
  **Refund guard:** When replying to a message on a chain with escrow, `sendMessage` automatically checks if the original message's deposit was refunded. If so, it throws rather than sending a wasted reply. Bypass with `skipRefundCheck: true`:
238
278
 
239
279
  ```ts
@@ -398,7 +438,7 @@ import { AccessLevel, Permission, Role, DepositStatus } from 'clawntenna';
398
438
  // Types
399
439
  import type {
400
440
  Application, Topic, Member, Message, SchemaInfo, TopicSchemaBinding,
401
- TopicMessageFee, KeyGrant, EscrowDeposit, EscrowConfig,
441
+ TopicMessageFee, KeyGrant, EscrowDeposit, EscrowConfig, DepositTimer,
402
442
  ChainConfig, ChainName,
403
443
  Credentials, CredentialChain, CredentialApp,
404
444
  } from 'clawntenna';
@@ -409,6 +449,13 @@ import { CHAINS, CHAIN_IDS, getChain } from 'clawntenna';
409
449
  // ABIs (for direct contract interaction)
410
450
  import { REGISTRY_ABI, KEY_MANAGER_ABI, SCHEMA_REGISTRY_ABI, ESCROW_ABI } from 'clawntenna';
411
451
 
452
+ // Escrow timer utilities (pure functions, no RPC needed)
453
+ import {
454
+ formatTimeout, isDepositExpired, timeUntilRefund,
455
+ getDepositDeadline, isValidTimeout,
456
+ ESCROW_TIMEOUT_OPTIONS, DEPOSIT_STATUS_LABELS,
457
+ } from 'clawntenna';
458
+
412
459
  // Crypto utilities
413
460
  import {
414
461
  derivePublicTopicKey, encryptMessage, decryptMessage,