nara-sdk 1.0.87 → 1.0.89

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/index.ts CHANGED
@@ -124,7 +124,9 @@ export {
124
124
  getAgentMemory,
125
125
  getConfig as getAgentRegistryConfig,
126
126
  setBio,
127
+ makeSetBioIx,
127
128
  setMetadata,
129
+ makeSetMetadataIx,
128
130
  uploadMemory,
129
131
  closeBuffer as closeAgentBuffer,
130
132
  transferAgentAuthority,
@@ -134,6 +136,14 @@ export {
134
136
  makeLogActivityIx,
135
137
  makeLogActivityWithReferralIx,
136
138
  setReferral,
139
+ // Agent index
140
+ getAgentIndex,
141
+ listIndexesByAgent,
142
+ registerAgentIndex,
143
+ unregisterAgentIndex,
144
+ makeRegisterAgentIndexIx,
145
+ makeUnregisterAgentIndexIx,
146
+ computeIndexHash,
137
147
  // Twitter verification
138
148
  getAgentTwitter,
139
149
  getTweetVerify,
@@ -163,6 +173,8 @@ export {
163
173
  withdrawTwitterVerifyFees,
164
174
  type AgentRecord,
165
175
  type AgentInfo,
176
+ type AgentIndexInfo,
177
+ type ReverseIndexInfo,
166
178
  type AgentTwitterInfo,
167
179
  type TweetVerifyInfo,
168
180
  type TweetRecordInfo,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nara-sdk",
3
- "version": "1.0.87",
3
+ "version": "1.0.89",
4
4
  "description": "SDK for the Nara chain (Solana-compatible)",
5
5
  "module": "index.ts",
6
6
  "main": "index.ts",
@@ -14,6 +14,7 @@ import * as anchor from "@coral-xyz/anchor";
14
14
  import { Program, AnchorProvider, Wallet } from "@coral-xyz/anchor";
15
15
  import BN from "bn.js";
16
16
  import { getAssociatedTokenAddressSync, TOKEN_2022_PROGRAM_ID } from "@solana/spl-token";
17
+ import { createHash } from "node:crypto";
17
18
  import bs58 from "bs58";
18
19
  import type { NaraAgentRegistry } from "./idls/nara_agent_registry";
19
20
  import { DEFAULT_AGENT_REGISTRY_PROGRAM_ID } from "./constants";
@@ -56,6 +57,22 @@ export interface AgentInfo {
56
57
  metadata: string | null;
57
58
  }
58
59
 
60
+ export interface AgentIndexInfo {
61
+ /** Agent PDA that owns this index entry */
62
+ agent: PublicKey;
63
+ /** agent_id of the owning agent */
64
+ agentId: string;
65
+ createdAt: number;
66
+ }
67
+
68
+ export interface ReverseIndexInfo {
69
+ /** Agent PDA that owns this reverse-index entry */
70
+ agent: PublicKey;
71
+ /** Index string registered for the agent (UTF-8, up to 128 bytes) */
72
+ index: string;
73
+ createdAt: number;
74
+ }
75
+
59
76
  export interface AgentTwitterInfo {
60
77
  agentId: string;
61
78
  status: number;
@@ -181,6 +198,35 @@ function getTreasuryPda(programId: PublicKey): PublicKey {
181
198
  return pda;
182
199
  }
183
200
 
201
+ /**
202
+ * SHA-256 of an index string. The chain uses this 32-byte hash both as a PDA
203
+ * seed (lifting the 32-byte raw-seed limit) and as an integrity check against
204
+ * the supplied `index_str` (errors with `AgentIndexHashMismatch` on mismatch).
205
+ */
206
+ export function computeIndexHash(indexStr: string): Buffer {
207
+ return createHash("sha256").update(indexStr, "utf8").digest();
208
+ }
209
+
210
+ function getAgentIndexPda(programId: PublicKey, indexHash: Buffer | Uint8Array): PublicKey {
211
+ const [pda] = PublicKey.findProgramAddressSync(
212
+ [Buffer.from("agent_index"), Buffer.from(indexHash)],
213
+ programId
214
+ );
215
+ return pda;
216
+ }
217
+
218
+ function getReverseIndexPda(
219
+ programId: PublicKey,
220
+ agentPda: PublicKey,
221
+ indexHash: Buffer | Uint8Array
222
+ ): PublicKey {
223
+ const [pda] = PublicKey.findProgramAddressSync(
224
+ [Buffer.from("reverse_index"), agentPda.toBytes(), Buffer.from(indexHash)],
225
+ programId
226
+ );
227
+ return pda;
228
+ }
229
+
184
230
  function getTwitterPda(programId: PublicKey, agentPda: PublicKey): PublicKey {
185
231
  const [pda] = PublicKey.findProgramAddressSync(
186
232
  [Buffer.from("twitter"), agentPda.toBuffer()],
@@ -713,6 +759,23 @@ export async function deleteAgent(
713
759
 
714
760
  // ─── Bio & Metadata ─────────────────────────────────────────────
715
761
 
762
+ /**
763
+ * Build a setBio instruction without sending it.
764
+ */
765
+ export async function makeSetBioIx(
766
+ connection: Connection,
767
+ authority: PublicKey,
768
+ agentId: string,
769
+ bio: string,
770
+ options?: AgentRegistryOptions
771
+ ): Promise<TransactionInstruction> {
772
+ const program = createProgram(connection, Keypair.generate(), options?.programId);
773
+ return program.methods
774
+ .setBio(agentId, bio)
775
+ .accounts({ authority } as any)
776
+ .instruction();
777
+ }
778
+
716
779
  /**
717
780
  * Set or update the agent's bio.
718
781
  */
@@ -723,14 +786,27 @@ export async function setBio(
723
786
  bio: string,
724
787
  options?: AgentRegistryOptions
725
788
  ): Promise<string> {
726
- const program = createProgram(connection, wallet, options?.programId);
727
- const ix = await program.methods
728
- .setBio(agentId, bio)
729
- .accounts({ authority: wallet.publicKey } as any)
730
- .instruction();
789
+ const ix = await makeSetBioIx(connection, wallet.publicKey, agentId, bio, options);
731
790
  return sendTx(connection, wallet, [ix]);
732
791
  }
733
792
 
793
+ /**
794
+ * Build a setMetadata instruction without sending it.
795
+ */
796
+ export async function makeSetMetadataIx(
797
+ connection: Connection,
798
+ authority: PublicKey,
799
+ agentId: string,
800
+ data: string,
801
+ options?: AgentRegistryOptions
802
+ ): Promise<TransactionInstruction> {
803
+ const program = createProgram(connection, Keypair.generate(), options?.programId);
804
+ return program.methods
805
+ .setMetadata(agentId, data)
806
+ .accounts({ authority } as any)
807
+ .instruction();
808
+ }
809
+
734
810
  /**
735
811
  * Set or update the agent's metadata (typically JSON).
736
812
  */
@@ -741,11 +817,7 @@ export async function setMetadata(
741
817
  data: string,
742
818
  options?: AgentRegistryOptions
743
819
  ): Promise<string> {
744
- const program = createProgram(connection, wallet, options?.programId);
745
- const ix = await program.methods
746
- .setMetadata(agentId, data)
747
- .accounts({ authority: wallet.publicKey } as any)
748
- .instruction();
820
+ const ix = await makeSetMetadataIx(connection, wallet.publicKey, agentId, data, options);
749
821
  return sendTx(connection, wallet, [ix]);
750
822
  }
751
823
 
@@ -1087,6 +1159,186 @@ export async function setReferral(
1087
1159
  return sendTx(connection, wallet, [ix]);
1088
1160
  }
1089
1161
 
1162
+ // ─── Agent Index ────────────────────────────────────────────────
1163
+
1164
+ /**
1165
+ * Parse AgentIndex account data (bytemuck zero-copy layout).
1166
+ * Layout (after 8-byte discriminator):
1167
+ * 32 agent | 8 created_at | 4 agent_id_len | 4 _padding |
1168
+ * 32 agent_id | 32 _reserved
1169
+ */
1170
+ function parseAgentIndexData(data: Buffer | Uint8Array): AgentIndexInfo {
1171
+ const buf = Buffer.from(data);
1172
+ let offset = 8;
1173
+ const agent = new PublicKey(buf.subarray(offset, offset + 32)); offset += 32;
1174
+ const createdAt = Number(buf.readBigInt64LE(offset)); offset += 8;
1175
+ const agentIdLen = buf.readUInt32LE(offset); offset += 4;
1176
+ offset += 4; // _padding
1177
+ const agentId = buf.subarray(offset, offset + agentIdLen).toString("utf-8");
1178
+ return { agent, agentId, createdAt };
1179
+ }
1180
+
1181
+ /**
1182
+ * Parse ReverseIndex account data (bytemuck zero-copy layout).
1183
+ * Layout (after 8-byte discriminator):
1184
+ * 32 agent | 8 created_at | 4 index_len | 4 _padding |
1185
+ * 128 index | 32 _reserved
1186
+ */
1187
+ function parseReverseIndexData(data: Buffer | Uint8Array): ReverseIndexInfo {
1188
+ const buf = Buffer.from(data);
1189
+ let offset = 8;
1190
+ const agent = new PublicKey(buf.subarray(offset, offset + 32)); offset += 32;
1191
+ const createdAt = Number(buf.readBigInt64LE(offset)); offset += 8;
1192
+ const indexLen = buf.readUInt32LE(offset); offset += 4;
1193
+ offset += 4; // _padding
1194
+ const index = buf.subarray(offset, offset + indexLen).toString("utf-8");
1195
+ return { agent, index, createdAt };
1196
+ }
1197
+
1198
+ /**
1199
+ * Look up an agent_index entry by index string.
1200
+ * Returns null if no agent has claimed this index.
1201
+ */
1202
+ export async function getAgentIndex(
1203
+ connection: Connection,
1204
+ indexStr: string,
1205
+ options?: AgentRegistryOptions
1206
+ ): Promise<AgentIndexInfo | null> {
1207
+ const pid = new PublicKey(options?.programId ?? DEFAULT_AGENT_REGISTRY_PROGRAM_ID);
1208
+ const pda = getAgentIndexPda(pid, computeIndexHash(indexStr));
1209
+ const accountInfo = await connection.getAccountInfo(pda);
1210
+ if (!accountInfo) return null;
1211
+ return parseAgentIndexData(accountInfo.data);
1212
+ }
1213
+
1214
+ /** ReverseIndex account discriminator (from IDL). */
1215
+ const REVERSE_INDEX_DISCRIMINATOR = Buffer.from([130, 180, 241, 155, 193, 32, 173, 207]);
1216
+
1217
+ /**
1218
+ * List all index strings registered for a given agent.
1219
+ * Scans the program via `getProgramAccounts` with memcmp filters on the
1220
+ * ReverseIndex discriminator and the `agent` field (offset 8).
1221
+ */
1222
+ export async function listIndexesByAgent(
1223
+ connection: Connection,
1224
+ agentId: string,
1225
+ options?: AgentRegistryOptions
1226
+ ): Promise<ReverseIndexInfo[]> {
1227
+ const pid = new PublicKey(options?.programId ?? DEFAULT_AGENT_REGISTRY_PROGRAM_ID);
1228
+ const agentPda = getAgentPda(pid, agentId);
1229
+
1230
+ const accounts = await connection.getProgramAccounts(pid, {
1231
+ commitment: "confirmed",
1232
+ filters: [
1233
+ { memcmp: { offset: 0, bytes: bs58.encode(REVERSE_INDEX_DISCRIMINATOR) } },
1234
+ { memcmp: { offset: 8, bytes: agentPda.toBase58() } },
1235
+ ],
1236
+ });
1237
+
1238
+ return accounts.map(({ account }) => parseReverseIndexData(account.data));
1239
+ }
1240
+
1241
+ /**
1242
+ * Build a registerAgentIndex instruction without sending it.
1243
+ */
1244
+ export async function makeRegisterAgentIndexIx(
1245
+ connection: Connection,
1246
+ payer: PublicKey,
1247
+ authority: PublicKey,
1248
+ agentId: string,
1249
+ indexStr: string,
1250
+ options?: AgentRegistryOptions
1251
+ ): Promise<TransactionInstruction> {
1252
+ const program = createProgram(connection, Keypair.generate(), options?.programId);
1253
+ const agent = getAgentPda(program.programId, agentId);
1254
+ const indexHash = computeIndexHash(indexStr);
1255
+ return program.methods
1256
+ .registerAgentIndex(indexStr, Array.from(indexHash))
1257
+ .accounts({ payer, authority, agent } as any)
1258
+ .instruction();
1259
+ }
1260
+
1261
+ /**
1262
+ * Register a custom index string that points to the given agent.
1263
+ * The (index_str → agent_id) mapping can be looked up via getAgentIndex;
1264
+ * the reverse (agent → all index_strs) via listIndexesByAgent.
1265
+ */
1266
+ export async function registerAgentIndex(
1267
+ connection: Connection,
1268
+ wallet: Keypair,
1269
+ agentId: string,
1270
+ indexStr: string,
1271
+ options?: AgentRegistryOptions,
1272
+ payer?: Keypair
1273
+ ): Promise<{ signature: string; agentIndexPda: PublicKey; reverseIndexPda: PublicKey }> {
1274
+ const payerKp = payer ?? wallet;
1275
+ const program = createProgram(connection, payerKp, options?.programId);
1276
+ const agent = getAgentPda(program.programId, agentId);
1277
+ const indexHash = computeIndexHash(indexStr);
1278
+ const ix = await program.methods
1279
+ .registerAgentIndex(indexStr, Array.from(indexHash))
1280
+ .accounts({
1281
+ payer: payerKp.publicKey,
1282
+ authority: wallet.publicKey,
1283
+ agent,
1284
+ } as any)
1285
+ .instruction();
1286
+ const signers = payer && !payer.publicKey.equals(wallet.publicKey) ? [wallet] : [];
1287
+ const signature = await sendTx(connection, payerKp, [ix], signers);
1288
+ return {
1289
+ signature,
1290
+ agentIndexPda: getAgentIndexPda(program.programId, indexHash),
1291
+ reverseIndexPda: getReverseIndexPda(program.programId, agent, indexHash),
1292
+ };
1293
+ }
1294
+
1295
+ /**
1296
+ * Build an unregisterAgentIndex instruction without sending it.
1297
+ */
1298
+ export async function makeUnregisterAgentIndexIx(
1299
+ connection: Connection,
1300
+ rentDestination: PublicKey,
1301
+ authority: PublicKey,
1302
+ agentId: string,
1303
+ indexStr: string,
1304
+ options?: AgentRegistryOptions
1305
+ ): Promise<TransactionInstruction> {
1306
+ const program = createProgram(connection, Keypair.generate(), options?.programId);
1307
+ const agent = getAgentPda(program.programId, agentId);
1308
+ const indexHash = computeIndexHash(indexStr);
1309
+ return program.methods
1310
+ .unregisterAgentIndex(Array.from(indexHash))
1311
+ .accounts({ rentDestination, authority, agent } as any)
1312
+ .instruction();
1313
+ }
1314
+
1315
+ /**
1316
+ * Unregister a custom index string and reclaim rent.
1317
+ * The signing wallet must be the agent's authority.
1318
+ * @param rentDestination - Account to receive reclaimed rent (defaults to wallet pubkey).
1319
+ */
1320
+ export async function unregisterAgentIndex(
1321
+ connection: Connection,
1322
+ wallet: Keypair,
1323
+ agentId: string,
1324
+ indexStr: string,
1325
+ options?: AgentRegistryOptions,
1326
+ rentDestination?: PublicKey
1327
+ ): Promise<string> {
1328
+ const program = createProgram(connection, wallet, options?.programId);
1329
+ const agent = getAgentPda(program.programId, agentId);
1330
+ const indexHash = computeIndexHash(indexStr);
1331
+ const ix = await program.methods
1332
+ .unregisterAgentIndex(Array.from(indexHash))
1333
+ .accounts({
1334
+ rentDestination: rentDestination ?? wallet.publicKey,
1335
+ authority: wallet.publicKey,
1336
+ agent,
1337
+ } as any)
1338
+ .instruction();
1339
+ return sendTx(connection, wallet, [ix]);
1340
+ }
1341
+
1090
1342
  // ─── Admin functions ────────────────────────────────────────────
1091
1343
 
1092
1344
  /**
@@ -1959,6 +1959,123 @@
1959
1959
  }
1960
1960
  ]
1961
1961
  },
1962
+ {
1963
+ "name": "register_agent_index",
1964
+ "discriminator": [
1965
+ 193,
1966
+ 207,
1967
+ 223,
1968
+ 226,
1969
+ 130,
1970
+ 228,
1971
+ 161,
1972
+ 207
1973
+ ],
1974
+ "accounts": [
1975
+ {
1976
+ "name": "payer",
1977
+ "writable": true,
1978
+ "signer": true
1979
+ },
1980
+ {
1981
+ "name": "authority",
1982
+ "signer": true,
1983
+ "relations": [
1984
+ "agent"
1985
+ ]
1986
+ },
1987
+ {
1988
+ "name": "agent"
1989
+ },
1990
+ {
1991
+ "name": "agent_index",
1992
+ "docs": [
1993
+ "Forward-lookup PDA: keyed by hash(index_str). Globally unique per index_str."
1994
+ ],
1995
+ "writable": true,
1996
+ "pda": {
1997
+ "seeds": [
1998
+ {
1999
+ "kind": "const",
2000
+ "value": [
2001
+ 97,
2002
+ 103,
2003
+ 101,
2004
+ 110,
2005
+ 116,
2006
+ 95,
2007
+ 105,
2008
+ 110,
2009
+ 100,
2010
+ 101,
2011
+ 120
2012
+ ]
2013
+ },
2014
+ {
2015
+ "kind": "arg",
2016
+ "path": "index_hash"
2017
+ }
2018
+ ]
2019
+ }
2020
+ },
2021
+ {
2022
+ "name": "reverse_index",
2023
+ "docs": [
2024
+ "Reverse-lookup PDA: keyed by (agent, hash(index_str)). One per agent per index."
2025
+ ],
2026
+ "writable": true,
2027
+ "pda": {
2028
+ "seeds": [
2029
+ {
2030
+ "kind": "const",
2031
+ "value": [
2032
+ 114,
2033
+ 101,
2034
+ 118,
2035
+ 101,
2036
+ 114,
2037
+ 115,
2038
+ 101,
2039
+ 95,
2040
+ 105,
2041
+ 110,
2042
+ 100,
2043
+ 101,
2044
+ 120
2045
+ ]
2046
+ },
2047
+ {
2048
+ "kind": "account",
2049
+ "path": "agent"
2050
+ },
2051
+ {
2052
+ "kind": "arg",
2053
+ "path": "index_hash"
2054
+ }
2055
+ ]
2056
+ }
2057
+ },
2058
+ {
2059
+ "name": "system_program",
2060
+ "address": "11111111111111111111111111111111"
2061
+ }
2062
+ ],
2063
+ "args": [
2064
+ {
2065
+ "name": "index_str",
2066
+ "type": "string"
2067
+ },
2068
+ {
2069
+ "name": "index_hash",
2070
+ "type": {
2071
+ "array": [
2072
+ "u8",
2073
+ 32
2074
+ ]
2075
+ }
2076
+ }
2077
+ ]
2078
+ },
1962
2079
  {
1963
2080
  "name": "register_agent_with_referral",
1964
2081
  "discriminator": [
@@ -3540,6 +3657,115 @@
3540
3657
  }
3541
3658
  ]
3542
3659
  },
3660
+ {
3661
+ "name": "unregister_agent_index",
3662
+ "discriminator": [
3663
+ 245,
3664
+ 18,
3665
+ 46,
3666
+ 12,
3667
+ 147,
3668
+ 155,
3669
+ 203,
3670
+ 169
3671
+ ],
3672
+ "accounts": [
3673
+ {
3674
+ "name": "rent_destination",
3675
+ "writable": true
3676
+ },
3677
+ {
3678
+ "name": "authority",
3679
+ "signer": true,
3680
+ "relations": [
3681
+ "agent"
3682
+ ]
3683
+ },
3684
+ {
3685
+ "name": "agent"
3686
+ },
3687
+ {
3688
+ "name": "agent_index",
3689
+ "writable": true,
3690
+ "pda": {
3691
+ "seeds": [
3692
+ {
3693
+ "kind": "const",
3694
+ "value": [
3695
+ 97,
3696
+ 103,
3697
+ 101,
3698
+ 110,
3699
+ 116,
3700
+ 95,
3701
+ 105,
3702
+ 110,
3703
+ 100,
3704
+ 101,
3705
+ 120
3706
+ ]
3707
+ },
3708
+ {
3709
+ "kind": "arg",
3710
+ "path": "index_hash"
3711
+ }
3712
+ ]
3713
+ }
3714
+ },
3715
+ {
3716
+ "name": "reverse_index",
3717
+ "docs": [
3718
+ "Reverse-lookup PDA, closed alongside the main index entry."
3719
+ ],
3720
+ "writable": true,
3721
+ "pda": {
3722
+ "seeds": [
3723
+ {
3724
+ "kind": "const",
3725
+ "value": [
3726
+ 114,
3727
+ 101,
3728
+ 118,
3729
+ 101,
3730
+ 114,
3731
+ 115,
3732
+ 101,
3733
+ 95,
3734
+ 105,
3735
+ 110,
3736
+ 100,
3737
+ 101,
3738
+ 120
3739
+ ]
3740
+ },
3741
+ {
3742
+ "kind": "account",
3743
+ "path": "agent"
3744
+ },
3745
+ {
3746
+ "kind": "arg",
3747
+ "path": "index_hash"
3748
+ }
3749
+ ]
3750
+ }
3751
+ },
3752
+ {
3753
+ "name": "system_program",
3754
+ "address": "11111111111111111111111111111111"
3755
+ }
3756
+ ],
3757
+ "args": [
3758
+ {
3759
+ "name": "index_hash",
3760
+ "type": {
3761
+ "array": [
3762
+ "u8",
3763
+ 32
3764
+ ]
3765
+ }
3766
+ }
3767
+ ]
3768
+ },
3543
3769
  {
3544
3770
  "name": "update_activity_config",
3545
3771
  "discriminator": [
@@ -4502,6 +4728,19 @@
4502
4728
  }
4503
4729
  ],
4504
4730
  "accounts": [
4731
+ {
4732
+ "name": "AgentIndex",
4733
+ "discriminator": [
4734
+ 241,
4735
+ 154,
4736
+ 35,
4737
+ 103,
4738
+ 180,
4739
+ 141,
4740
+ 49,
4741
+ 179
4742
+ ]
4743
+ },
4505
4744
  {
4506
4745
  "name": "AgentState",
4507
4746
  "discriminator": [
@@ -4554,6 +4793,19 @@
4554
4793
  63
4555
4794
  ]
4556
4795
  },
4796
+ {
4797
+ "name": "ReverseIndex",
4798
+ "discriminator": [
4799
+ 130,
4800
+ 180,
4801
+ 241,
4802
+ 155,
4803
+ 193,
4804
+ 32,
4805
+ 173,
4806
+ 207
4807
+ ]
4808
+ },
4557
4809
  {
4558
4810
  "name": "TweetRecord",
4559
4811
  "discriminator": [
@@ -4875,6 +5127,26 @@
4875
5127
  "code": 6047,
4876
5128
  "name": "TwitterNotRejected",
4877
5129
  "msg": "Twitter binding is not in rejected status"
5130
+ },
5131
+ {
5132
+ "code": 6048,
5133
+ "name": "AgentIndexEmpty",
5134
+ "msg": "Agent index string is empty"
5135
+ },
5136
+ {
5137
+ "code": 6049,
5138
+ "name": "AgentIndexTooLong",
5139
+ "msg": "Agent index string too long"
5140
+ },
5141
+ {
5142
+ "code": 6050,
5143
+ "name": "AgentIndexMismatch",
5144
+ "msg": "Agent index does not belong to the given agent"
5145
+ },
5146
+ {
5147
+ "code": 6051,
5148
+ "name": "AgentIndexHashMismatch",
5149
+ "msg": "Agent index hash does not match the provided index string"
4878
5150
  }
4879
5151
  ],
4880
5152
  "types": [
@@ -4922,6 +5194,69 @@
4922
5194
  ]
4923
5195
  }
4924
5196
  },
5197
+ {
5198
+ "name": "AgentIndex",
5199
+ "docs": [
5200
+ "Per-agent custom index entry. Lets an agent claim arbitrary index strings",
5201
+ "that point back to its agent_id.",
5202
+ "Seeds: [SEED_AGENT_INDEX, index_str.as_bytes()]"
5203
+ ],
5204
+ "serialization": "bytemuck",
5205
+ "repr": {
5206
+ "kind": "c"
5207
+ },
5208
+ "type": {
5209
+ "kind": "struct",
5210
+ "fields": [
5211
+ {
5212
+ "name": "agent",
5213
+ "docs": [
5214
+ "The AgentState PDA that owns this index entry"
5215
+ ],
5216
+ "type": "pubkey"
5217
+ },
5218
+ {
5219
+ "name": "created_at",
5220
+ "docs": [
5221
+ "Unix timestamp when this index was registered"
5222
+ ],
5223
+ "type": "i64"
5224
+ },
5225
+ {
5226
+ "name": "agent_id_len",
5227
+ "docs": [
5228
+ "Length of the agent_id stored below"
5229
+ ],
5230
+ "type": "u32"
5231
+ },
5232
+ {
5233
+ "name": "_padding",
5234
+ "type": "u32"
5235
+ },
5236
+ {
5237
+ "name": "agent_id",
5238
+ "docs": [
5239
+ "agent_id of the owning agent (zero-padded)"
5240
+ ],
5241
+ "type": {
5242
+ "array": [
5243
+ "u8",
5244
+ 32
5245
+ ]
5246
+ }
5247
+ },
5248
+ {
5249
+ "name": "_reserved",
5250
+ "type": {
5251
+ "array": [
5252
+ "u8",
5253
+ 32
5254
+ ]
5255
+ }
5256
+ }
5257
+ ]
5258
+ }
5259
+ },
4925
5260
  {
4926
5261
  "name": "AgentState",
4927
5262
  "docs": [
@@ -5253,6 +5588,71 @@
5253
5588
  ]
5254
5589
  }
5255
5590
  },
5591
+ {
5592
+ "name": "ReverseIndex",
5593
+ "docs": [
5594
+ "Reverse-lookup record: given an agent, list all index strings registered for it.",
5595
+ "Seeds: [SEED_REVERSE_INDEX, agent_pda.as_ref(), index_str.as_bytes()]",
5596
+ "",
5597
+ "Clients can fetch all reverse_index entries for a given agent via",
5598
+ "`getProgramAccounts` with a memcmp filter on the `agent` field."
5599
+ ],
5600
+ "serialization": "bytemuck",
5601
+ "repr": {
5602
+ "kind": "c"
5603
+ },
5604
+ "type": {
5605
+ "kind": "struct",
5606
+ "fields": [
5607
+ {
5608
+ "name": "agent",
5609
+ "docs": [
5610
+ "The AgentState PDA that owns this reverse-index entry"
5611
+ ],
5612
+ "type": "pubkey"
5613
+ },
5614
+ {
5615
+ "name": "created_at",
5616
+ "docs": [
5617
+ "Unix timestamp when this entry was created"
5618
+ ],
5619
+ "type": "i64"
5620
+ },
5621
+ {
5622
+ "name": "index_len",
5623
+ "docs": [
5624
+ "Length of the index string stored below"
5625
+ ],
5626
+ "type": "u32"
5627
+ },
5628
+ {
5629
+ "name": "_padding",
5630
+ "type": "u32"
5631
+ },
5632
+ {
5633
+ "name": "index",
5634
+ "docs": [
5635
+ "Index string (zero-padded), up to 128 bytes"
5636
+ ],
5637
+ "type": {
5638
+ "array": [
5639
+ "u8",
5640
+ 128
5641
+ ]
5642
+ }
5643
+ },
5644
+ {
5645
+ "name": "_reserved",
5646
+ "type": {
5647
+ "array": [
5648
+ "u8",
5649
+ 32
5650
+ ]
5651
+ }
5652
+ }
5653
+ ]
5654
+ }
5655
+ },
5256
5656
  {
5257
5657
  "name": "TweetRecord",
5258
5658
  "docs": [
@@ -1965,6 +1965,123 @@ export type NaraAgentRegistry = {
1965
1965
  }
1966
1966
  ]
1967
1967
  },
1968
+ {
1969
+ "name": "registerAgentIndex",
1970
+ "discriminator": [
1971
+ 193,
1972
+ 207,
1973
+ 223,
1974
+ 226,
1975
+ 130,
1976
+ 228,
1977
+ 161,
1978
+ 207
1979
+ ],
1980
+ "accounts": [
1981
+ {
1982
+ "name": "payer",
1983
+ "writable": true,
1984
+ "signer": true
1985
+ },
1986
+ {
1987
+ "name": "authority",
1988
+ "signer": true,
1989
+ "relations": [
1990
+ "agent"
1991
+ ]
1992
+ },
1993
+ {
1994
+ "name": "agent"
1995
+ },
1996
+ {
1997
+ "name": "agentIndex",
1998
+ "docs": [
1999
+ "Forward-lookup PDA: keyed by hash(index_str). Globally unique per index_str."
2000
+ ],
2001
+ "writable": true,
2002
+ "pda": {
2003
+ "seeds": [
2004
+ {
2005
+ "kind": "const",
2006
+ "value": [
2007
+ 97,
2008
+ 103,
2009
+ 101,
2010
+ 110,
2011
+ 116,
2012
+ 95,
2013
+ 105,
2014
+ 110,
2015
+ 100,
2016
+ 101,
2017
+ 120
2018
+ ]
2019
+ },
2020
+ {
2021
+ "kind": "arg",
2022
+ "path": "indexHash"
2023
+ }
2024
+ ]
2025
+ }
2026
+ },
2027
+ {
2028
+ "name": "reverseIndex",
2029
+ "docs": [
2030
+ "Reverse-lookup PDA: keyed by (agent, hash(index_str)). One per agent per index."
2031
+ ],
2032
+ "writable": true,
2033
+ "pda": {
2034
+ "seeds": [
2035
+ {
2036
+ "kind": "const",
2037
+ "value": [
2038
+ 114,
2039
+ 101,
2040
+ 118,
2041
+ 101,
2042
+ 114,
2043
+ 115,
2044
+ 101,
2045
+ 95,
2046
+ 105,
2047
+ 110,
2048
+ 100,
2049
+ 101,
2050
+ 120
2051
+ ]
2052
+ },
2053
+ {
2054
+ "kind": "account",
2055
+ "path": "agent"
2056
+ },
2057
+ {
2058
+ "kind": "arg",
2059
+ "path": "indexHash"
2060
+ }
2061
+ ]
2062
+ }
2063
+ },
2064
+ {
2065
+ "name": "systemProgram",
2066
+ "address": "11111111111111111111111111111111"
2067
+ }
2068
+ ],
2069
+ "args": [
2070
+ {
2071
+ "name": "indexStr",
2072
+ "type": "string"
2073
+ },
2074
+ {
2075
+ "name": "indexHash",
2076
+ "type": {
2077
+ "array": [
2078
+ "u8",
2079
+ 32
2080
+ ]
2081
+ }
2082
+ }
2083
+ ]
2084
+ },
1968
2085
  {
1969
2086
  "name": "registerAgentWithReferral",
1970
2087
  "discriminator": [
@@ -3546,6 +3663,115 @@ export type NaraAgentRegistry = {
3546
3663
  }
3547
3664
  ]
3548
3665
  },
3666
+ {
3667
+ "name": "unregisterAgentIndex",
3668
+ "discriminator": [
3669
+ 245,
3670
+ 18,
3671
+ 46,
3672
+ 12,
3673
+ 147,
3674
+ 155,
3675
+ 203,
3676
+ 169
3677
+ ],
3678
+ "accounts": [
3679
+ {
3680
+ "name": "rentDestination",
3681
+ "writable": true
3682
+ },
3683
+ {
3684
+ "name": "authority",
3685
+ "signer": true,
3686
+ "relations": [
3687
+ "agent"
3688
+ ]
3689
+ },
3690
+ {
3691
+ "name": "agent"
3692
+ },
3693
+ {
3694
+ "name": "agentIndex",
3695
+ "writable": true,
3696
+ "pda": {
3697
+ "seeds": [
3698
+ {
3699
+ "kind": "const",
3700
+ "value": [
3701
+ 97,
3702
+ 103,
3703
+ 101,
3704
+ 110,
3705
+ 116,
3706
+ 95,
3707
+ 105,
3708
+ 110,
3709
+ 100,
3710
+ 101,
3711
+ 120
3712
+ ]
3713
+ },
3714
+ {
3715
+ "kind": "arg",
3716
+ "path": "indexHash"
3717
+ }
3718
+ ]
3719
+ }
3720
+ },
3721
+ {
3722
+ "name": "reverseIndex",
3723
+ "docs": [
3724
+ "Reverse-lookup PDA, closed alongside the main index entry."
3725
+ ],
3726
+ "writable": true,
3727
+ "pda": {
3728
+ "seeds": [
3729
+ {
3730
+ "kind": "const",
3731
+ "value": [
3732
+ 114,
3733
+ 101,
3734
+ 118,
3735
+ 101,
3736
+ 114,
3737
+ 115,
3738
+ 101,
3739
+ 95,
3740
+ 105,
3741
+ 110,
3742
+ 100,
3743
+ 101,
3744
+ 120
3745
+ ]
3746
+ },
3747
+ {
3748
+ "kind": "account",
3749
+ "path": "agent"
3750
+ },
3751
+ {
3752
+ "kind": "arg",
3753
+ "path": "indexHash"
3754
+ }
3755
+ ]
3756
+ }
3757
+ },
3758
+ {
3759
+ "name": "systemProgram",
3760
+ "address": "11111111111111111111111111111111"
3761
+ }
3762
+ ],
3763
+ "args": [
3764
+ {
3765
+ "name": "indexHash",
3766
+ "type": {
3767
+ "array": [
3768
+ "u8",
3769
+ 32
3770
+ ]
3771
+ }
3772
+ }
3773
+ ]
3774
+ },
3549
3775
  {
3550
3776
  "name": "updateActivityConfig",
3551
3777
  "discriminator": [
@@ -4508,6 +4734,19 @@ export type NaraAgentRegistry = {
4508
4734
  }
4509
4735
  ],
4510
4736
  "accounts": [
4737
+ {
4738
+ "name": "agentIndex",
4739
+ "discriminator": [
4740
+ 241,
4741
+ 154,
4742
+ 35,
4743
+ 103,
4744
+ 180,
4745
+ 141,
4746
+ 49,
4747
+ 179
4748
+ ]
4749
+ },
4511
4750
  {
4512
4751
  "name": "agentState",
4513
4752
  "discriminator": [
@@ -4560,6 +4799,19 @@ export type NaraAgentRegistry = {
4560
4799
  63
4561
4800
  ]
4562
4801
  },
4802
+ {
4803
+ "name": "reverseIndex",
4804
+ "discriminator": [
4805
+ 130,
4806
+ 180,
4807
+ 241,
4808
+ 155,
4809
+ 193,
4810
+ 32,
4811
+ 173,
4812
+ 207
4813
+ ]
4814
+ },
4563
4815
  {
4564
4816
  "name": "tweetRecord",
4565
4817
  "discriminator": [
@@ -4881,6 +5133,26 @@ export type NaraAgentRegistry = {
4881
5133
  "code": 6047,
4882
5134
  "name": "twitterNotRejected",
4883
5135
  "msg": "Twitter binding is not in rejected status"
5136
+ },
5137
+ {
5138
+ "code": 6048,
5139
+ "name": "agentIndexEmpty",
5140
+ "msg": "Agent index string is empty"
5141
+ },
5142
+ {
5143
+ "code": 6049,
5144
+ "name": "agentIndexTooLong",
5145
+ "msg": "Agent index string too long"
5146
+ },
5147
+ {
5148
+ "code": 6050,
5149
+ "name": "agentIndexMismatch",
5150
+ "msg": "Agent index does not belong to the given agent"
5151
+ },
5152
+ {
5153
+ "code": 6051,
5154
+ "name": "agentIndexHashMismatch",
5155
+ "msg": "Agent index hash does not match the provided index string"
4884
5156
  }
4885
5157
  ],
4886
5158
  "types": [
@@ -4928,6 +5200,69 @@ export type NaraAgentRegistry = {
4928
5200
  ]
4929
5201
  }
4930
5202
  },
5203
+ {
5204
+ "name": "agentIndex",
5205
+ "docs": [
5206
+ "Per-agent custom index entry. Lets an agent claim arbitrary index strings",
5207
+ "that point back to its agent_id.",
5208
+ "Seeds: [SEED_AGENT_INDEX, index_str.as_bytes()]"
5209
+ ],
5210
+ "serialization": "bytemuck",
5211
+ "repr": {
5212
+ "kind": "c"
5213
+ },
5214
+ "type": {
5215
+ "kind": "struct",
5216
+ "fields": [
5217
+ {
5218
+ "name": "agent",
5219
+ "docs": [
5220
+ "The AgentState PDA that owns this index entry"
5221
+ ],
5222
+ "type": "pubkey"
5223
+ },
5224
+ {
5225
+ "name": "createdAt",
5226
+ "docs": [
5227
+ "Unix timestamp when this index was registered"
5228
+ ],
5229
+ "type": "i64"
5230
+ },
5231
+ {
5232
+ "name": "agentIdLen",
5233
+ "docs": [
5234
+ "Length of the agent_id stored below"
5235
+ ],
5236
+ "type": "u32"
5237
+ },
5238
+ {
5239
+ "name": "padding",
5240
+ "type": "u32"
5241
+ },
5242
+ {
5243
+ "name": "agentId",
5244
+ "docs": [
5245
+ "agent_id of the owning agent (zero-padded)"
5246
+ ],
5247
+ "type": {
5248
+ "array": [
5249
+ "u8",
5250
+ 32
5251
+ ]
5252
+ }
5253
+ },
5254
+ {
5255
+ "name": "reserved",
5256
+ "type": {
5257
+ "array": [
5258
+ "u8",
5259
+ 32
5260
+ ]
5261
+ }
5262
+ }
5263
+ ]
5264
+ }
5265
+ },
4931
5266
  {
4932
5267
  "name": "agentState",
4933
5268
  "docs": [
@@ -5259,6 +5594,71 @@ export type NaraAgentRegistry = {
5259
5594
  ]
5260
5595
  }
5261
5596
  },
5597
+ {
5598
+ "name": "reverseIndex",
5599
+ "docs": [
5600
+ "Reverse-lookup record: given an agent, list all index strings registered for it.",
5601
+ "Seeds: [SEED_REVERSE_INDEX, agent_pda.as_ref(), index_str.as_bytes()]",
5602
+ "",
5603
+ "Clients can fetch all reverse_index entries for a given agent via",
5604
+ "`getProgramAccounts` with a memcmp filter on the `agent` field."
5605
+ ],
5606
+ "serialization": "bytemuck",
5607
+ "repr": {
5608
+ "kind": "c"
5609
+ },
5610
+ "type": {
5611
+ "kind": "struct",
5612
+ "fields": [
5613
+ {
5614
+ "name": "agent",
5615
+ "docs": [
5616
+ "The AgentState PDA that owns this reverse-index entry"
5617
+ ],
5618
+ "type": "pubkey"
5619
+ },
5620
+ {
5621
+ "name": "createdAt",
5622
+ "docs": [
5623
+ "Unix timestamp when this entry was created"
5624
+ ],
5625
+ "type": "i64"
5626
+ },
5627
+ {
5628
+ "name": "indexLen",
5629
+ "docs": [
5630
+ "Length of the index string stored below"
5631
+ ],
5632
+ "type": "u32"
5633
+ },
5634
+ {
5635
+ "name": "padding",
5636
+ "type": "u32"
5637
+ },
5638
+ {
5639
+ "name": "index",
5640
+ "docs": [
5641
+ "Index string (zero-padded), up to 128 bytes"
5642
+ ],
5643
+ "type": {
5644
+ "array": [
5645
+ "u8",
5646
+ 128
5647
+ ]
5648
+ }
5649
+ },
5650
+ {
5651
+ "name": "reserved",
5652
+ "type": {
5653
+ "array": [
5654
+ "u8",
5655
+ 32
5656
+ ]
5657
+ }
5658
+ }
5659
+ ]
5660
+ }
5661
+ },
5262
5662
  {
5263
5663
  "name": "tweetRecord",
5264
5664
  "docs": [