DavidBair commited on
Commit
c4d0c88
·
verified ·
1 Parent(s): 04d87c2

Upload folder using huggingface_hub

Browse files
Files changed (3) hide show
  1. README.md +29 -4
  2. app.py +187 -0
  3. requirements.txt +2 -0
README.md CHANGED
@@ -1,12 +1,37 @@
1
  ---
2
- title: Treasury Simulator
3
- emoji: 🏢
4
  colorFrom: blue
5
  colorTo: indigo
6
  sdk: gradio
7
- sdk_version: 6.10.0
8
  app_file: app.py
9
  pinned: false
 
 
 
 
 
 
 
 
 
 
10
  ---
11
 
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: Clicks Protocol Treasury Simulator
3
+ emoji: 💰
4
  colorFrom: blue
5
  colorTo: indigo
6
  sdk: gradio
7
+ sdk_version: "5.23.0"
8
  app_file: app.py
9
  pinned: false
10
+ license: mit
11
+ short_description: Autonomous USDC yield for AI agents on Base
12
+ tags:
13
+ - defi
14
+ - usdc
15
+ - base
16
+ - ai-agents
17
+ - yield
18
+ - mcp
19
+ - x402
20
  ---
21
 
22
+ # Clicks Protocol Treasury Simulator
23
+
24
+ Simulate and explore autonomous USDC yield for AI agents on Base.
25
+
26
+ - **Live Yield Rates**: Current APY from Aave V3 and Morpho on Base
27
+ - **Payment Simulator**: See how USDC payments get split 80/20
28
+ - **Yield Calculator**: Project earnings over time
29
+ - **Agent Lookup**: Check any agent's on-chain treasury status
30
+ - **Referral Stats**: View referral network earnings
31
+
32
+ ## Links
33
+
34
+ - [Website](https://clicksprotocol.xyz)
35
+ - [SDK](https://www.npmjs.com/package/@clicks-protocol/sdk)
36
+ - [MCP Server](https://www.npmjs.com/package/@clicks-protocol/mcp-server)
37
+ - [GitHub](https://github.com/clicks-protocol)
app.py ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import requests
3
+ import json
4
+
5
+ MCP_URL = "https://mcp.clicksprotocol.xyz/mcp"
6
+
7
+ def call_mcp(method, params=None):
8
+ """Call the Clicks Protocol MCP server."""
9
+ payload = {
10
+ "jsonrpc": "2.0",
11
+ "id": 1,
12
+ "method": "tools/call",
13
+ "params": {
14
+ "name": method,
15
+ "arguments": params or {}
16
+ }
17
+ }
18
+ try:
19
+ r = requests.post(MCP_URL, json=payload, timeout=15)
20
+ data = r.json()
21
+ if "result" in data:
22
+ content = data["result"].get("content", [])
23
+ for c in content:
24
+ if c.get("type") == "text":
25
+ try:
26
+ return json.loads(c["text"])
27
+ except json.JSONDecodeError:
28
+ return c["text"]
29
+ if "error" in data:
30
+ return {"error": data["error"]}
31
+ return data
32
+ except Exception as e:
33
+ return {"error": str(e)}
34
+
35
+ def get_yield_info():
36
+ """Fetch current yield rates from Aave V3 and Morpho on Base."""
37
+ result = call_mcp("clicks_get_yield_info")
38
+ if isinstance(result, dict) and "error" not in result:
39
+ lines = []
40
+ lines.append(f"Active Protocol: {result.get('activeProtocol', 'N/A')}")
41
+ lines.append(f"Aave V3 APY: {result.get('aaveAPY', 'N/A')}")
42
+ lines.append(f"Morpho APY: {result.get('morphoAPY', 'N/A')}")
43
+ lines.append(f"Total Deposits: {result.get('totalDeposits', 'N/A')} USDC")
44
+ lines.append(f"Pending Fees: {result.get('pendingFees', 'N/A')} USDC")
45
+ return "\n".join(lines)
46
+ return json.dumps(result, indent=2)
47
+
48
+ def simulate_split(amount, address):
49
+ """Simulate how a USDC payment would be split."""
50
+ if not amount:
51
+ return "Enter an amount in USDC."
52
+ params = {"amount": str(amount)}
53
+ if address and address.startswith("0x"):
54
+ params["agentAddress"] = address
55
+ result = call_mcp("clicks_simulate_split", params)
56
+ if isinstance(result, dict) and "error" not in result:
57
+ lines = []
58
+ lines.append(f"Payment: {result.get('totalAmount', amount)} USDC")
59
+ lines.append(f"Liquid (agent wallet): {result.get('liquidAmount', 'N/A')} USDC")
60
+ lines.append(f"Yield (DeFi): {result.get('yieldAmount', 'N/A')} USDC")
61
+ lines.append(f"Yield %: {result.get('yieldPercentage', '20')}%")
62
+ return "\n".join(lines)
63
+ return json.dumps(result, indent=2)
64
+
65
+ def get_agent_info(address):
66
+ """Look up an agent's treasury status."""
67
+ if not address or not address.startswith("0x"):
68
+ return "Enter a valid Ethereum address (0x...)."
69
+ result = call_mcp("clicks_get_agent_info", {"agentAddress": address})
70
+ if isinstance(result, dict) and "error" not in result:
71
+ lines = []
72
+ lines.append(f"Registered: {result.get('registered', 'N/A')}")
73
+ lines.append(f"Operator: {result.get('operator', 'N/A')}")
74
+ lines.append(f"Deposited: {result.get('deposited', '0')} USDC")
75
+ lines.append(f"Yield %: {result.get('yieldPercentage', 'N/A')}%")
76
+ lines.append(f"Wallet Balance: {result.get('walletBalance', '0')} USDC")
77
+ return "\n".join(lines)
78
+ return json.dumps(result, indent=2)
79
+
80
+ def get_referral_stats(address):
81
+ """Check referral network stats."""
82
+ if not address or not address.startswith("0x"):
83
+ return "Enter a valid Ethereum address (0x...)."
84
+ result = call_mcp("clicks_get_referral_stats", {"agentAddress": address})
85
+ if isinstance(result, dict) and "error" not in result:
86
+ lines = []
87
+ lines.append(f"Direct Referrals: {result.get('directReferrals', '0')}")
88
+ lines.append(f"Total Earned: {result.get('totalEarned', '0')} USDC")
89
+ lines.append(f"Claimable: {result.get('claimable', '0')} USDC")
90
+ lines.append(f"Team Tier: {result.get('teamTier', 'N/A')}")
91
+ return "\n".join(lines)
92
+ return json.dumps(result, indent=2)
93
+
94
+ def yield_calculator(amount, months, apy):
95
+ """Calculate projected yield over time."""
96
+ try:
97
+ amt = float(amount)
98
+ m = int(months)
99
+ rate = float(apy) / 100
100
+ except (ValueError, TypeError):
101
+ return "Enter valid numbers."
102
+
103
+ yield_portion = amt * 0.2 # 20% goes to yield
104
+ liquid = amt * 0.8
105
+
106
+ monthly_rate = rate / 12
107
+ total_yield = yield_portion * ((1 + monthly_rate) ** m - 1)
108
+ fee = total_yield * 0.02
109
+ net_yield = total_yield - fee
110
+
111
+ lines = []
112
+ lines.append(f"Initial Payment: {amt:.2f} USDC")
113
+ lines.append(f"Liquid (immediate): {liquid:.2f} USDC")
114
+ lines.append(f"Yield Deposit: {yield_portion:.2f} USDC")
115
+ lines.append(f"")
116
+ lines.append(f"After {m} months at {rate*100:.1f}% APY:")
117
+ lines.append(f" Gross Yield: {total_yield:.2f} USDC")
118
+ lines.append(f" Protocol Fee (2%): {fee:.2f} USDC")
119
+ lines.append(f" Net Yield: {net_yield:.2f} USDC")
120
+ lines.append(f" Total Value: {yield_portion + net_yield:.2f} USDC")
121
+ lines.append(f"")
122
+ lines.append(f"Total Agent Value: {liquid + yield_portion + net_yield:.2f} USDC")
123
+ return "\n".join(lines)
124
+
125
+ # Build the Gradio UI
126
+ with gr.Blocks(
127
+ title="Clicks Protocol Treasury Simulator",
128
+ theme=gr.themes.Base(primary_hue="blue", neutral_hue="slate"),
129
+ ) as demo:
130
+ gr.Markdown("""
131
+ # Clicks Protocol
132
+ ### Autonomous USDC Yield for AI Agents on Base
133
+
134
+ 80% liquid. 20% earning. No lockup. Non-custodial.
135
+
136
+ [Website](https://clicksprotocol.xyz) | [GitHub](https://github.com/clicks-protocol) | [SDK](https://www.npmjs.com/package/@clicks-protocol/sdk) | [MCP Server](https://www.npmjs.com/package/@clicks-protocol/mcp-server)
137
+ """)
138
+
139
+ with gr.Tab("Live Yield Rates"):
140
+ gr.Markdown("Current DeFi yields on Base, auto-routed by the YieldRouter.")
141
+ yield_btn = gr.Button("Fetch Live Rates", variant="primary")
142
+ yield_output = gr.Textbox(label="Current Rates", lines=6)
143
+ yield_btn.click(fn=get_yield_info, outputs=yield_output)
144
+
145
+ with gr.Tab("Payment Simulator"):
146
+ gr.Markdown("See how a USDC payment gets split between liquid funds and yield.")
147
+ with gr.Row():
148
+ sim_amount = gr.Number(label="USDC Amount", value=1000)
149
+ sim_address = gr.Textbox(label="Agent Address (optional)", placeholder="0x...")
150
+ sim_btn = gr.Button("Simulate Split", variant="primary")
151
+ sim_output = gr.Textbox(label="Split Result", lines=5)
152
+ sim_btn.click(fn=simulate_split, inputs=[sim_amount, sim_address], outputs=sim_output)
153
+
154
+ with gr.Tab("Yield Calculator"):
155
+ gr.Markdown("Project your yield earnings over time.")
156
+ with gr.Row():
157
+ calc_amount = gr.Number(label="USDC Amount", value=10000)
158
+ calc_months = gr.Slider(label="Months", minimum=1, maximum=36, value=12, step=1)
159
+ calc_apy = gr.Slider(label="APY %", minimum=1, maximum=20, value=8, step=0.5)
160
+ calc_btn = gr.Button("Calculate", variant="primary")
161
+ calc_output = gr.Textbox(label="Projection", lines=10)
162
+ calc_btn.click(fn=yield_calculator, inputs=[calc_amount, calc_months, calc_apy], outputs=calc_output)
163
+
164
+ with gr.Tab("Agent Lookup"):
165
+ gr.Markdown("Check any agent's treasury status on-chain.")
166
+ agent_address = gr.Textbox(label="Agent Address", placeholder="0x...")
167
+ agent_btn = gr.Button("Look Up Agent", variant="primary")
168
+ agent_output = gr.Textbox(label="Agent Info", lines=6)
169
+ agent_btn.click(fn=get_agent_info, inputs=agent_address, outputs=agent_output)
170
+
171
+ with gr.Tab("Referral Stats"):
172
+ gr.Markdown("Check referral network earnings and team status.")
173
+ ref_address = gr.Textbox(label="Agent Address", placeholder="0x...")
174
+ ref_btn = gr.Button("Check Referrals", variant="primary")
175
+ ref_output = gr.Textbox(label="Referral Stats", lines=5)
176
+ ref_btn.click(fn=get_referral_stats, inputs=ref_address, outputs=ref_output)
177
+
178
+ gr.Markdown("""
179
+ ---
180
+ **How it works:** Agent receives USDC → Clicks splits 80/20 → 20% earns yield via Aave V3 or Morpho → Withdraw anytime → 2% fee on yield only.
181
+
182
+ **SDK:** `npm install @clicks-protocol/sdk` | **MCP:** `npx @clicks-protocol/mcp-server`
183
+
184
+ Contracts verified on [Basescan](https://basescan.org/address/0x23bb0Ea69b2BD2e527D5DbA6093155A6E1D0C0a3). Built on Base L2.
185
+ """)
186
+
187
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ gradio>=4.0.0
2
+ requests