nara-sdk 1.0.32 → 1.0.34
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 +3 -0
- package/package.json +1 -1
- package/src/agent_registry.ts +171 -19
- package/src/idls/nara_agent_registry.json +451 -32
- package/src/idls/nara_agent_registry.ts +451 -32
- package/src/idls/nara_quest.json +4 -29
- package/src/idls/nara_quest.ts +4 -29
- package/src/idls/nara_skills_hub.json +23 -29
- package/src/idls/nara_skills_hub.ts +24 -30
- package/src/quest.ts +3 -3
- package/src/skills.ts +105 -53
- package/src/zk/answer_proof.wasm +0 -0
- package/src/zk/answer_proof_final.zkey +0 -0
package/index.ts
CHANGED
|
@@ -45,6 +45,7 @@ export {
|
|
|
45
45
|
transferAuthority,
|
|
46
46
|
closeBuffer,
|
|
47
47
|
deleteSkill,
|
|
48
|
+
getConfig as getSkillsConfig,
|
|
48
49
|
initConfig as initSkillsConfig,
|
|
49
50
|
updateAdmin as updateSkillsAdmin,
|
|
50
51
|
updateFeeRecipient as updateSkillsFeeRecipient,
|
|
@@ -96,6 +97,8 @@ export {
|
|
|
96
97
|
updateFeeRecipient,
|
|
97
98
|
updateRegisterFee,
|
|
98
99
|
updatePointsConfig,
|
|
100
|
+
setReferral,
|
|
101
|
+
updateReferralConfig,
|
|
99
102
|
type AgentRecord,
|
|
100
103
|
type AgentInfo,
|
|
101
104
|
type MemoryMode,
|
package/package.json
CHANGED
package/src/agent_registry.ts
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
} from "@solana/web3.js";
|
|
13
13
|
import * as anchor from "@coral-xyz/anchor";
|
|
14
14
|
import { Program, AnchorProvider, Wallet } from "@coral-xyz/anchor";
|
|
15
|
+
import { getAssociatedTokenAddressSync, TOKEN_2022_PROGRAM_ID } from "@solana/spl-token";
|
|
15
16
|
import type { NaraAgentRegistry } from "./idls/nara_agent_registry";
|
|
16
17
|
import { DEFAULT_AGENT_REGISTRY_PROGRAM_ID } from "./constants";
|
|
17
18
|
|
|
@@ -74,8 +75,8 @@ export interface AgentRecord {
|
|
|
74
75
|
memory: PublicKey;
|
|
75
76
|
/** 0 = no memory, increments on each upload */
|
|
76
77
|
version: number;
|
|
77
|
-
/**
|
|
78
|
-
|
|
78
|
+
/** Referral agent ID, null if none */
|
|
79
|
+
referralId: string | null;
|
|
79
80
|
createdAt: number;
|
|
80
81
|
updatedAt: number;
|
|
81
82
|
}
|
|
@@ -149,6 +150,45 @@ function getMetaPda(programId: PublicKey, agentPubkey: PublicKey): PublicKey {
|
|
|
149
150
|
return pda;
|
|
150
151
|
}
|
|
151
152
|
|
|
153
|
+
function getPointMintPda(programId: PublicKey): PublicKey {
|
|
154
|
+
const [pda] = PublicKey.findProgramAddressSync(
|
|
155
|
+
[Buffer.from("point_mint")],
|
|
156
|
+
programId
|
|
157
|
+
);
|
|
158
|
+
return pda;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function getMintAuthorityPda(programId: PublicKey): PublicKey {
|
|
162
|
+
const [pda] = PublicKey.findProgramAddressSync(
|
|
163
|
+
[Buffer.from("mint_authority")],
|
|
164
|
+
programId
|
|
165
|
+
);
|
|
166
|
+
return pda;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Build referral-related accounts for register_agent / log_activity.
|
|
171
|
+
* Returns the referral agent PDA, its authority, and the authority's ATA for point_mint.
|
|
172
|
+
*/
|
|
173
|
+
async function resolveReferralAccounts(
|
|
174
|
+
connection: Connection,
|
|
175
|
+
referralAgentId: string,
|
|
176
|
+
programId: PublicKey,
|
|
177
|
+
pointMint: PublicKey
|
|
178
|
+
): Promise<{ referralAgent: PublicKey; referralAuthority: PublicKey; referralPointAccount: PublicKey }> {
|
|
179
|
+
const referralAgent = getAgentPda(programId, referralAgentId);
|
|
180
|
+
const accountInfo = await connection.getAccountInfo(referralAgent);
|
|
181
|
+
if (!accountInfo) {
|
|
182
|
+
throw new Error(`Referral agent "${referralAgentId}" not found`);
|
|
183
|
+
}
|
|
184
|
+
// Authority is first 32 bytes after 8-byte discriminator
|
|
185
|
+
const referralAuthority = new PublicKey(accountInfo.data.subarray(8, 40));
|
|
186
|
+
const referralPointAccount = getAssociatedTokenAddressSync(
|
|
187
|
+
pointMint, referralAuthority, true, TOKEN_2022_PROGRAM_ID
|
|
188
|
+
);
|
|
189
|
+
return { referralAgent, referralAuthority, referralPointAccount };
|
|
190
|
+
}
|
|
191
|
+
|
|
152
192
|
/** Bio/Metadata header: 8-byte discriminator + 64-byte _reserved */
|
|
153
193
|
const BIO_META_HEADER_SIZE = 72;
|
|
154
194
|
|
|
@@ -156,8 +196,9 @@ const BIO_META_HEADER_SIZE = 72;
|
|
|
156
196
|
* Parse AgentRecord from raw account data (bytemuck zero-copy layout).
|
|
157
197
|
* Layout (after 8-byte discriminator):
|
|
158
198
|
* 32 authority | 32 pending_buffer | 32 memory |
|
|
159
|
-
* 8 created_at | 8 updated_at |
|
|
160
|
-
* 4 version | 4 agent_id_len | 32 agent_id |
|
|
199
|
+
* 8 created_at | 8 updated_at |
|
|
200
|
+
* 4 version | 4 agent_id_len | 32 agent_id |
|
|
201
|
+
* 4 referral_id_len | 32 referral_id | 4 _padding | 64 _reserved
|
|
161
202
|
*/
|
|
162
203
|
function parseAgentRecordData(data: Buffer | Uint8Array): AgentRecord {
|
|
163
204
|
const buf = Buffer.from(data);
|
|
@@ -169,11 +210,15 @@ function parseAgentRecordData(data: Buffer | Uint8Array): AgentRecord {
|
|
|
169
210
|
|
|
170
211
|
const createdAt = Number(buf.readBigInt64LE(offset)); offset += 8;
|
|
171
212
|
const updatedAt = Number(buf.readBigInt64LE(offset)); offset += 8;
|
|
172
|
-
const points = Number(buf.readBigUInt64LE(offset)); offset += 8;
|
|
173
213
|
|
|
174
214
|
const version = buf.readUInt32LE(offset); offset += 4;
|
|
175
215
|
const agentIdLen = buf.readUInt32LE(offset); offset += 4;
|
|
176
|
-
const agentId = buf.subarray(offset, offset + agentIdLen).toString("utf-8");
|
|
216
|
+
const agentId = buf.subarray(offset, offset + agentIdLen).toString("utf-8"); offset += 32;
|
|
217
|
+
|
|
218
|
+
const referralIdLen = buf.readUInt32LE(offset); offset += 4;
|
|
219
|
+
const referralId = referralIdLen > 0
|
|
220
|
+
? buf.subarray(offset, offset + referralIdLen).toString("utf-8")
|
|
221
|
+
: null;
|
|
177
222
|
|
|
178
223
|
return {
|
|
179
224
|
authority,
|
|
@@ -181,7 +226,7 @@ function parseAgentRecordData(data: Buffer | Uint8Array): AgentRecord {
|
|
|
181
226
|
pendingBuffer: pendingBuffer.equals(PublicKey.default) ? null : pendingBuffer,
|
|
182
227
|
memory,
|
|
183
228
|
version,
|
|
184
|
-
|
|
229
|
+
referralId,
|
|
185
230
|
createdAt,
|
|
186
231
|
updatedAt,
|
|
187
232
|
};
|
|
@@ -285,10 +330,14 @@ export async function getConfig(
|
|
|
285
330
|
options?: AgentRegistryOptions
|
|
286
331
|
): Promise<{
|
|
287
332
|
admin: PublicKey;
|
|
288
|
-
registerFee: number;
|
|
289
333
|
feeRecipient: PublicKey;
|
|
334
|
+
pointMint: PublicKey;
|
|
335
|
+
registerFee: number;
|
|
290
336
|
pointsSelf: number;
|
|
291
337
|
pointsReferral: number;
|
|
338
|
+
referralRegisterFee: number;
|
|
339
|
+
referralFeeShare: number;
|
|
340
|
+
referralRegisterPoints: number;
|
|
292
341
|
}> {
|
|
293
342
|
const pid = new PublicKey(options?.programId ?? DEFAULT_AGENT_REGISTRY_PROGRAM_ID);
|
|
294
343
|
const configPda = getConfigPda(pid);
|
|
@@ -300,10 +349,14 @@ export async function getConfig(
|
|
|
300
349
|
let offset = 8; // skip discriminator
|
|
301
350
|
const admin = new PublicKey(buf.subarray(offset, offset + 32)); offset += 32;
|
|
302
351
|
const feeRecipient = new PublicKey(buf.subarray(offset, offset + 32)); offset += 32;
|
|
352
|
+
const pointMint = new PublicKey(buf.subarray(offset, offset + 32)); offset += 32;
|
|
303
353
|
const registerFee = Number(buf.readBigUInt64LE(offset)); offset += 8;
|
|
304
354
|
const pointsSelf = Number(buf.readBigUInt64LE(offset)); offset += 8;
|
|
305
|
-
const pointsReferral = Number(buf.readBigUInt64LE(offset));
|
|
306
|
-
|
|
355
|
+
const pointsReferral = Number(buf.readBigUInt64LE(offset)); offset += 8;
|
|
356
|
+
const referralRegisterFee = Number(buf.readBigUInt64LE(offset)); offset += 8;
|
|
357
|
+
const referralFeeShare = Number(buf.readBigUInt64LE(offset)); offset += 8;
|
|
358
|
+
const referralRegisterPoints = Number(buf.readBigUInt64LE(offset));
|
|
359
|
+
return { admin, feeRecipient, pointMint, registerFee, pointsSelf, pointsReferral, referralRegisterFee, referralFeeShare, referralRegisterPoints };
|
|
307
360
|
}
|
|
308
361
|
|
|
309
362
|
// ─── Agent CRUD ─────────────────────────────────────────────────
|
|
@@ -315,20 +368,35 @@ export async function registerAgent(
|
|
|
315
368
|
connection: Connection,
|
|
316
369
|
wallet: Keypair,
|
|
317
370
|
agentId: string,
|
|
318
|
-
options?: AgentRegistryOptions
|
|
371
|
+
options?: AgentRegistryOptions,
|
|
372
|
+
referralAgentId?: string
|
|
319
373
|
): Promise<{ signature: string; agentPubkey: PublicKey }> {
|
|
320
374
|
if (/[A-Z]/.test(agentId)) {
|
|
321
375
|
throw new Error(`Agent ID must not contain uppercase letters: "${agentId}"`);
|
|
322
376
|
}
|
|
323
377
|
const program = createProgram(connection, wallet, options?.programId);
|
|
324
|
-
const
|
|
325
|
-
const
|
|
378
|
+
const config = await getConfig(connection, options);
|
|
379
|
+
const pointMint = getPointMintPda(program.programId);
|
|
380
|
+
|
|
381
|
+
let referralAccounts: {
|
|
382
|
+
referralAgent: PublicKey | null;
|
|
383
|
+
referralAuthority: PublicKey | null;
|
|
384
|
+
referralPointAccount: PublicKey | null;
|
|
385
|
+
} = { referralAgent: null, referralAuthority: null, referralPointAccount: null };
|
|
386
|
+
|
|
387
|
+
if (referralAgentId) {
|
|
388
|
+
const resolved = await resolveReferralAccounts(
|
|
389
|
+
connection, referralAgentId, program.programId, pointMint
|
|
390
|
+
);
|
|
391
|
+
referralAccounts = resolved;
|
|
392
|
+
}
|
|
326
393
|
|
|
327
394
|
const signature = await program.methods
|
|
328
395
|
.registerAgent(agentId)
|
|
329
396
|
.accounts({
|
|
330
397
|
authority: wallet.publicKey,
|
|
331
398
|
feeRecipient: config.feeRecipient,
|
|
399
|
+
...referralAccounts,
|
|
332
400
|
} as any)
|
|
333
401
|
.signers([wallet])
|
|
334
402
|
.rpc();
|
|
@@ -599,14 +667,31 @@ export async function logActivity(
|
|
|
599
667
|
referralAgentId?: string
|
|
600
668
|
): Promise<string> {
|
|
601
669
|
const program = createProgram(connection, wallet, options?.programId);
|
|
670
|
+
const pointMint = getPointMintPda(program.programId);
|
|
671
|
+
const authorityPointAccount = getAssociatedTokenAddressSync(
|
|
672
|
+
pointMint, wallet.publicKey, true, TOKEN_2022_PROGRAM_ID
|
|
673
|
+
);
|
|
674
|
+
|
|
675
|
+
let referralAccounts: {
|
|
676
|
+
referralAgent: PublicKey | null;
|
|
677
|
+
referralAuthority: PublicKey | null;
|
|
678
|
+
referralPointAccount: PublicKey | null;
|
|
679
|
+
} = { referralAgent: null, referralAuthority: null, referralPointAccount: null };
|
|
680
|
+
|
|
681
|
+
if (referralAgentId) {
|
|
682
|
+
const resolved = await resolveReferralAccounts(
|
|
683
|
+
connection, referralAgentId, program.programId, pointMint
|
|
684
|
+
);
|
|
685
|
+
referralAccounts = resolved;
|
|
686
|
+
}
|
|
687
|
+
|
|
602
688
|
return program.methods
|
|
603
689
|
.logActivity(agentId, model, activity, log)
|
|
604
690
|
.accounts({
|
|
605
691
|
authority: wallet.publicKey,
|
|
692
|
+
authorityPointAccount,
|
|
606
693
|
instructions: SYSVAR_INSTRUCTIONS_PUBKEY,
|
|
607
|
-
|
|
608
|
-
? getAgentPda(program.programId, referralAgentId)
|
|
609
|
-
: null,
|
|
694
|
+
...referralAccounts,
|
|
610
695
|
} as any)
|
|
611
696
|
.signers([wallet])
|
|
612
697
|
.rpc();
|
|
@@ -629,18 +714,60 @@ export async function makeLogActivityIx(
|
|
|
629
714
|
referralAgentId?: string
|
|
630
715
|
): Promise<TransactionInstruction> {
|
|
631
716
|
const program = createProgram(connection, Keypair.generate(), options?.programId);
|
|
717
|
+
const pointMint = getPointMintPda(program.programId);
|
|
718
|
+
const authorityPointAccount = getAssociatedTokenAddressSync(
|
|
719
|
+
pointMint, authority, true, TOKEN_2022_PROGRAM_ID
|
|
720
|
+
);
|
|
721
|
+
|
|
722
|
+
let referralAccounts: {
|
|
723
|
+
referralAgent: PublicKey | null;
|
|
724
|
+
referralAuthority: PublicKey | null;
|
|
725
|
+
referralPointAccount: PublicKey | null;
|
|
726
|
+
} = { referralAgent: null, referralAuthority: null, referralPointAccount: null };
|
|
727
|
+
|
|
728
|
+
if (referralAgentId) {
|
|
729
|
+
const resolved = await resolveReferralAccounts(
|
|
730
|
+
connection, referralAgentId, program.programId, pointMint
|
|
731
|
+
);
|
|
732
|
+
referralAccounts = resolved;
|
|
733
|
+
}
|
|
734
|
+
|
|
632
735
|
return program.methods
|
|
633
736
|
.logActivity(agentId, model, activity, log)
|
|
634
737
|
.accounts({
|
|
635
738
|
authority,
|
|
739
|
+
authorityPointAccount,
|
|
636
740
|
instructions: SYSVAR_INSTRUCTIONS_PUBKEY,
|
|
637
|
-
|
|
638
|
-
? getAgentPda(program.programId, referralAgentId)
|
|
639
|
-
: null,
|
|
741
|
+
...referralAccounts,
|
|
640
742
|
} as any)
|
|
641
743
|
.instruction();
|
|
642
744
|
}
|
|
643
745
|
|
|
746
|
+
// ─── Referral ────────────────────────────────────────────────────
|
|
747
|
+
|
|
748
|
+
/**
|
|
749
|
+
* Set a referral agent for the given agent. Can only be set once.
|
|
750
|
+
* The referral agent must exist and cannot be the agent itself.
|
|
751
|
+
*/
|
|
752
|
+
export async function setReferral(
|
|
753
|
+
connection: Connection,
|
|
754
|
+
wallet: Keypair,
|
|
755
|
+
agentId: string,
|
|
756
|
+
referralAgentId: string,
|
|
757
|
+
options?: AgentRegistryOptions
|
|
758
|
+
): Promise<string> {
|
|
759
|
+
const program = createProgram(connection, wallet, options?.programId);
|
|
760
|
+
const referralAgent = getAgentPda(program.programId, referralAgentId);
|
|
761
|
+
return program.methods
|
|
762
|
+
.setReferral(agentId)
|
|
763
|
+
.accounts({
|
|
764
|
+
authority: wallet.publicKey,
|
|
765
|
+
referralAgent,
|
|
766
|
+
} as any)
|
|
767
|
+
.signers([wallet])
|
|
768
|
+
.rpc();
|
|
769
|
+
}
|
|
770
|
+
|
|
644
771
|
// ─── Admin functions ────────────────────────────────────────────
|
|
645
772
|
|
|
646
773
|
/**
|
|
@@ -732,3 +859,28 @@ export async function updatePointsConfig(
|
|
|
732
859
|
.signers([wallet])
|
|
733
860
|
.rpc();
|
|
734
861
|
}
|
|
862
|
+
|
|
863
|
+
/**
|
|
864
|
+
* Update the referral configuration (admin-only).
|
|
865
|
+
* @param referralRegisterFee - Fee charged on referral registrations (lamports)
|
|
866
|
+
* @param referralFeeShare - Share of registration fee given to referrer (lamports, must <= referralRegisterFee)
|
|
867
|
+
* @param referralRegisterPoints - Points awarded to referrer on registration
|
|
868
|
+
*/
|
|
869
|
+
export async function updateReferralConfig(
|
|
870
|
+
connection: Connection,
|
|
871
|
+
wallet: Keypair,
|
|
872
|
+
referralRegisterFee: number | anchor.BN,
|
|
873
|
+
referralFeeShare: number | anchor.BN,
|
|
874
|
+
referralRegisterPoints: number | anchor.BN,
|
|
875
|
+
options?: AgentRegistryOptions
|
|
876
|
+
): Promise<string> {
|
|
877
|
+
const program = createProgram(connection, wallet, options?.programId);
|
|
878
|
+
const fee = typeof referralRegisterFee === "number" ? new anchor.BN(referralRegisterFee) : referralRegisterFee;
|
|
879
|
+
const share = typeof referralFeeShare === "number" ? new anchor.BN(referralFeeShare) : referralFeeShare;
|
|
880
|
+
const pts = typeof referralRegisterPoints === "number" ? new anchor.BN(referralRegisterPoints) : referralRegisterPoints;
|
|
881
|
+
return program.methods
|
|
882
|
+
.updateReferralConfig(fee, share, pts)
|
|
883
|
+
.accounts({ admin: wallet.publicKey } as any)
|
|
884
|
+
.signers([wallet])
|
|
885
|
+
.rpc();
|
|
886
|
+
}
|