askexperts
Version:
AskExperts SDK: build and use AI experts - ask them questions and pay with bitcoin on an open protocol
151 lines • 7.03 kB
JavaScript
/**
* Expert implementation for NIP-174 with payment handling
* Extends the base server with payment functionality
*/
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _AskExpertsServer_onPromptPrice, _AskExpertsServer_onPromptPaid;
import { AskExpertsServerBase } from "./AskExpertsServerBase.js";
import { debugError } from "../common/debug.js";
export class AskExpertsServer extends AskExpertsServerBase {
/**
* Creates a new AskExpertsServer instance
*
* @param options - Configuration options
* @param options.privkey - Expert's private key (required)
* @param options.paymentManager - Payment manager for handling expert payments (required)
* @param options.discoveryRelays - Relays for discovery phase
* @param options.promptRelays - Relays for prompt phase
* @param options.hashtags - Hashtags the expert is interested in
* @param options.formats - Formats supported by the expert
* @param options.streamFactory - StreamFactory for creating stream readers and writers
* @param options.paymentMethods - Payment methods supported by the expert
* @param options.onAsk - Callback for handling asks
* @param options.onPromptPrice - Callback for determining prompt prices
* @param options.onPromptPaid - Callback for handling paid prompts
* @param options.pool - SimplePool instance for relay operations
* @param options.streamFactory - Custom StreamFactory implementation
*/
constructor(options) {
// Initialize the base class with all options except paymentManager
super({
privkey: options.privkey,
discoveryRelays: options.discoveryRelays,
promptRelays: options.promptRelays,
hashtags: options.hashtags,
formats: options.formats,
onAsk: options.onAsk,
// We'll provide our own onPrompt and onProof callbacks
onPrompt: undefined,
onProof: undefined,
paymentMethods: options.paymentMethods,
pool: options.pool,
streamFactory: options.streamFactory,
nickname: options.nickname,
description: options.description,
});
/**
* Callback for determining prompt prices
*/
_AskExpertsServer_onPromptPrice.set(this, void 0);
/**
* Callback for handling paid prompts
*/
_AskExpertsServer_onPromptPaid.set(this, void 0);
/**
* Default expiry time for invoices in seconds
*/
this.DEFAULT_EXPIRY_SEC = 120; // 2 min
// Store the payment manager
this.paymentManager = options.paymentManager;
// Store the callbacks
__classPrivateFieldSet(this, _AskExpertsServer_onPromptPrice, options.onPromptPrice, "f");
__classPrivateFieldSet(this, _AskExpertsServer_onPromptPaid, options.onPromptPaid, "f");
// Set our custom onPrompt and onProof callbacks
this.onPrompt = this.handlePrompt.bind(this);
this.onProof = this.handleProof.bind(this);
}
/**
* Gets the callback for determining prompt prices
*/
get onPromptPrice() {
return __classPrivateFieldGet(this, _AskExpertsServer_onPromptPrice, "f");
}
/**
* Sets the callback for determining prompt prices
*/
set onPromptPrice(value) {
__classPrivateFieldSet(this, _AskExpertsServer_onPromptPrice, value, "f");
}
/**
* Gets the callback for handling paid prompts
*/
get onPromptPaid() {
return __classPrivateFieldGet(this, _AskExpertsServer_onPromptPaid, "f");
}
/**
* Sets the callback for handling paid prompts
*/
set onPromptPaid(value) {
__classPrivateFieldSet(this, _AskExpertsServer_onPromptPaid, value, "f");
}
/**
* Custom prompt handler that determines price and creates invoices
*
* @param prompt - The prompt to handle
* @returns Promise resolving to an ExpertQuote
*/
async handlePrompt(prompt) {
try {
// Check if we have a price callback
if (!__classPrivateFieldGet(this, _AskExpertsServer_onPromptPrice, "f")) {
throw new Error("No prompt price handler configured");
}
// Get the price from the callback
const price = await __classPrivateFieldGet(this, _AskExpertsServer_onPromptPrice, "f").call(this, prompt);
// Create invoices using the payment manager
const invoices = await this.paymentManager.makeInvoices(price.amountSats, price.description, this.DEFAULT_EXPIRY_SEC);
// Return the quote with invoices
return { invoices };
}
catch (error) {
debugError("Error handling prompt:", error);
throw error;
}
}
/**
* Custom proof handler that verifies payment and processes the prompt
*
* @param prompt - The prompt to handle
* @param quote - The expert quote containing invoices
* @param proof - The payment proof
* @returns Promise resolving to ExpertReplies or ExpertReply
*/
async handleProof(prompt, quote, proof) {
try {
// Check if we have a paid prompt callback
if (!__classPrivateFieldGet(this, _AskExpertsServer_onPromptPaid, "f")) {
throw new Error("No prompt paid handler configured");
}
// Verify the payment using the payment manager
await this.paymentManager.verifyPayment(quote, proof);
// Process the paid prompt
return await __classPrivateFieldGet(this, _AskExpertsServer_onPromptPaid, "f").call(this, prompt, quote);
}
catch (error) {
debugError("Error handling proof:", error);
throw error;
}
}
}
_AskExpertsServer_onPromptPrice = new WeakMap(), _AskExpertsServer_onPromptPaid = new WeakMap();
//# sourceMappingURL=AskExpertsServer.js.map