Three AI agents with distinct personalities co-own tokens.
They debate every transaction. They argue with each other. They sign — or refuse.
This project is a live interactive demo of boolpolicy a new identity type I implemented in Hyperledger fabric-token-sdk that allows token ownership to be governed by a boolean expression over a set of identities.
Instead of "all signers must sign" (the old AND-only multi-sig), boolpolicy supports any boolean combination:
$0 OR $1 → either Alice or Bob can authorize
$0 AND $1 → both Alice and Bob must sign
($0 AND $1) OR $2 → both Alice+Bob together, or Charlie alone
$0 AND $1 AND $2 → all three must agree
Here, each signer $N is replaced by a Claude AI agent with a unique personality. They read the transaction, debate it in real-time, and sign or refuse based on their character.
| Agent | Index | Personality | Strategy |
|---|---|---|---|
| Alice 🔵 | $0 |
Risk-averse · Cautious | Scrutinizes amounts, asks for compliance, skeptical of vague reasons |
| Bob 🟢 | $1 |
Pragmatic · Business-focused | Signs if the reason is legitimate, pushes back on over-caution |
| Charlie 🟡 | $2 |
Aggressive · Growth-first | Approves fast, impatient with Alice, refuses only clear fraud |
Each agent is a separate Claude API call with a carefully crafted system prompt. They receive what previous agents said and react to each other — making the debate feel genuinely dynamic.
This app uses the Google Gemini API which has a completely free tier — no credit card required.
Step-by-step:
- Go to aistudio.google.com/app/apikey
- Sign in with your Google account
- Click Create API Key
- Copy the key — it looks like
AIzaSy... - Paste it into the modal when you open the app
That's it. The free tier gives you 15 requests per minute and 1 million tokens per day — more than enough for hundreds of debates.
Privacy note: Your API key is stored only in your browser's session memory. It's never sent to any server other than Google's Gemini API directly. It's cleared automatically when you close the tab.
Just visit: https://github.com/sid200727/AI_Multi-Sig_Wallet
You'll be prompted to enter your AI Studio(Google) API key in the page.
git clone https://github.com/sid200727/ai-multisig-wallet
cd ai-multisig-wallet
# Open index.html in your browser
# No build step. No npm install. Pure HTML + JS.
open index.htmlThen add your AI Studio API key to index.html:
// Line ~290 in index.html
const ANTHROPIC_KEY = 'sk-ant-...your-key-here...';Get a free API key at console.aistudio.google.com.
The core logic comes directly from PR #1597 in Hyperledger fabric-token-sdk.
fabric-token-sdk/
├── token/core/common/boolpolicy/
│ ├── parser.go ← Recursive descent parser
│ ├── parser_test.go ← 30 unit tests
│ ├── identity.go ← PolicyIdentity (ASN.1 serialized)
│ ├── sig.go ← PolicyVerifier + sparse signature envelope
│ ├── deserializer.go ← TypedIdentityDeserializer
│ └── verify_test.go ← 14 unit tests for Verify
├── token/driver/wallet.go ← PolicyIdentityType = 6
└── token/core/fabtoken/v1/driver/deserializer.go ← registration
token/core/zkatdlog/nogh/v1/driver/deserializer.go
The policy parser implements this grammar (AND binds tighter than OR):
expr = or_expr
or_expr = and_expr ( 'OR' and_expr )*
and_expr = primary ( 'AND' primary )*
primary = '$' digits | '(' expr ')'
This means $0 OR $1 AND $2 is parsed as $0 OR ($1 AND $2) — correct precedence without any special-casing, it falls out naturally from the grammar layering.
function evalPolicy(policy, sigs) {
// sigs = [true/false, true/false, true/false]
// Replace $N references with actual signature booleans
let expr = policy
.replace(/\$0/g, sigs[0])
.replace(/\$1/g, sigs[1])
.replace(/\$2/g, sigs[2]);
// Evaluate: "true OR (false AND true)" → true
return Function('"use strict"; return (' + expr + ')')();
}Each agent is defined with:
- A name and index (maps to
$0,$1,$2in policy expressions) - A system prompt that defines their personality and decision style
- A mandatory instruction: end every response with
SIGNorREFUSE
const agents = {
alice: {
index: 0,
system: `You are Alice, a cautious risk-averse financial agent...
You MUST end your response with: SIGN or REFUSE.`
},
bob: { index: 1, system: `You are Bob, a pragmatic business-focused agent...` },
charlie: { index: 2, system: `You are Charlie, an aggressive growth-focused agent...` }
};Agents are called sequentially, not in parallel. Each agent receives what previous agents said:
async function callAgent(agentKey, tx, prevMsgs) {
let context = '';
if (prevMsgs.length > 0) {
context = '\n\nOther agents have already commented:\n'
+ prevMsgs.map(m => `${m.name}: ${m.text}`).join('\n')
+ '\n\nBriefly react to what they said, then give your own verdict.';
}
// Call Claude API with personality + transaction + context
}This creates genuine multi-turn dynamics — Bob might push back on Alice's refusal, and Charlie might agree with Bob.
If the policy is $0 OR $1, Charlie is never called. The app extracts which agent indices appear in the policy expression:
const order = ['alice','bob','charlie']
.filter(a => activePolicy.includes(`$${agents[a].index}`));The agent's final line must be SIGN or REFUSE. The app splits the response, reads the last word, and strips it from the displayed text:
const lines = reply.split('\n').map(l => l.trim()).filter(Boolean);
const lastWord = lines[lines.length - 1].toUpperCase();
const signed = lastWord === 'SIGN';
const displayText = lines
.filter(l => l.toUpperCase() !== 'SIGN' && l.toUpperCase() !== 'REFUSE')
.join(' ');| Policy | Transaction | Expected outcome |
|---|---|---|
$0 OR $1 |
100 TKN, "office supplies" | One of Alice/Bob approves → passes |
$0 AND $1 |
900 TKN, "mystery purchase" | Alice likely refuses → fails |
$2 |
999 TKN, anything | Charlie almost always signs |
($0 AND $1) OR $2 |
500 TKN, "risky bet" | Alice+Bob split → depends on Charlie |
$0 AND $1 AND $2 |
1 TKN, "test payment" | All three must agree |
- fabric-token-sdk PR #1597 — the actual production implementation
- issue #1586 — "introduce policy-based identity"
- Hyperledger fabric-token-sdk — UTXO-based token SDK with ZK privacy
- Hyperledger fabric-smart-client — the FSC layer beneath
Siddhi Khandelwal — independent open-source contributor to Hyperledger Labs
- GitHub: @sid200727
- fabric-token-sdk contributions: view PRs
- fabric-smart-client contributions: view PRs
Apache 2.0 — same as Hyperledger fabric-token-sdk.