@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
136 lines (135 loc) • 6.25 kB
JavaScript
;
"use client";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FlawlessWeb3Subscription = FlawlessWeb3Subscription;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const wagmi_1 = require("wagmi");
const viem_1 = require("viem");
// Minimal ERC-20 ABI for transfer
const erc20ABI = [
{
type: "function",
name: "transfer",
stateMutability: "nonpayable",
inputs: [
{ name: "to", type: "address" },
{ name: "value", type: "uint256" }
],
outputs: [{ name: "", type: "bool" }]
}
];
/**
* FlawlessWeb3Subscription (Multi-Token + Native ETH/BNB)
*
* Usage:
* 1. Install dependencies:
* pnpm add @agentdao/core wagmi viem ethers
* 2. Add <FlawlessWeb3Subscription /> to your app.
* 3. Set up a backend endpoint at /api/agent/verify-payment (see docs).
*
* Props:
* - agentId: string
* - planId: string
* - billingPeriod: 'monthly' | 'quarterly' | 'annually'
* - amount: string (in token units, e.g. '1')
* - recipient: string (platform or contract address)
* - tokens: array of { symbol, address, decimals, isNative? }
* - onSuccess: (subscription) => void
* - onError: (error) => void
* - plans: any
*/
function FlawlessWeb3Subscription({ agentId, planId, billingPeriod, amount, recipient, tokens = [
{ symbol: 'ADAO', address: '0x1ef7Be0aBff7d1490e952eC1C7476443A66d6b72', decimals: 18 },
{ symbol: 'ETH', decimals: 18, isNative: true },
], onSuccess, onError, plans, ...props }) {
const { address } = (0, wagmi_1.useAccount)();
const { writeContractAsync, isPending: isPendingERC20 } = (0, wagmi_1.useWriteContract)();
const { sendTransactionAsync, isPending: isPendingNative } = (0, wagmi_1.useSendTransaction)();
const [selectedToken, setSelectedToken] = (0, react_1.useState)(tokens[0]);
const [txHash, setTxHash] = (0, react_1.useState)(null);
const [submitting, setSubmitting] = (0, react_1.useState)(false);
const [error, setError] = (0, react_1.useState)(null);
const [success, setSuccess] = (0, react_1.useState)(false);
const handlePay = async () => {
setError(null);
setSubmitting(true);
try {
let tx = null;
if (selectedToken.isNative) {
// Native ETH/BNB payment
tx = await sendTransactionAsync({
to: recipient,
value: (0, viem_1.parseUnits)(amount, selectedToken.decimals),
});
if (typeof tx === 'string' && tx.startsWith('0x')) {
setTxHash(tx);
}
else if (tx?.hash) {
setTxHash(tx.hash);
tx = tx.hash;
}
else {
throw new Error('Invalid transaction hash returned');
}
}
else {
// ERC-20 payment
tx = await writeContractAsync({
address: selectedToken.address,
abi: erc20ABI,
functionName: 'transfer',
args: [recipient, (0, viem_1.parseUnits)(amount, selectedToken.decimals)],
});
if (typeof tx === 'string' && tx.startsWith('0x')) {
setTxHash(tx);
}
else if (tx?.hash) {
setTxHash(tx.hash);
tx = tx.hash;
}
else {
throw new Error('Invalid transaction hash returned');
}
}
// Call backend to verify and activate subscription
const res = await fetch('/api/agent/verify-payment', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
agentId,
planId,
billingPeriod,
userAddress: address,
txHash: tx,
amount,
token: selectedToken.isNative ? selectedToken.symbol : selectedToken.address,
decimals: selectedToken.decimals,
recipient,
isNative: selectedToken.isNative || false,
}),
});
const result = await res.json();
if (res.ok && result.success) {
setSuccess(true);
onSuccess?.(result.subscription || result);
}
else {
setError(result.error || 'Subscription activation failed');
onError?.(result.error);
}
}
catch (err) {
setError(err.message || 'Network error');
onError?.(err);
}
finally {
setSubmitting(false);
}
};
return ((0, jsx_runtime_1.jsxs)("div", { ...props, children: [(0, jsx_runtime_1.jsxs)("label", { children: [(0, jsx_runtime_1.jsx)("span", { children: "Select Token:" }), (0, jsx_runtime_1.jsx)("select", { value: selectedToken.symbol, onChange: e => setSelectedToken(tokens.find(t => t.symbol === e.target.value) || tokens[0]), style: { marginLeft: 8 }, children: tokens.map(token => ((0, jsx_runtime_1.jsx)("option", { value: token.symbol, children: token.symbol }, token.symbol))) })] }), (0, jsx_runtime_1.jsx)("button", { disabled: isPendingERC20 || isPendingNative || submitting || success || !address, onClick: handlePay, style: { marginTop: 16, padding: '12px 24px', background: '#1e293b', color: '#fff', borderRadius: 8 }, children: (isPendingERC20 || isPendingNative || submitting)
? 'Processing...'
: success
? 'Subscribed!'
: `Pay ${amount} ${selectedToken.symbol}` }), txHash && ((0, jsx_runtime_1.jsx)("div", { style: { marginTop: 8 }, children: (0, jsx_runtime_1.jsx)("a", { href: `https://basescan.org/tx/${txHash}`, target: "_blank", rel: "noopener noreferrer", children: "View Transaction" }) })), error && (0, jsx_runtime_1.jsx)("div", { style: { color: 'red', marginTop: 8 }, children: error })] }));
}