@agentdao/core
Version:
Core functionality, skills, and ready-made UI components for AgentDAO - Web3 subscriptions, content generation, social media, help support, live chat, RSS fetching, web search, and agent pricing integration
236 lines (235 loc) • 9.61 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TokenGatingService = void 0;
const ethers_1 = require("ethers");
const Web3SubscriptionSkill_1 = require("./Web3SubscriptionSkill");
const FundAgent_1 = require("./FundAgent");
class TokenGatingService {
constructor(config) {
this.config = config;
// Create provider from RPC URL or use provided provider
this.provider = config.fundAgent.provider || new ethers_1.ethers.JsonRpcProvider(config.fundAgent.rpcUrl);
this.subscriptionSkill = new Web3SubscriptionSkill_1.Web3SubscriptionSkill(config.subscription);
this.fundAgent = new FundAgent_1.FundAgent(config.fundAgent);
}
/**
* Check user access to AgentDAO features
*/
async checkUserAccess(userAddress) {
try {
// Check ADAO balance
const adaoBalance = await this.getADaoBalance(userAddress);
// Check subscription status
const subscription = await this.subscriptionSkill.checkSubscription(userAddress);
// Check Safe wallet
const safeWallet = await this.getUserSafeWallet(userAddress);
// Determine overall access
const hasAccess = this.determineAccess(adaoBalance, subscription, safeWallet);
// Check individual feature access
const features = await this.checkFeatureAccess(userAddress, adaoBalance, subscription, safeWallet);
return {
hasAccess,
subscription: subscription.hasActiveSubscription ? subscription : null,
safeWallet: safeWallet?.address || null,
adaoBalance,
features,
nextBillingDate: subscription.nextBillingDate,
gracePeriodDays: this.calculateGracePeriod(subscription)
};
}
catch (error) {
console.error('Error checking user access:', error);
return {
hasAccess: false,
subscription: null,
safeWallet: null,
adaoBalance: 0,
features: {}
};
}
}
/**
* Create subscription and Safe wallet for new user
*/
async onboardUser(userAddress, planId, billingPeriod, createSafeWallet = true) {
try {
// 1. Create subscription
const subscription = await this.subscriptionSkill.createSubscription(userAddress, planId, billingPeriod);
let safeWallet;
// 2. Create Safe wallet if requested and required
if (createSafeWallet && this.config.gating.requireSafeWallet) {
const depositAmount = this.config.fundAgent.minDeposit;
safeWallet = await this.fundAgent.createSafeWallet(userAddress, depositAmount);
// Add user as owner to the Safe wallet
await this.fundAgent.addOwner(safeWallet, userAddress);
}
return {
subscription,
safeWallet,
success: true
};
}
catch (error) {
console.error('Error onboarding user:', error);
return {
subscription: null,
success: false,
error: error.message
};
}
}
/**
* Upgrade user subscription and potentially Safe wallet
*/
async upgradeUser(userAddress, newPlanId, newBillingPeriod) {
try {
// Check if user has enough ADAO for upgrade
const balance = await this.getADaoBalance(userAddress);
const plan = this.config.subscription.plans[newPlanId];
const pricing = plan.pricing[newBillingPeriod];
if (balance < pricing.price) {
throw new Error(`Insufficient ADAO balance for upgrade. Required: ${pricing.price}, Available: ${balance}`);
}
// Process upgrade (this would typically involve smart contract calls)
const success = await this.subscriptionSkill.changeBillingPeriod(userAddress, newBillingPeriod);
if (success) {
const subscription = await this.subscriptionSkill.checkSubscription(userAddress);
return {
success: true,
subscription
};
}
else {
throw new Error('Failed to process upgrade');
}
}
catch (error) {
console.error('Error upgrading user:', error);
return {
success: false,
error: error.message
};
}
}
/**
* Get user's Safe wallet information
*/
async getUserSafeWallet(userAddress) {
try {
// Query database for user's Safe wallet
if (!this.config.database || !this.config.database.endpoint) {
throw new Error('No database endpoint configured for Safe wallet lookup. Please configure a database endpoint to use this feature.');
}
const response = await fetch(`${this.config.database.endpoint}/safe-wallets`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
...(this.config.database.apiKey ? { 'Authorization': `Bearer ${this.config.database.apiKey}` } : {})
}
});
if (response.ok) {
const data = await response.json();
const userSafeWallet = data.safeWallets.find(wallet => wallet.owners && wallet.owners.includes(userAddress.toLowerCase()));
if (userSafeWallet) {
// Get real status from blockchain
const status = await this.fundAgent.getWalletStatus(userSafeWallet.address);
return {
address: status.address,
owners: status.owners,
threshold: status.threshold,
balance: status.balance,
isActive: status.isActive,
createdAt: new Date(userSafeWallet.createdAt || Date.now())
};
}
}
// If no Safe wallet found in database, return null
return null;
}
catch (error) {
console.error('Error getting user Safe wallet:', error);
return null;
}
}
/**
* Check if user can access a specific feature
*/
async checkFeatureAccess(userAddress, adaoBalance, subscription, safeWallet) {
const features = {};
for (const [featureName, featureConfig] of Object.entries(this.config.gating.features)) {
let accessible = true;
let reason;
// Check ADAO requirement
if (adaoBalance < featureConfig.requiredTokens) {
accessible = false;
reason = `Insufficient tokens. Required: ${featureConfig.requiredTokens}, Available: ${adaoBalance}`;
}
// Check subscription requirement
if (featureConfig.requiredPlan && (!subscription.hasActiveSubscription || subscription.planId !== featureConfig.requiredPlan)) {
accessible = false;
reason = `Requires ${featureConfig.requiredPlan} subscription`;
}
// Check Safe wallet requirement
if (featureConfig.requireSafeWallet && !safeWallet) {
accessible = false;
reason = 'Safe wallet required';
}
features[featureName] = { accessible, reason };
}
return features;
}
/**
* Get available plans for user based on their ADAO balance
*/
async getAvailablePlansForUser(userAddress) {
const balance = await this.getADaoBalance(userAddress);
const allPlans = await this.subscriptionSkill.getAvailablePlans();
return allPlans.filter(plan => {
const minPrice = Math.min(plan.pricing.monthly.price, plan.pricing.quarterly.price, plan.pricing.annually.price);
return balance >= minPrice;
});
}
/**
* Get user's ADAO balance
*/
async getADaoBalance(userAddress) {
return await this.subscriptionSkill.getADaoBalance(userAddress);
}
/**
* Determine overall access based on subscription, balance, and Safe wallet
*/
determineAccess(adaoBalance, subscription, safeWallet) {
// Check minimum ADAO requirement
if (adaoBalance < this.config.gating.minTokenForAccess) {
return false;
}
// Check subscription requirement
if (!subscription.hasActiveSubscription) {
return false;
}
// Check Safe wallet requirement if enabled
if (this.config.gating.requireSafeWallet && !safeWallet) {
return false;
}
return true;
}
/**
* Calculate grace period days
*/
calculateGracePeriod(subscription) {
if (!subscription.hasActiveSubscription || subscription.daysLeft === undefined) {
return undefined;
}
if (subscription.daysLeft <= 0) {
return Math.max(0, this.config.gating.gracePeriod + subscription.daysLeft);
}
return undefined;
}
/**
* Set signer for transactions
*/
setSigner(signer) {
this.subscriptionSkill.setSigner(signer);
}
}
exports.TokenGatingService = TokenGatingService;