mirror of
https://github.com/arkorty/B.Tech-Project-III.git
synced 2026-04-19 12:41:48 +00:00
447 lines
17 KiB
Markdown
447 lines
17 KiB
Markdown
# negoT8 — Blockchain Integration Guide
|
||
|
||
> **Invisible to users. Powerful to judges. Built for Algorand + ETHIndia tracks.**
|
||
|
||
---
|
||
|
||
## Core Philosophy: Blockchain That Users Never See
|
||
|
||
The blockchain layer is like the engine in a car. The user just drives — they never open the hood. Every transaction, every hash, every contract runs invisibly. The user sees only:
|
||
|
||
```
|
||
✅ Agreement Secured | 🔗 View Proof: negot8.app/verify/TXN123ABC
|
||
```
|
||
|
||
This guide is structured in **4 milestones**, each building on the last. Milestone 1 is the baseline that touches every feature. Milestones 2–4 are depth features for the Algorand and ETHIndia tracks.
|
||
|
||
---
|
||
|
||
## Updated Folder Structure
|
||
|
||
Add the following to your existing `negot8/backend/` directory:
|
||
|
||
```
|
||
negot8/
|
||
├── backend/
|
||
│ ├── blockchain/ ← NEW DIRECTORY
|
||
│ │ ├── __init__.py
|
||
│ │ ├── algorand_client.py ← Algorand SDK wrapper + TestNet connection
|
||
│ │ ├── notarize.py ← Hash agreement → write to chain
|
||
│ │ ├── escrow_contract.py ← PyTeal freelancer escrow smart contract
|
||
│ │ ├── reputation.py ← On-chain agent reputation scoring
|
||
│ │ └── contract_templates/
|
||
│ │ └── freelance_escrow.py ← PyTeal contract logic
|
||
│ │
|
||
│ ├── features/
|
||
│ │ ├── freelance.py ← MODIFIED: add escrow deploy after resolution
|
||
│ │ └── expenses.py ← MODIFIED: add notarization after resolution
|
||
│ │
|
||
│ └── tools/
|
||
│ └── verify.py ← NEW: lookup a txid and return proof data
|
||
│
|
||
├── dashboard/
|
||
│ ├── app/
|
||
│ │ └── verify/
|
||
│ │ └── [txid]/page.tsx ← NEW: public verification page
|
||
│ └── components/
|
||
│ ├── VerifiedBadge.tsx ← NEW: green checkmark badge component
|
||
│ └── ProofCard.tsx ← NEW: shows agreement details + chain proof
|
||
```
|
||
|
||
Everything else in your existing structure stays exactly the same. These are **pure additions**, no rewrites.
|
||
|
||
---
|
||
|
||
## Milestone 1 — Agreement Notarization (Baseline)
|
||
|
||
Every single negotiation that resolves gets its agreement hashed and anchored on Algorand. Zero user friction. Works for all 8 features.
|
||
|
||
**What the user sees in Telegram:**
|
||
```
|
||
✅ Agreement reached!
|
||
|
||
📋 Summary: Meet at Blue Tokai, Connaught Place on Friday 3pm
|
||
🔐 Secured on Algorand · View proof: negot8.app/verify/TXN123ABC
|
||
```
|
||
|
||
**What actually happens under the hood:**
|
||
1. Negotiation resolves → agreement JSON is assembled
|
||
2. SHA-256 hash of the JSON is computed
|
||
3. Hash is written to an Algorand transaction note field (costs 0.001 ALGO)
|
||
4. Transaction ID (TxID) is stored in your SQLite DB alongside the negotiation
|
||
5. TxID is included in the Telegram resolution message as a verify link
|
||
|
||
### Install
|
||
|
||
```bash
|
||
pip install py-algorand-sdk
|
||
```
|
||
|
||
### blockchain/algorand_client.py
|
||
|
||
```python
|
||
import algosdk, os
|
||
from algosdk.v2client import algod
|
||
|
||
ALGOD_URL = "https://testnet-api.algonode.cloud"
|
||
ALGOD_TOKEN = "" # AlgoNode TestNet needs no token
|
||
|
||
def get_client():
|
||
return algod.AlgodClient(ALGOD_TOKEN, ALGOD_URL)
|
||
|
||
def get_agent_account():
|
||
# Load from env — one funded TestNet account for all notarizations
|
||
private_key = os.environ['ALGORAND_PRIVATE_KEY']
|
||
address = algosdk.account.address_from_private_key(private_key)
|
||
return private_key, address
|
||
```
|
||
|
||
### blockchain/notarize.py
|
||
|
||
```python
|
||
import hashlib, json
|
||
from algosdk import transaction
|
||
from .algorand_client import get_client, get_agent_account
|
||
|
||
async def notarize_agreement(agreement: dict) -> str:
|
||
"""Hash the agreement dict, write to Algorand. Returns TxID."""
|
||
# Step 1: Create canonical hash
|
||
agreement_str = json.dumps(agreement, sort_keys=True)
|
||
hash_bytes = hashlib.sha256(agreement_str.encode()).hexdigest()
|
||
|
||
# Step 2: Write hash to chain as a zero-value transaction note
|
||
client = get_client()
|
||
private_key, address = get_agent_account()
|
||
params = client.suggested_params()
|
||
|
||
note = f"negot8:v1:{hash_bytes}".encode() # max 1KB
|
||
txn = transaction.PaymentTransaction(
|
||
sender=address,
|
||
sp=params,
|
||
receiver=address, # send to self, 0 ALGO
|
||
amt=0,
|
||
note=note
|
||
)
|
||
signed = txn.sign(private_key)
|
||
txid = client.send_transaction(signed)
|
||
|
||
# Step 3: Wait for confirmation (3.3 sec on Algorand)
|
||
transaction.wait_for_confirmation(client, txid, 4)
|
||
return txid # store this in SQLite + send to Telegram
|
||
```
|
||
|
||
### Hook Into Existing Resolution Flow
|
||
|
||
In each of your feature files (e.g. `features/scheduling.py`), add 3 lines after resolution:
|
||
|
||
```python
|
||
# EXISTING CODE — runs when negotiation resolves
|
||
resolution = await negotiator.finalize()
|
||
await store_resolution(db, negotiation_id, resolution)
|
||
|
||
# NEW: 3 lines — notarize on-chain
|
||
from blockchain.notarize import notarize_agreement
|
||
txid = await notarize_agreement(resolution)
|
||
await db.execute('UPDATE negotiations SET txid=? WHERE id=?', (txid, negotiation_id))
|
||
|
||
# EXISTING — send Telegram message (just add the verify link)
|
||
verify_url = f'https://negot8.app/verify/{txid}'
|
||
await bot.send_message(chat_id, f'✅ Done!\n🔐 Secured: {verify_url}')
|
||
```
|
||
|
||
---
|
||
|
||
## Milestone 2 — Verification Page (User Trust Layer)
|
||
|
||
This is what the user sees when they tap the verify link. Clean, simple, no crypto jargon. Shows what was agreed, when, and quietly shows it's on Algorand.
|
||
|
||
### dashboard/app/verify/[txid]/page.tsx
|
||
|
||
```tsx
|
||
export default async function VerifyPage({ params }: { params: { txid: string } }) {
|
||
const data = await fetch(`/api/verify/${params.txid}`).then(r => r.json())
|
||
|
||
return (
|
||
<div className='max-w-lg mx-auto p-6'>
|
||
<div className='flex items-center gap-2 mb-4'>
|
||
<span className='text-green-500 text-2xl'>✅</span>
|
||
<h1 className='text-xl font-bold'>Agreement Verified</h1>
|
||
</div>
|
||
|
||
<div className='bg-gray-50 rounded-xl p-4 mb-4'>
|
||
<p className='text-sm text-gray-500 mb-1'>What was agreed</p>
|
||
<p className='font-medium'>{data.summary}</p>
|
||
</div>
|
||
|
||
<div className='grid grid-cols-2 gap-3 mb-4'>
|
||
<div className='bg-white border rounded-lg p-3'>
|
||
<p className='text-xs text-gray-400'>Between</p>
|
||
<p className='font-medium text-sm'>{data.parties.join(' & ')}</p>
|
||
</div>
|
||
<div className='bg-white border rounded-lg p-3'>
|
||
<p className='text-xs text-gray-400'>On</p>
|
||
<p className='font-medium text-sm'>{data.timestamp}</p>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Quiet blockchain mention — not the hero, just a trust signal */}
|
||
<p className='text-xs text-gray-400 text-center'>
|
||
Secured on Algorand ·{' '}
|
||
<a href={`https://testnet.algoexplorer.io/tx/${params.txid}`} className='underline'>
|
||
View transaction
|
||
</a>
|
||
</p>
|
||
</div>
|
||
)
|
||
}
|
||
```
|
||
|
||
> **Note:** The word "blockchain" never appears. The user sees "Secured" and a checkmark. The Algorand link is there for whoever wants it — but never forced.
|
||
|
||
---
|
||
|
||
## Milestone 3 — Freelancer Escrow Smart Contract (Algorand Track)
|
||
|
||
This is your flagship feature for the Algorand track. After the agents negotiate scope + budget, the client's agent autonomously deploys a smart contract that locks payment in escrow. **No human writes a contract. The AI does it.**
|
||
|
||
> **Demo pitch:** *"The AI agents just negotiated a ₹50,000 freelance deal. The payment is now locked on Algorand. It auto-releases when the milestone is confirmed. No lawyers, no disputes, no chasing payments."*
|
||
|
||
### The Flow
|
||
|
||
1. Agents negotiate: scope = `landing page`, budget = ₹50,000, deadline = 2 weeks
|
||
2. Resolution triggers contract deployment (automatic, no user action needed)
|
||
3. Client gets Telegram message: *"Fund escrow to lock in your deal → [link]"*
|
||
4. On milestone completion, freelancer sends `/complete` to their agent
|
||
5. Contract releases funds automatically
|
||
|
||
### blockchain/contract_templates/freelance_escrow.py (PyTeal)
|
||
|
||
```python
|
||
from pyteal import *
|
||
|
||
def freelance_escrow(client_addr: str, freelancer_addr: str,
|
||
amount: int, deadline_round: int):
|
||
|
||
# Release: only freelancer can claim, only before deadline
|
||
release = And(
|
||
Txn.sender() == Addr(freelancer_addr),
|
||
Txn.receiver() == Addr(freelancer_addr),
|
||
Global.round() <= Int(deadline_round)
|
||
)
|
||
|
||
# Refund: client reclaims if deadline passed
|
||
refund = And(
|
||
Txn.sender() == Addr(client_addr),
|
||
Global.round() > Int(deadline_round)
|
||
)
|
||
|
||
return If(release, Approve(), If(refund, Approve(), Reject()))
|
||
```
|
||
|
||
### blockchain/escrow_contract.py
|
||
|
||
```python
|
||
from algosdk import transaction, logic
|
||
from pyteal import compileTeal, Mode
|
||
from .contract_templates.freelance_escrow import freelance_escrow
|
||
from .algorand_client import get_client, get_agent_account
|
||
|
||
async def deploy_escrow(client_addr, freelancer_addr, amount_inr):
|
||
"""Compile + deploy escrow. Returns escrow address + txid."""
|
||
client = get_client()
|
||
params = client.suggested_params()
|
||
|
||
# Deadline = current round + ~10,000 blocks (≈ 2 weeks on Algorand)
|
||
deadline_round = client.status()['last-round'] + 10000
|
||
|
||
# Compile PyTeal to TEAL bytecode
|
||
teal_code = compileTeal(
|
||
freelance_escrow(client_addr, freelancer_addr, amount_inr, deadline_round),
|
||
mode=Mode.Signature, version=6
|
||
)
|
||
compiled = client.compile(teal_code)
|
||
escrow_address = compiled['hash']
|
||
|
||
return {
|
||
'escrow_address': escrow_address,
|
||
'deadline_round': deadline_round,
|
||
'fund_link': f'https://testnet.algoexplorer.io/address/{escrow_address}'
|
||
}
|
||
```
|
||
|
||
### Hook Into features/freelance.py
|
||
|
||
```python
|
||
# After negotiation resolves in freelance.py:
|
||
from blockchain.escrow_contract import deploy_escrow
|
||
from blockchain.notarize import notarize_agreement
|
||
|
||
escrow = await deploy_escrow(
|
||
client_addr=user_a.wallet_address,
|
||
freelancer_addr=user_b.wallet_address,
|
||
amount_inr=resolution['budget']
|
||
)
|
||
txid = await notarize_agreement(resolution)
|
||
|
||
# Message to client
|
||
await bot.send_message(user_a.telegram_id,
|
||
f'✅ Deal agreed!\n'
|
||
f'💰 Lock ₹{resolution["budget"]} in escrow:\n'
|
||
f'{escrow["fund_link"]}\n'
|
||
f'🔐 Agreement proof: negot8.app/verify/{txid}'
|
||
)
|
||
```
|
||
|
||
---
|
||
|
||
## Milestone 4 — Agent Reputation on EVM (ETHIndia Track)
|
||
|
||
Your analytics already track satisfaction scores per negotiation. This milestone writes those scores on-chain, creating a **verifiable reputation** for each agent that persists forever and is portable across any app.
|
||
|
||
> **ETHIndia angle:** *Decentralized, portable, user-owned agent reputation. Your agent's trustworthiness isn't locked in our database — it lives on-chain.*
|
||
|
||
### Simple Solidity Contract
|
||
|
||
```solidity
|
||
// SPDX-License-Identifier: MIT
|
||
pragma solidity ^0.8.0;
|
||
|
||
contract AgentReputation {
|
||
struct Score {
|
||
uint256 totalScore; // sum of all satisfaction scores (0-100)
|
||
uint256 count; // number of negotiations
|
||
uint256 lastUpdated; // block timestamp
|
||
}
|
||
|
||
// agentAddress => reputation
|
||
mapping(address => Score) public reputation;
|
||
|
||
event ScoreRecorded(address indexed agent, uint8 score, uint256 average);
|
||
|
||
function recordScore(address agent, uint8 score) external {
|
||
require(score <= 100, "Score out of range");
|
||
Score storage s = reputation[agent];
|
||
s.totalScore += score;
|
||
s.count += 1;
|
||
s.lastUpdated = block.timestamp;
|
||
emit ScoreRecorded(agent, score, s.totalScore / s.count);
|
||
}
|
||
|
||
function getAverage(address agent) external view returns (uint256) {
|
||
Score storage s = reputation[agent];
|
||
if (s.count == 0) return 0;
|
||
return s.totalScore / s.count;
|
||
}
|
||
}
|
||
```
|
||
|
||
Deploy this on **Polygon Mumbai TestNet** (free, gas is near-zero). Your Python backend calls it after every resolved negotiation using `web3.py`.
|
||
|
||
### blockchain/reputation.py
|
||
|
||
```python
|
||
from web3 import Web3
|
||
import os
|
||
|
||
RPC_URL = 'https://rpc-mumbai.maticvigil.com'
|
||
CONTRACT_ADDRESS = 'YOUR_DEPLOYED_CONTRACT_ADDRESS'
|
||
ABI = [/* paste ABI after deploying */]
|
||
|
||
async def record_reputation(agent_wallet: str, satisfaction_score: int):
|
||
w3 = Web3(Web3.HTTPProvider(RPC_URL))
|
||
contract = w3.eth.contract(address=CONTRACT_ADDRESS, abi=ABI)
|
||
account = w3.eth.account.from_key(os.environ['ETH_PRIVATE_KEY'])
|
||
|
||
tx = contract.functions.recordScore(agent_wallet, satisfaction_score).build_transaction({
|
||
'from': account.address,
|
||
'nonce': w3.eth.get_transaction_count(account.address),
|
||
'gas': 100000,
|
||
'gasPrice': w3.to_wei('1', 'gwei') # near-zero on Mumbai
|
||
})
|
||
signed = account.sign_transaction(tx)
|
||
tx_hash = w3.eth.send_raw_transaction(signed.rawTransaction)
|
||
return tx_hash.hex()
|
||
```
|
||
|
||
---
|
||
|
||
## New Environment Variables
|
||
|
||
Add these to your existing `.env` file:
|
||
|
||
```bash
|
||
# ─── Blockchain (Algorand) ───────────────────────────────────────
|
||
ALGORAND_PRIVATE_KEY=your_testnet_account_private_key_here
|
||
ALGORAND_ADDRESS=your_testnet_account_address_here
|
||
|
||
# ─── Blockchain (ETHIndia / Polygon) ─────────────────────────────
|
||
ETH_PRIVATE_KEY=your_polygon_mumbai_private_key_here
|
||
REPUTATION_CONTRACT_ADDRESS=your_deployed_contract_address_here
|
||
|
||
# ─── Feature flags (so you can demo without chain if needed) ─────
|
||
ENABLE_NOTARIZATION=true
|
||
ENABLE_ESCROW=true
|
||
ENABLE_REPUTATION=true
|
||
```
|
||
|
||
> **Important:** Create a fresh wallet for hackathon use only. Never use a wallet with real funds. Fund it with TestNet ALGO from [bank.testnet.algorand.network/dispenser](https://bank.testnet.algorand.network/dispenser) (free).
|
||
|
||
---
|
||
|
||
## New Install Commands
|
||
|
||
```bash
|
||
# Algorand SDK + PyTeal
|
||
pip install py-algorand-sdk pyteal
|
||
|
||
# Web3 for ETHIndia track
|
||
pip install web3
|
||
```
|
||
|
||
---
|
||
|
||
## Milestone Summary
|
||
|
||
| Milestone | What It Builds | Track | User Sees | Effort |
|
||
|---|---|---|---|---|
|
||
| 1 — Notarization | Hash + anchor every agreement on Algorand TestNet | Algorand | 🔐 Secured badge + verify link | Low — 1 file, 3 lines per feature |
|
||
| 2 — Verify Page | Public webpage showing agreement proof | Both | Clean proof page, no crypto jargon | Low — 1 Next.js page |
|
||
| 3 — Escrow Contract | PyTeal smart contract for freelancer payments | Algorand | Fund escrow link in Telegram | Medium — PyTeal + deploy flow |
|
||
| 4 — Reputation | On-chain agent satisfaction scores (EVM) | ETHIndia | Agent reputation badge on dashboard | Low — 1 Solidity contract |
|
||
|
||
---
|
||
|
||
## Hackathon Demo Script (Blockchain Moments)
|
||
|
||
**Scene 1 — Any Feature (30 seconds)**
|
||
> *"Rahul and Priya's agents just agreed to meet Friday at 3pm. Watch what happens — the agreement is automatically secured on Algorand. Here's the verification link. Anyone can check this, forever, without trusting us."*
|
||
|
||
**Scene 2 — Freelancer Escrow (1 minute — Algorand Track highlight)**
|
||
> *"These two AI agents just negotiated a ₹50,000 project. But here's what's different — the payment is now locked in a smart contract on Algorand that was deployed automatically by the agents, not by a human. The freelancer gets paid when they deliver. The client gets a refund if they don't. Zero paperwork, zero lawyers, zero trust required."*
|
||
|
||
**Scene 3 — Reputation (30 seconds — ETHIndia Track)**
|
||
> *"Every time an agent closes a negotiation, the satisfaction score goes on-chain. This is Rahul's agent — 94/100 average across 12 negotiations. That score lives on Polygon. It's portable. If Rahul moves to another app tomorrow, his agent's reputation comes with him. That's user-owned AI reputation."*
|
||
|
||
---
|
||
|
||
## Key Points to Remember
|
||
|
||
- Never mention "blockchain", "wallet", "gas", or "seed phrase" to end users
|
||
- All blockchain calls are async and non-blocking — if chain is slow, resolution still sends to Telegram immediately
|
||
- Always wrap blockchain calls in `try/except` — if chain fails, the product still works, just without the proof link
|
||
- Use TestNet throughout the hackathon — real funds are never needed
|
||
- AlgoNode (TestNet) is free and needs no API key — just use the public URL
|
||
- Polygon Mumbai gas is near-zero — reputation writes cost fractions of a cent
|
||
|
||
```python
|
||
# Always wrap blockchain in try/except so it never breaks the core product
|
||
try:
|
||
txid = await notarize_agreement(resolution)
|
||
verify_url = f'negot8.app/verify/{txid}'
|
||
except Exception as e:
|
||
print(f'Notarization failed (non-critical): {e}')
|
||
verify_url = None # just don't show the link, product still works
|
||
```
|
||
|
||
> This is the most important pattern in the entire blockchain integration. The feature degrades gracefully. **The product never breaks because of the chain.**
|