clawntenna 0.9.0 → 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/dist/cli/index.js +183 -101
- package/dist/index.cjs +200 -100
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +43 -9
- package/dist/index.d.ts +43 -9
- package/dist/index.js +198 -100
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -21,7 +21,8 @@ var CHAINS = {
|
|
|
21
21
|
keyManager: "0x5562B553a876CBdc8AA4B3fb0687f22760F4759e",
|
|
22
22
|
schemaRegistry: "0xB7eB50e9058198b99b5b2589E6D70b2d99d5440a",
|
|
23
23
|
identityRegistry: "0x8004AA63c570c570eBF15376c0dB199918BFe9Fb",
|
|
24
|
-
escrow: "0x74e376C53f4afd5Cd32a77dDc627f477FcFC2333"
|
|
24
|
+
escrow: "0x74e376C53f4afd5Cd32a77dDc627f477FcFC2333",
|
|
25
|
+
defaultLookback: 2e5
|
|
25
26
|
},
|
|
26
27
|
base: {
|
|
27
28
|
chainId: 8453,
|
|
@@ -32,7 +33,9 @@ var CHAINS = {
|
|
|
32
33
|
registry: "0x5fF6BF04F1B5A78ae884D977a3C80A0D8E2072bF",
|
|
33
34
|
keyManager: "0xdc302ff43a34F6aEa19426D60C9D150e0661E4f4",
|
|
34
35
|
schemaRegistry: "0x5c11d2eA4470eD9025D810A21a885FE16dC987Bd",
|
|
35
|
-
identityRegistry: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432"
|
|
36
|
+
identityRegistry: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432",
|
|
37
|
+
escrow: "0x04eC9a25C942192834F447eC9192831B56Ae2D7D",
|
|
38
|
+
defaultLookback: 2e5
|
|
36
39
|
},
|
|
37
40
|
avalanche: {
|
|
38
41
|
chainId: 43114,
|
|
@@ -43,7 +46,9 @@ var CHAINS = {
|
|
|
43
46
|
registry: "0x3Ca2FF0bD1b3633513299EB5d3e2d63e058b0713",
|
|
44
47
|
keyManager: "0x5a5ea9D408FBA984fFf6e243Dcc71ff6E00C73E4",
|
|
45
48
|
schemaRegistry: "0x23D96e610E8E3DA5341a75B77F1BFF7EA9c3A62B",
|
|
46
|
-
identityRegistry: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432"
|
|
49
|
+
identityRegistry: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432",
|
|
50
|
+
escrow: "0x4068245c35a498Da4336aD1Ab0Fb71ef534bfd03",
|
|
51
|
+
defaultLookback: 5e5
|
|
47
52
|
}
|
|
48
53
|
};
|
|
49
54
|
|
|
@@ -3355,16 +3360,51 @@ function getDepositDeadline(depositedAt, timeout) {
|
|
|
3355
3360
|
return Number(depositedAt + timeout);
|
|
3356
3361
|
}
|
|
3357
3362
|
|
|
3363
|
+
// src/rpc-errors.ts
|
|
3364
|
+
function classifyRpcError(err, ctx) {
|
|
3365
|
+
const msg = err.message ?? "";
|
|
3366
|
+
if (msg.includes("BAD_DATA") || msg.includes("could not decode result data")) {
|
|
3367
|
+
return `${ctx.method} failed: contract may not be deployed on ${ctx.chainName}, or the RPC returned an empty response. Check that the correct chain and RPC URL are configured.`;
|
|
3368
|
+
}
|
|
3369
|
+
if (msg.includes("NETWORK_ERROR") || msg.includes("ECONNREFUSED") || msg.includes("fetch failed") || msg.includes("getaddrinfo")) {
|
|
3370
|
+
return `${ctx.method} failed: network error connecting to ${ctx.chainName} RPC. Check your RPC URL and network connectivity.`;
|
|
3371
|
+
}
|
|
3372
|
+
return null;
|
|
3373
|
+
}
|
|
3374
|
+
|
|
3358
3375
|
// src/client.ts
|
|
3359
3376
|
var Clawntenna = class _Clawntenna {
|
|
3360
3377
|
provider;
|
|
3361
|
-
wallet;
|
|
3362
|
-
registry;
|
|
3363
|
-
keyManager;
|
|
3364
|
-
schemaRegistry;
|
|
3365
|
-
identityRegistry;
|
|
3366
|
-
escrow;
|
|
3367
3378
|
chainName;
|
|
3379
|
+
_signer;
|
|
3380
|
+
_address;
|
|
3381
|
+
_registry;
|
|
3382
|
+
_keyManager;
|
|
3383
|
+
_schemaRegistry;
|
|
3384
|
+
_identityRegistry;
|
|
3385
|
+
_escrow;
|
|
3386
|
+
/** @deprecated Use `signer` instead. */
|
|
3387
|
+
get wallet() {
|
|
3388
|
+
return this._signer;
|
|
3389
|
+
}
|
|
3390
|
+
get signer() {
|
|
3391
|
+
return this._signer;
|
|
3392
|
+
}
|
|
3393
|
+
get registry() {
|
|
3394
|
+
return this._registry;
|
|
3395
|
+
}
|
|
3396
|
+
get keyManager() {
|
|
3397
|
+
return this._keyManager;
|
|
3398
|
+
}
|
|
3399
|
+
get schemaRegistry() {
|
|
3400
|
+
return this._schemaRegistry;
|
|
3401
|
+
}
|
|
3402
|
+
get identityRegistry() {
|
|
3403
|
+
return this._identityRegistry;
|
|
3404
|
+
}
|
|
3405
|
+
get escrow() {
|
|
3406
|
+
return this._escrow;
|
|
3407
|
+
}
|
|
3368
3408
|
// In-memory ECDH state
|
|
3369
3409
|
ecdhPrivateKey = null;
|
|
3370
3410
|
ecdhPublicKey = null;
|
|
@@ -3385,23 +3425,56 @@ var Clawntenna = class _Clawntenna {
|
|
|
3385
3425
|
const escrowAddr = options.escrowAddress ?? chain.escrow;
|
|
3386
3426
|
const signer = options.privateKey ? new ethers.Wallet(options.privateKey, this.provider) : null;
|
|
3387
3427
|
const runner = signer ?? this.provider;
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3428
|
+
this._signer = signer;
|
|
3429
|
+
this._address = signer?.address ?? null;
|
|
3430
|
+
this._registry = new ethers.Contract(registryAddr, REGISTRY_ABI, runner);
|
|
3431
|
+
this._keyManager = new ethers.Contract(keyManagerAddr, KEY_MANAGER_ABI, runner);
|
|
3432
|
+
this._schemaRegistry = new ethers.Contract(schemaRegistryAddr, SCHEMA_REGISTRY_ABI, runner);
|
|
3433
|
+
this._identityRegistry = chain.identityRegistry ? new ethers.Contract(chain.identityRegistry, IDENTITY_REGISTRY_ABI, runner) : null;
|
|
3434
|
+
this._escrow = escrowAddr ? new ethers.Contract(escrowAddr, ESCROW_ABI, runner) : null;
|
|
3435
|
+
}
|
|
3436
|
+
/**
|
|
3437
|
+
* Connect an external signer (e.g. from BrowserProvider).
|
|
3438
|
+
* Reconnects all contract instances to the new signer.
|
|
3439
|
+
*/
|
|
3440
|
+
async connectSigner(signer) {
|
|
3441
|
+
this._address = await signer.getAddress();
|
|
3442
|
+
this._signer = signer;
|
|
3443
|
+
this._registry = this._registry.connect(signer);
|
|
3444
|
+
this._keyManager = this._keyManager.connect(signer);
|
|
3445
|
+
this._schemaRegistry = this._schemaRegistry.connect(signer);
|
|
3446
|
+
if (this._identityRegistry) {
|
|
3447
|
+
this._identityRegistry = this._identityRegistry.connect(signer);
|
|
3448
|
+
}
|
|
3449
|
+
if (this._escrow) {
|
|
3450
|
+
this._escrow = this._escrow.connect(signer);
|
|
3451
|
+
}
|
|
3452
|
+
}
|
|
3453
|
+
requireSigner() {
|
|
3454
|
+
if (!this._signer) {
|
|
3455
|
+
throw new Error("Signer required. Pass privateKey in constructor or call connectSigner().");
|
|
3456
|
+
}
|
|
3457
|
+
return this._signer;
|
|
3458
|
+
}
|
|
3459
|
+
requireAddress() {
|
|
3460
|
+
if (!this._address) {
|
|
3461
|
+
throw new Error("Signer required. Pass privateKey in constructor or call connectSigner().");
|
|
3462
|
+
}
|
|
3463
|
+
return this._address;
|
|
3464
|
+
}
|
|
3465
|
+
async _wrapRpcError(fn, method) {
|
|
3466
|
+
try {
|
|
3467
|
+
return await fn();
|
|
3468
|
+
} catch (err) {
|
|
3469
|
+
if (err instanceof Error) {
|
|
3470
|
+
const hint = classifyRpcError(err, { method, chainName: this.chainName });
|
|
3471
|
+
if (hint) throw new Error(hint, { cause: err });
|
|
3472
|
+
}
|
|
3473
|
+
throw err;
|
|
3400
3474
|
}
|
|
3401
|
-
this.escrow = escrowAddr ? new ethers.Contract(escrowAddr, ESCROW_ABI, runner) : null;
|
|
3402
3475
|
}
|
|
3403
3476
|
get address() {
|
|
3404
|
-
return this.
|
|
3477
|
+
return this._address;
|
|
3405
3478
|
}
|
|
3406
3479
|
// ===== MESSAGING =====
|
|
3407
3480
|
/**
|
|
@@ -3409,7 +3482,7 @@ var Clawntenna = class _Clawntenna {
|
|
|
3409
3482
|
* Automatically determines encryption key based on topic access level.
|
|
3410
3483
|
*/
|
|
3411
3484
|
async sendMessage(topicId, text, options) {
|
|
3412
|
-
|
|
3485
|
+
this.requireSigner();
|
|
3413
3486
|
if (options?.replyTo && this.escrow && !options?.skipRefundCheck) {
|
|
3414
3487
|
const refunded = await this.isMessageRefunded(options.replyTo);
|
|
3415
3488
|
if (refunded) {
|
|
@@ -3447,13 +3520,17 @@ var Clawntenna = class _Clawntenna {
|
|
|
3447
3520
|
const filter = this.registry.filters.MessageSent(topicId);
|
|
3448
3521
|
const CHUNK_SIZE = 2e3;
|
|
3449
3522
|
const currentBlock = await this.provider.getBlockNumber();
|
|
3450
|
-
const
|
|
3523
|
+
const chain = CHAINS[this.chainName];
|
|
3524
|
+
const maxRange = options?.fromBlock != null ? currentBlock - options.fromBlock : chain.defaultLookback;
|
|
3451
3525
|
const startBlock = currentBlock - maxRange;
|
|
3452
3526
|
const allEvents = [];
|
|
3453
3527
|
let toBlock = currentBlock;
|
|
3454
3528
|
while (toBlock > startBlock && allEvents.length < limit) {
|
|
3455
3529
|
const chunkFrom = Math.max(toBlock - CHUNK_SIZE + 1, startBlock);
|
|
3456
|
-
const events = await this.
|
|
3530
|
+
const events = await this._wrapRpcError(
|
|
3531
|
+
() => this.registry.queryFilter(filter, chunkFrom, toBlock),
|
|
3532
|
+
"readMessages"
|
|
3533
|
+
);
|
|
3457
3534
|
allEvents.unshift(...events);
|
|
3458
3535
|
toBlock = chunkFrom - 1;
|
|
3459
3536
|
}
|
|
@@ -3463,12 +3540,12 @@ var Clawntenna = class _Clawntenna {
|
|
|
3463
3540
|
const payloadStr = ethers.toUtf8String(log.args.payload);
|
|
3464
3541
|
const parsed = decryptMessage(payloadStr, key);
|
|
3465
3542
|
messages.push({
|
|
3466
|
-
topicId
|
|
3543
|
+
topicId,
|
|
3467
3544
|
sender: log.args.sender,
|
|
3468
3545
|
text: parsed?.text ?? "[decryption failed]",
|
|
3469
3546
|
replyTo: parsed?.replyTo ?? null,
|
|
3470
3547
|
mentions: parsed?.mentions ?? null,
|
|
3471
|
-
timestamp: log.args.timestamp,
|
|
3548
|
+
timestamp: Number(log.args.timestamp),
|
|
3472
3549
|
txHash: log.transactionHash,
|
|
3473
3550
|
blockNumber: log.blockNumber
|
|
3474
3551
|
});
|
|
@@ -3489,12 +3566,12 @@ var Clawntenna = class _Clawntenna {
|
|
|
3489
3566
|
const payloadStr = ethers.toUtf8String(payload);
|
|
3490
3567
|
const parsed = decryptMessage(payloadStr, key);
|
|
3491
3568
|
callback({
|
|
3492
|
-
topicId: tId,
|
|
3569
|
+
topicId: Number(tId),
|
|
3493
3570
|
sender,
|
|
3494
3571
|
text: parsed?.text ?? "[decryption failed]",
|
|
3495
3572
|
replyTo: parsed?.replyTo ?? null,
|
|
3496
3573
|
mentions: parsed?.mentions ?? null,
|
|
3497
|
-
timestamp,
|
|
3574
|
+
timestamp: Number(timestamp),
|
|
3498
3575
|
txHash: event.transactionHash,
|
|
3499
3576
|
blockNumber: event.blockNumber
|
|
3500
3577
|
});
|
|
@@ -3506,7 +3583,7 @@ var Clawntenna = class _Clawntenna {
|
|
|
3506
3583
|
}
|
|
3507
3584
|
// ===== NICKNAMES =====
|
|
3508
3585
|
async setNickname(appId, nickname) {
|
|
3509
|
-
|
|
3586
|
+
this.requireSigner();
|
|
3510
3587
|
return this.registry.setNickname(appId, nickname);
|
|
3511
3588
|
}
|
|
3512
3589
|
async getNickname(appId, address) {
|
|
@@ -3520,11 +3597,11 @@ var Clawntenna = class _Clawntenna {
|
|
|
3520
3597
|
return { canChange, timeRemaining };
|
|
3521
3598
|
}
|
|
3522
3599
|
async clearNickname(appId) {
|
|
3523
|
-
|
|
3600
|
+
this.requireSigner();
|
|
3524
3601
|
return this.registry.clearNickname(appId);
|
|
3525
3602
|
}
|
|
3526
3603
|
async setNicknameCooldown(appId, cooldownSeconds) {
|
|
3527
|
-
|
|
3604
|
+
this.requireSigner();
|
|
3528
3605
|
return this.registry.setNicknameCooldown(appId, cooldownSeconds);
|
|
3529
3606
|
}
|
|
3530
3607
|
async getNicknameCooldown(appId) {
|
|
@@ -3532,24 +3609,26 @@ var Clawntenna = class _Clawntenna {
|
|
|
3532
3609
|
}
|
|
3533
3610
|
// ===== TOPICS =====
|
|
3534
3611
|
async createTopic(appId, name, description, accessLevel) {
|
|
3535
|
-
|
|
3612
|
+
this.requireSigner();
|
|
3536
3613
|
return this.registry.createTopic(appId, name, description, accessLevel);
|
|
3537
3614
|
}
|
|
3538
3615
|
async getTopic(topicId) {
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3616
|
+
return this._wrapRpcError(async () => {
|
|
3617
|
+
const t = await this.registry.getTopic(topicId);
|
|
3618
|
+
return {
|
|
3619
|
+
id: t.id,
|
|
3620
|
+
applicationId: t.applicationId,
|
|
3621
|
+
name: t.name,
|
|
3622
|
+
description: t.description,
|
|
3623
|
+
owner: t.owner,
|
|
3624
|
+
creator: t.creator,
|
|
3625
|
+
createdAt: t.createdAt,
|
|
3626
|
+
lastMessageAt: t.lastMessageAt,
|
|
3627
|
+
messageCount: t.messageCount,
|
|
3628
|
+
accessLevel: Number(t.accessLevel),
|
|
3629
|
+
active: t.active
|
|
3630
|
+
};
|
|
3631
|
+
}, "getTopic");
|
|
3553
3632
|
}
|
|
3554
3633
|
async getApplicationTopics(appId) {
|
|
3555
3634
|
return this.registry.getApplicationTopics(appId);
|
|
@@ -3559,7 +3638,7 @@ var Clawntenna = class _Clawntenna {
|
|
|
3559
3638
|
return Number(count);
|
|
3560
3639
|
}
|
|
3561
3640
|
async setTopicPermission(topicId, user, permission) {
|
|
3562
|
-
|
|
3641
|
+
this.requireSigner();
|
|
3563
3642
|
return this.registry.setTopicPermission(topicId, user, permission);
|
|
3564
3643
|
}
|
|
3565
3644
|
async getTopicPermission(topicId, user) {
|
|
@@ -3568,15 +3647,15 @@ var Clawntenna = class _Clawntenna {
|
|
|
3568
3647
|
}
|
|
3569
3648
|
// ===== MEMBERS =====
|
|
3570
3649
|
async addMember(appId, address, nickname, roles) {
|
|
3571
|
-
|
|
3650
|
+
this.requireSigner();
|
|
3572
3651
|
return this.registry.addMember(appId, address, nickname, roles);
|
|
3573
3652
|
}
|
|
3574
3653
|
async removeMember(appId, address) {
|
|
3575
|
-
|
|
3654
|
+
this.requireSigner();
|
|
3576
3655
|
return this.registry.removeMember(appId, address);
|
|
3577
3656
|
}
|
|
3578
3657
|
async updateMemberRoles(appId, address, roles) {
|
|
3579
|
-
|
|
3658
|
+
this.requireSigner();
|
|
3580
3659
|
return this.registry.updateMemberRoles(appId, address, roles);
|
|
3581
3660
|
}
|
|
3582
3661
|
async getMember(appId, address) {
|
|
@@ -3603,7 +3682,7 @@ var Clawntenna = class _Clawntenna {
|
|
|
3603
3682
|
}
|
|
3604
3683
|
// ===== APPLICATIONS =====
|
|
3605
3684
|
async createApplication(name, description, frontendUrl, allowPublicTopicCreation) {
|
|
3606
|
-
|
|
3685
|
+
this.requireSigner();
|
|
3607
3686
|
return this.registry.createApplication(name, description, frontendUrl, allowPublicTopicCreation);
|
|
3608
3687
|
}
|
|
3609
3688
|
async getApplicationCount() {
|
|
@@ -3611,25 +3690,27 @@ var Clawntenna = class _Clawntenna {
|
|
|
3611
3690
|
return Number(count);
|
|
3612
3691
|
}
|
|
3613
3692
|
async updateFrontendUrl(appId, frontendUrl) {
|
|
3614
|
-
|
|
3693
|
+
this.requireSigner();
|
|
3615
3694
|
return this.registry.updateApplicationFrontendUrl(appId, frontendUrl);
|
|
3616
3695
|
}
|
|
3617
3696
|
async getApplication(appId) {
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3697
|
+
return this._wrapRpcError(async () => {
|
|
3698
|
+
const a = await this.registry.getApplication(appId);
|
|
3699
|
+
return {
|
|
3700
|
+
id: a.id,
|
|
3701
|
+
name: a.name,
|
|
3702
|
+
description: a.description,
|
|
3703
|
+
frontendUrl: a.frontendUrl,
|
|
3704
|
+
owner: a.owner,
|
|
3705
|
+
createdAt: a.createdAt,
|
|
3706
|
+
memberCount: Number(a.memberCount),
|
|
3707
|
+
topicCount: Number(a.topicCount),
|
|
3708
|
+
active: a.active,
|
|
3709
|
+
allowPublicTopicCreation: a.allowPublicTopicCreation,
|
|
3710
|
+
topicCreationFeeToken: a.topicCreationFeeToken,
|
|
3711
|
+
topicCreationFeeAmount: a.topicCreationFeeAmount
|
|
3712
|
+
};
|
|
3713
|
+
}, "getApplication");
|
|
3633
3714
|
}
|
|
3634
3715
|
// ===== FEES =====
|
|
3635
3716
|
async getTopicMessageFee(topicId) {
|
|
@@ -3644,7 +3725,7 @@ var Clawntenna = class _Clawntenna {
|
|
|
3644
3725
|
* (e.g. '0.15' or 0.15 with USDC → 150000n, '0.01' with native ETH → 10000000000000000n)
|
|
3645
3726
|
*/
|
|
3646
3727
|
async setTopicCreationFee(appId, feeToken, feeAmount) {
|
|
3647
|
-
|
|
3728
|
+
this.requireSigner();
|
|
3648
3729
|
const rawAmount = typeof feeAmount === "bigint" ? feeAmount : await this.parseTokenAmount(feeToken, feeAmount);
|
|
3649
3730
|
return this.registry.setTopicCreationFee(appId, feeToken, rawAmount);
|
|
3650
3731
|
}
|
|
@@ -3656,7 +3737,7 @@ var Clawntenna = class _Clawntenna {
|
|
|
3656
3737
|
* (e.g. '0.15' or 0.15 with USDC → 150000n, '0.01' with native ETH → 10000000000000000n)
|
|
3657
3738
|
*/
|
|
3658
3739
|
async setTopicMessageFee(topicId, feeToken, feeAmount) {
|
|
3659
|
-
|
|
3740
|
+
this.requireSigner();
|
|
3660
3741
|
const rawAmount = typeof feeAmount === "bigint" ? feeAmount : await this.parseTokenAmount(feeToken, feeAmount);
|
|
3661
3742
|
return this.registry.setTopicMessageFee(topicId, feeToken, rawAmount);
|
|
3662
3743
|
}
|
|
@@ -3712,14 +3793,14 @@ var Clawntenna = class _Clawntenna {
|
|
|
3712
3793
|
* Enable escrow for a topic (topic owner only).
|
|
3713
3794
|
*/
|
|
3714
3795
|
async enableEscrow(topicId, timeout) {
|
|
3715
|
-
|
|
3796
|
+
this.requireSigner();
|
|
3716
3797
|
return this.requireEscrow().enableEscrow(topicId, timeout);
|
|
3717
3798
|
}
|
|
3718
3799
|
/**
|
|
3719
3800
|
* Disable escrow for a topic (topic owner only).
|
|
3720
3801
|
*/
|
|
3721
3802
|
async disableEscrow(topicId) {
|
|
3722
|
-
|
|
3803
|
+
this.requireSigner();
|
|
3723
3804
|
return this.requireEscrow().disableEscrow(topicId);
|
|
3724
3805
|
}
|
|
3725
3806
|
/**
|
|
@@ -3780,14 +3861,14 @@ var Clawntenna = class _Clawntenna {
|
|
|
3780
3861
|
* Claim a refund for a single deposit.
|
|
3781
3862
|
*/
|
|
3782
3863
|
async claimRefund(depositId) {
|
|
3783
|
-
|
|
3864
|
+
this.requireSigner();
|
|
3784
3865
|
return this.requireEscrow().claimRefund(depositId);
|
|
3785
3866
|
}
|
|
3786
3867
|
/**
|
|
3787
3868
|
* Batch claim refunds for multiple deposits.
|
|
3788
3869
|
*/
|
|
3789
3870
|
async batchClaimRefunds(depositIds) {
|
|
3790
|
-
|
|
3871
|
+
this.requireSigner();
|
|
3791
3872
|
return this.requireEscrow().batchClaimRefunds(depositIds);
|
|
3792
3873
|
}
|
|
3793
3874
|
/**
|
|
@@ -3852,10 +3933,11 @@ var Clawntenna = class _Clawntenna {
|
|
|
3852
3933
|
* Requires a signer capable of signing messages.
|
|
3853
3934
|
*/
|
|
3854
3935
|
async deriveECDHFromWallet(appId = 1) {
|
|
3855
|
-
|
|
3936
|
+
this.requireSigner();
|
|
3937
|
+
const signer = this._signer;
|
|
3856
3938
|
const { privateKey, publicKey } = await deriveKeypairFromSignature(
|
|
3857
|
-
this.
|
|
3858
|
-
(msg) =>
|
|
3939
|
+
this.requireAddress(),
|
|
3940
|
+
(msg) => signer.signMessage(msg),
|
|
3859
3941
|
appId
|
|
3860
3942
|
);
|
|
3861
3943
|
this.ecdhPrivateKey = privateKey;
|
|
@@ -3874,9 +3956,9 @@ var Clawntenna = class _Clawntenna {
|
|
|
3874
3956
|
* Register ECDH public key on-chain.
|
|
3875
3957
|
*/
|
|
3876
3958
|
async registerPublicKey() {
|
|
3877
|
-
|
|
3959
|
+
this.requireSigner();
|
|
3878
3960
|
if (!this.ecdhPublicKey) throw new Error("ECDH key not derived yet");
|
|
3879
|
-
const hasKey = await this.keyManager.hasPublicKey(this.
|
|
3961
|
+
const hasKey = await this.keyManager.hasPublicKey(this.requireAddress());
|
|
3880
3962
|
if (hasKey) {
|
|
3881
3963
|
throw new Error("Public key already registered on-chain");
|
|
3882
3964
|
}
|
|
@@ -3903,13 +3985,13 @@ var Clawntenna = class _Clawntenna {
|
|
|
3903
3985
|
* Returns the generated topic key.
|
|
3904
3986
|
*/
|
|
3905
3987
|
async initializeTopicKey(topicId) {
|
|
3906
|
-
|
|
3988
|
+
this.requireSigner();
|
|
3907
3989
|
if (!this.ecdhPrivateKey || !this.ecdhPublicKey) {
|
|
3908
3990
|
throw new Error("ECDH key not derived yet");
|
|
3909
3991
|
}
|
|
3910
3992
|
const topicKey = randomBytes(32);
|
|
3911
3993
|
const encrypted = encryptTopicKeyForUser(topicKey, this.ecdhPrivateKey, this.ecdhPublicKey);
|
|
3912
|
-
const tx = await this.keyManager.grantKeyAccess(topicId, this.
|
|
3994
|
+
const tx = await this.keyManager.grantKeyAccess(topicId, this.requireAddress(), encrypted);
|
|
3913
3995
|
await tx.wait();
|
|
3914
3996
|
this.topicKeys.set(topicId, topicKey);
|
|
3915
3997
|
return topicKey;
|
|
@@ -3926,9 +4008,9 @@ var Clawntenna = class _Clawntenna {
|
|
|
3926
4008
|
const isNoGrant = err instanceof Error && err.message.includes("No key grant found");
|
|
3927
4009
|
if (!isNoGrant) throw err;
|
|
3928
4010
|
const topic = await this.getTopic(topicId);
|
|
3929
|
-
if (!this.
|
|
4011
|
+
if (!this._signer || topic.owner.toLowerCase() !== this._address.toLowerCase()) {
|
|
3930
4012
|
throw new Error(
|
|
3931
|
-
`No key grant found for topic ${topicId}. Ask the topic owner to grant you access with: keys grant ${topicId} ${this.
|
|
4013
|
+
`No key grant found for topic ${topicId}. Ask the topic owner to grant you access with: keys grant ${topicId} ${this._address ?? "<your-address>"}`
|
|
3932
4014
|
);
|
|
3933
4015
|
}
|
|
3934
4016
|
return this.initializeTopicKey(topicId);
|
|
@@ -3938,7 +4020,7 @@ var Clawntenna = class _Clawntenna {
|
|
|
3938
4020
|
* Grant a user access to a private topic's symmetric key.
|
|
3939
4021
|
*/
|
|
3940
4022
|
async grantKeyAccess(topicId, userAddress, topicKey) {
|
|
3941
|
-
|
|
4023
|
+
this.requireSigner();
|
|
3942
4024
|
if (!this.ecdhPrivateKey) throw new Error("ECDH key not derived yet");
|
|
3943
4025
|
const hasKey = await this.keyManager.hasPublicKey(userAddress);
|
|
3944
4026
|
if (!hasKey) {
|
|
@@ -4023,7 +4105,7 @@ var Clawntenna = class _Clawntenna {
|
|
|
4023
4105
|
* Batch grant key access to multiple users at once (max 50).
|
|
4024
4106
|
*/
|
|
4025
4107
|
async batchGrantKeyAccess(topicId, users, topicKey) {
|
|
4026
|
-
|
|
4108
|
+
this.requireSigner();
|
|
4027
4109
|
if (!this.ecdhPrivateKey) throw new Error("ECDH key not derived yet");
|
|
4028
4110
|
const encryptedKeys = [];
|
|
4029
4111
|
for (const user of users) {
|
|
@@ -4037,14 +4119,14 @@ var Clawntenna = class _Clawntenna {
|
|
|
4037
4119
|
* Revoke a user's key access for a topic.
|
|
4038
4120
|
*/
|
|
4039
4121
|
async revokeKeyAccess(topicId, address) {
|
|
4040
|
-
|
|
4122
|
+
this.requireSigner();
|
|
4041
4123
|
return this.keyManager.revokeKeyAccess(topicId, address);
|
|
4042
4124
|
}
|
|
4043
4125
|
/**
|
|
4044
4126
|
* Rotate the key version for a topic. Existing grants become stale.
|
|
4045
4127
|
*/
|
|
4046
4128
|
async rotateKey(topicId) {
|
|
4047
|
-
|
|
4129
|
+
this.requireSigner();
|
|
4048
4130
|
return this.keyManager.rotateKey(topicId);
|
|
4049
4131
|
}
|
|
4050
4132
|
// ===== SCHEMAS =====
|
|
@@ -4052,21 +4134,21 @@ var Clawntenna = class _Clawntenna {
|
|
|
4052
4134
|
* Create a schema scoped to an application. Requires app admin role.
|
|
4053
4135
|
*/
|
|
4054
4136
|
async createAppSchema(appId, name, description, body) {
|
|
4055
|
-
|
|
4137
|
+
this.requireSigner();
|
|
4056
4138
|
return this.schemaRegistry.createAppSchema(appId, name, description, body);
|
|
4057
4139
|
}
|
|
4058
4140
|
/**
|
|
4059
4141
|
* Publish a new version of an existing schema.
|
|
4060
4142
|
*/
|
|
4061
4143
|
async publishSchemaVersion(schemaId, body) {
|
|
4062
|
-
|
|
4144
|
+
this.requireSigner();
|
|
4063
4145
|
return this.schemaRegistry.publishSchemaVersion(schemaId, body);
|
|
4064
4146
|
}
|
|
4065
4147
|
/**
|
|
4066
4148
|
* Deactivate a schema.
|
|
4067
4149
|
*/
|
|
4068
4150
|
async deactivateSchema(schemaId) {
|
|
4069
|
-
|
|
4151
|
+
this.requireSigner();
|
|
4070
4152
|
return this.schemaRegistry.deactivateSchema(schemaId);
|
|
4071
4153
|
}
|
|
4072
4154
|
/**
|
|
@@ -4118,14 +4200,14 @@ var Clawntenna = class _Clawntenna {
|
|
|
4118
4200
|
* Bind a schema version to a topic. Requires topic admin.
|
|
4119
4201
|
*/
|
|
4120
4202
|
async setTopicSchema(topicId, schemaId, version) {
|
|
4121
|
-
|
|
4203
|
+
this.requireSigner();
|
|
4122
4204
|
return this.schemaRegistry.setTopicSchema(topicId, schemaId, version);
|
|
4123
4205
|
}
|
|
4124
4206
|
/**
|
|
4125
4207
|
* Remove schema binding from a topic.
|
|
4126
4208
|
*/
|
|
4127
4209
|
async clearTopicSchema(topicId) {
|
|
4128
|
-
|
|
4210
|
+
this.requireSigner();
|
|
4129
4211
|
return this.schemaRegistry.clearTopicSchema(topicId);
|
|
4130
4212
|
}
|
|
4131
4213
|
// ===== AGENT IDENTITY (V5) =====
|
|
@@ -4134,14 +4216,14 @@ var Clawntenna = class _Clawntenna {
|
|
|
4134
4216
|
* Verifies ownership via ownerOf on the identity registry.
|
|
4135
4217
|
*/
|
|
4136
4218
|
async registerAgentIdentity(appId, tokenId) {
|
|
4137
|
-
|
|
4219
|
+
this.requireSigner();
|
|
4138
4220
|
return this.registry.registerAgentIdentity(appId, tokenId);
|
|
4139
4221
|
}
|
|
4140
4222
|
/**
|
|
4141
4223
|
* Clear your agent identity registration for an application (V5).
|
|
4142
4224
|
*/
|
|
4143
4225
|
async clearAgentIdentity(appId) {
|
|
4144
|
-
|
|
4226
|
+
this.requireSigner();
|
|
4145
4227
|
return this.registry.clearAgentIdentity(appId);
|
|
4146
4228
|
}
|
|
4147
4229
|
/**
|
|
@@ -4170,7 +4252,7 @@ var Clawntenna = class _Clawntenna {
|
|
|
4170
4252
|
* Optionally provide a URI for the agent's metadata.
|
|
4171
4253
|
*/
|
|
4172
4254
|
async registerAgent(agentURI) {
|
|
4173
|
-
|
|
4255
|
+
this.requireSigner();
|
|
4174
4256
|
const registry = this.requireIdentityRegistry();
|
|
4175
4257
|
const tx = agentURI ? await registry["register(string)"](agentURI) : await registry["register()"]();
|
|
4176
4258
|
const receipt = await tx.wait();
|
|
@@ -4193,7 +4275,7 @@ var Clawntenna = class _Clawntenna {
|
|
|
4193
4275
|
* Register as an agent with metadata entries.
|
|
4194
4276
|
*/
|
|
4195
4277
|
async registerAgentWithMetadata(agentURI, metadata) {
|
|
4196
|
-
|
|
4278
|
+
this.requireSigner();
|
|
4197
4279
|
const registry = this.requireIdentityRegistry();
|
|
4198
4280
|
const tx = await registry["register(string,(string,bytes)[])"](agentURI, metadata);
|
|
4199
4281
|
const receipt = await tx.wait();
|
|
@@ -4218,7 +4300,7 @@ var Clawntenna = class _Clawntenna {
|
|
|
4218
4300
|
*/
|
|
4219
4301
|
async isRegisteredAgent(address) {
|
|
4220
4302
|
const registry = this.requireIdentityRegistry();
|
|
4221
|
-
const addr = address ?? this.
|
|
4303
|
+
const addr = address ?? this._address;
|
|
4222
4304
|
if (!addr) throw new Error("Address required");
|
|
4223
4305
|
const balance = await registry.balanceOf(addr);
|
|
4224
4306
|
return balance > 0n;
|
|
@@ -4239,7 +4321,7 @@ var Clawntenna = class _Clawntenna {
|
|
|
4239
4321
|
* Set metadata for an agent.
|
|
4240
4322
|
*/
|
|
4241
4323
|
async setAgentMetadata(agentId, key, value) {
|
|
4242
|
-
|
|
4324
|
+
this.requireSigner();
|
|
4243
4325
|
const registry = this.requireIdentityRegistry();
|
|
4244
4326
|
return registry.setMetadata(agentId, key, value);
|
|
4245
4327
|
}
|
|
@@ -4255,7 +4337,7 @@ var Clawntenna = class _Clawntenna {
|
|
|
4255
4337
|
* Update the URI for an agent registration.
|
|
4256
4338
|
*/
|
|
4257
4339
|
async setAgentURI(agentId, newURI) {
|
|
4258
|
-
|
|
4340
|
+
this.requireSigner();
|
|
4259
4341
|
const registry = this.requireIdentityRegistry();
|
|
4260
4342
|
return registry.setAgentURI(agentId, newURI);
|
|
4261
4343
|
}
|
|
@@ -5594,7 +5676,7 @@ function decodeContractError(err) {
|
|
|
5594
5676
|
}
|
|
5595
5677
|
|
|
5596
5678
|
// src/cli/index.ts
|
|
5597
|
-
var VERSION = "0.
|
|
5679
|
+
var VERSION = "0.10.0";
|
|
5598
5680
|
var HELP = `
|
|
5599
5681
|
clawntenna v${VERSION}
|
|
5600
5682
|
On-chain encrypted messaging for AI agents
|