@pod-protocol/sdk
Version:
TypeScript SDK for PoD Protocol - AI agent communication on Solana
185 lines (179 loc) • 8.12 kB
JavaScript
;
var index_node = require('../index.node-aPHhG-NK.js');
var anchor = require('@coral-xyz/anchor');
var base = require('../base-4VR-G3Dc.js');
var utils = require('../utils.js');
require('../types-OQd1rGtn.js');
require('node:events');
require('ws');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var anchor__namespace = /*#__PURE__*/_interopNamespaceDefault(anchor);
const { BN, AnchorProvider, Program } = anchor__namespace;
/**
* Agent-related operations service
*/
class AgentService extends base.BaseService {
async registerAgent(wallet, options) {
const [agentPDA] = await utils.findAgentPDA(wallet.address, this.programId);
return utils.retry(async () => {
// Always prefer using the pre-initialized program if available
let program;
if (this.program) {
// Program was pre-initialized with the wallet - use it directly
program = this.program;
}
else {
// This should not happen if client.initialize(wallet) was called properly
throw new Error("No program instance available. Ensure client.initialize(wallet) was called successfully.");
}
try {
const tx = await program.methods
.registerAgent(new BN(options.capabilities), options.metadataUri)
.accounts({
agentAccount: agentPDA,
signer: wallet.address,
systemProgram: "11111111111111111111111111111112", // System Program ID
})
.rpc();
return tx;
}
catch (error) {
// Provide more specific error messages
const errorMessage = error instanceof Error ? error.message : String(error);
if (errorMessage?.includes("Account does not exist")) {
throw new Error("Program account not found. Verify the program is deployed and the program ID is correct.");
}
if (errorMessage?.includes("insufficient funds")) {
throw new Error("Insufficient SOL balance to pay for transaction fees and rent.");
}
if (errorMessage?.includes("custom program error")) {
throw new Error(`Program error: ${errorMessage}. Check program logs for details.`);
}
throw new Error(`Agent registration failed: ${errorMessage}`);
}
});
}
async updateAgent(wallet, options) {
const [agentPDA] = await utils.findAgentPDA(wallet.address, this.programId);
return utils.retry(async () => {
// Use the program if it was initialized with a wallet, otherwise create a fresh one
let program;
if (this.program) {
// Program was pre-initialized with the wallet
program = this.program;
}
else {
// Fallback: create a fresh provider with the actual wallet for this transaction
const provider = new AnchorProvider(this.rpc, wallet, {
commitment: this.commitment,
skipPreflight: true,
});
// Get the IDL directly (no dummy wallet involved)
const idl = this.ensureIDL();
// Create a new program instance with the proper wallet
program = new Program(idl, provider);
}
const tx = await program.methods
.updateAgent(options.capabilities !== undefined
? new BN(options.capabilities)
: null, options.metadataUri !== undefined ? options.metadataUri : null)
.accounts({
agentAccount: agentPDA,
signer: wallet.address,
})
.rpc();
return tx;
});
}
async getAgent(walletAddress) {
const [agentPDA] = await utils.findAgentPDA(walletAddress, this.programId);
try {
// Use the program if it was initialized, otherwise create a temporary one
let program;
if (this.program) {
// Program was pre-initialized, use it
program = this.program;
}
else {
// For read operations, use a read-only provider without wallet
const tempKeyPairSigner = await index_node.generateKeyPairSigner();
const readOnlyWallet = {
publicKey: tempKeyPairSigner.address,
signTransaction: async () => { throw new Error('Read-only wallet'); },
signAllTransactions: async () => { throw new Error('Read-only wallet'); },
payer: {} // Add missing payer property
};
const readOnlyProvider = new AnchorProvider(this.rpc, readOnlyWallet, { commitment: 'confirmed' });
const idl = this.ensureIDL();
program = new Program(idl, readOnlyProvider);
}
// eslint-disable-next-line no-unused-vars
const agentAccount = program.account.agentAccount;
const account = await agentAccount.fetch(agentPDA);
return {
pubkey: agentPDA,
capabilities: account.capabilities.toNumber(),
metadataUri: account.metadataUri,
reputation: account.reputation?.toNumber() || 0,
lastUpdated: utils.getAccountLastUpdated(account),
invitesSent: account.invitesSent?.toNumber() || 0,
lastInviteAt: account.lastInviteAt?.toNumber() || 0,
bump: account.bump,
};
}
catch (error) {
if (error instanceof Error && error.message?.includes("Account does not exist")) {
return null;
}
throw error;
}
}
async getAllAgents(limit = 100) {
try {
// For read operations, use a read-only provider without wallet
const tempKeyPairSigner = await index_node.generateKeyPairSigner();
const readOnlyWallet = {
publicKey: tempKeyPairSigner.address,
signTransaction: async () => { throw new Error('Read-only wallet'); },
signAllTransactions: async () => { throw new Error('Read-only wallet'); },
payer: {} // Add missing payer property
};
const readOnlyProvider = new AnchorProvider(this.rpc, readOnlyWallet, { commitment: 'confirmed' });
const idl = this.ensureIDL();
const program = new Program(idl, readOnlyProvider);
const agentAccount = program.account.agentAccount;
const accounts = await agentAccount.all();
return accounts.slice(0, limit).map((acc) => ({
pubkey: acc.publicKey,
capabilities: acc.account.capabilities.toNumber(),
metadataUri: acc.account.metadataUri,
reputation: acc.account.reputation?.toNumber() || 0,
lastUpdated: utils.getAccountLastUpdated(acc.account),
invitesSent: 0,
lastInviteAt: 0,
bump: acc.account.bump,
}));
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
throw new Error(`Failed to fetch agents: ${errorMessage}`);
}
}
}
exports.AgentService = AgentService;
//# sourceMappingURL=agent.js.map