Skip to content

Commit 2c633d5

Browse files
Blackman99claude
andcommitted
feat: add @trustin/txgraph-core multi-source data layer and embed demo in docs
- Create packages/core with DataSource adapter interface, GraphBuilder (BFS), and adapters for TrustIn, Etherscan, and Tronscan - Add rate limiter, BigInt amount formatter, and transaction aggregator - Update demo to support data source selection (TrustIn vs On-Chain) - Embed built demo as iframe in docs site with /demo nav entry - Update docs to link to live demo instead of v2.trustin.info Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 4ec03ba commit 2c633d5

29 files changed

Lines changed: 1223 additions & 91 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ dist/
33
!packages/react/dist/
44
.vitepress/dist/
55
.vitepress/cache/
6+
docs/public/demo/
67
*.local
78
.env
89
.DS_Store

docs/.vitepress/config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,15 @@ export default defineConfig({
1313
nav: [
1414
{ text: 'Guide', link: '/guide/layer1-product' },
1515
{ text: 'API', link: '/api/components' },
16+
{ text: 'Demo', link: '/demo' },
1617
{ text: 'GitHub', link: 'https://github.com/Blackman99/txgraph' },
1718
],
1819
sidebar: [
1920
{
2021
text: 'Getting Started',
2122
items: [
2223
{ text: 'Introduction', link: '/' },
23-
{ text: '🌐 Layer 1: Use Explorer', link: '/guide/layer1-product' },
24+
{ text: '🌐 Layer 1: Live Demo', link: '/guide/layer1-product' },
2425
{ text: '🤖 Layer 2: AI Agent API', link: '/guide/layer2-agent' },
2526
{ text: '💻 Layer 3: Local Demo', link: '/guide/layer3-demo' },
2627
{ text: '🛠 Layer 4: Build Your Own', link: '/guide/layer4-component' },
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<script setup lang="ts">
2+
import { useData } from 'vitepress'
3+
4+
const { isDark } = useData()
5+
</script>
6+
7+
<template>
8+
<div class="demo-frame-container">
9+
<iframe
10+
:src="`${$frontmatter.demoBase || '/txgraph/demo/'}${isDark ? '' : '?theme=light'}`"
11+
class="demo-frame"
12+
allow="clipboard-read; clipboard-write"
13+
/>
14+
</div>
15+
</template>
16+
17+
<style scoped>
18+
.demo-frame-container {
19+
width: 100%;
20+
height: calc(100vh - var(--vp-nav-height) - 1px);
21+
overflow: hidden;
22+
}
23+
24+
.demo-frame {
25+
width: 100%;
26+
height: 100%;
27+
border: none;
28+
}
29+
</style>

docs/.vitepress/theme/index.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import DefaultTheme from 'vitepress/theme'
2+
import DemoFrame from './DemoFrame.vue'
3+
4+
export default {
5+
extends: DefaultTheme,
6+
enhanceApp({ app }) {
7+
app.component('DemoFrame', DemoFrame)
8+
},
9+
}

docs/demo.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
layout: page
3+
title: Live Demo
4+
---
5+
6+
<DemoFrame />

docs/guide/layer1-product.md

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
1-
# 🌐 Use TrustIn Explorer
1+
# 🌐 Try the Live Demo
22

33
The fastest way to trace blockchain transactions — no setup, no API key, no code.
44

5-
## What is TrustIn Explorer?
5+
## Open the Demo
66

7-
[TrustIn Explorer](https://v2.trustin.info/explore) is a full-featured AML (Anti-Money Laundering) investigation platform. It provides:
7+
Go to the [Live Demo](/demo) page to start tracing immediately. The demo supports two data source modes:
88

9-
- **Visual transaction graph** — trace fund flows across Ethereum and Tron
10-
- **Risk scoring** — AI-powered risk assessment for every address
11-
- **Entity tagging** — identify exchanges, mixers, sanctioned addresses
12-
- **Multi-hop tracing** — follow funds through multiple hops
13-
- **Inflow & outflow analysis** — see where funds came from and where they went
9+
- **TrustIn** — uses the TrustIn API with risk scoring and entity tagging
10+
- **On-Chain** — fetches raw data directly from Etherscan (Ethereum) or Tronscan (Tron)
1411

1512
## Getting Started
1613

17-
1. Visit [v2.trustin.info](https://v2.trustin.info/explore)
14+
1. Open the [Live Demo](/demo)
1815
2. Enter a blockchain address (Ethereum or Tron)
19-
3. Select direction: **Inflow** / **Outflow** / **Both**
20-
4. Click **Explore** — the graph loads instantly
16+
3. Select data source: **TrustIn** or **On-Chain**
17+
4. Select direction: **Inflow** / **Outflow** / **All**
18+
5. Click **Explore** — the graph loads instantly
2119

2220
## Features
2321

@@ -32,6 +30,10 @@ Each node (address) is colored by risk:
3230
| 🟢 Green | Low | Verified exchange, known entity |
3331
| ⚫ Gray | Unknown | No data available |
3432

33+
::: tip
34+
Risk scoring and entity tags are only available when using the **TrustIn** data source. On-Chain mode shows all nodes as "unknown" risk.
35+
:::
36+
3537
### Expanding the Graph
3638

3739
- Click any node to see its details
@@ -44,11 +46,11 @@ Switch between two renderers:
4446
- **ReactFlow** — best for interactive exploration, drag nodes, zoom
4547
- **Sigma.js** — best for large graphs (1000+ nodes), WebGL-accelerated
4648

47-
## When to use TrustIn Explorer
49+
## When to use the Demo
4850

49-
✅ Quick investigation — need an answer now
50-
✅ No technical setup required
51-
Full feature set including AI risk scoring
51+
✅ Quick investigation — need an answer now
52+
✅ No technical setup required
53+
Compare TrustIn vs on-chain data
5254
✅ Regular compliance checks
5355

5456
→ For programmatic access, see [Layer 2: AI Agent API](/guide/layer2-agent). To run locally, see [Layer 3: Local Demo](/guide/layer3-demo). To embed in your own app, see [Layer 4: Build Your Own](/guide/layer4-component).

docs/guide/layer3-demo.md

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# 💻 Run Demo Locally
22

3-
Run TxGraph as a local Vite app connected to the TrustIn API. Ideal for evaluation, internal tooling, or as a starting point for your own integration.
3+
Run TxGraph as a local Vite app with multi-source support (TrustIn API or on-chain via Etherscan/Tronscan). Ideal for evaluation, internal tooling, or as a starting point for your own integration.
4+
5+
::: tip Try without setup
6+
You can also try the [Live Demo](/demo) directly in this documentation site — no installation needed.
7+
:::
48

59
## Prerequisites
610

@@ -25,26 +29,31 @@ Open [http://localhost:5173](http://localhost:5173)
2529

2630
## Configuration (Optional)
2731

28-
The demo works out of the box without any API key. For higher rate limits, create `examples/local-demo/.env`:
32+
The demo works out of the box without any API key. For higher rate limits or on-chain API keys, create `examples/local-demo/.env`:
2933

3034
```env
3135
VITE_TRUSTIN_API_URL=https://api.trustin.info
3236
VITE_TRUSTIN_API_KEY=your_api_key_here
37+
VITE_ETHERSCAN_API_KEY=your_etherscan_key
38+
VITE_TRONSCAN_API_KEY=your_tronscan_key
3339
```
3440

3541
| Variable | Default | Description |
3642
|----------|---------|-------------|
37-
| `VITE_TRUSTIN_API_URL` | `https://api.trustin.info` | API base URL |
38-
| `VITE_TRUSTIN_API_KEY` || Optional API key for higher rate limits |
43+
| `VITE_TRUSTIN_API_URL` | `https://api.trustin.info` | TrustIn API base URL |
44+
| `VITE_TRUSTIN_API_KEY` || Optional TrustIn API key for higher rate limits |
45+
| `VITE_ETHERSCAN_API_KEY` || Optional Etherscan API key (5 req/s free tier) |
46+
| `VITE_TRONSCAN_API_KEY` || Optional Tronscan API key |
3947

4048
## Using the Demo
4149

4250
1. **Enter an address** — Ethereum (0x…) or Tron (T…)
4351
2. **Select chain** — Ethereum or Tron
44-
3. **Choose direction** — Outflow / Inflow / Both
45-
4. **Set date range** (optional) — filter by transaction date
46-
5. **Click Explore** — graph renders immediately
47-
6. **Toggle renderer** — switch between ReactFlow and Sigma.js
52+
3. **Select data source** — TrustIn (with risk scoring) or On-Chain (Etherscan/Tronscan)
53+
4. **Choose direction** — Outflow / Inflow / All
54+
5. **Set date range** (optional) — filter by transaction date
55+
6. **Click Explore** — graph renders immediately
56+
7. **Toggle renderer** — switch between ReactFlow and Sigma.js
4857

4958
### Node Interactions
5059

@@ -81,7 +90,7 @@ If you use [Claude Code](https://claude.com/claude-code), the `/trace-graph` ski
8190
examples/local-demo/
8291
├── src/
8392
│ ├── App.tsx # Main UI with controls
84-
│ ├── api.ts # TrustIn API client
93+
│ ├── api.ts # Multi-source API client (TrustIn + on-chain)
8594
│ └── main.tsx # React entry point
8695
├── .env.example # Environment template
8796
├── index.html
@@ -109,4 +118,4 @@ The demo is intentionally simple. Common customizations:
109118
- **Multiple addresses** — extend the UI for batch exploration
110119
- **Export** — add JSON/CSV export of graph data
111120

112-
For deeper integration, see [Layer 3: Build Your Own](/guide/layer3-component).
121+
For deeper integration, see [Layer 4: Build Your Own](/guide/layer4-component).

docs/index.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,18 @@ hero:
1717

1818
features:
1919
- icon: 🌐
20-
title: Use TrustIn Explorer
21-
details: Instantly trace transactions at v2.trustin.info — no setup required. Full-featured AML investigation tool.
22-
link: /guide/layer1-product
23-
linkText: Open Explorer
20+
title: Try Live Demo
21+
details: Instantly trace transactions in the browser — no setup required. Supports TrustIn API and on-chain data sources (Etherscan, Tronscan).
22+
link: /demo
23+
linkText: Open Demo
2424
- icon: 🤖
2525
title: AI Agent API
2626
details: Self-register your AI agent in one request and start tracing addresses immediately. No account needed — 200 requests/day free quota. MCP-compatible.
2727
link: /guide/layer2-agent
2828
linkText: Agent Setup
2929
- icon: 💻
30-
title: Run Demo Locally
31-
details: Clone the example project and connect to TrustIn API with your API key. Full control over data and UI.
30+
title: Run Locally
31+
details: Clone the repo and run TxGraph locally for full control. Connect to TrustIn API or use on-chain data via Etherscan/Tronscan.
3232
link: /guide/layer3-demo
3333
linkText: Setup Guide
3434
- icon: 🛠

examples/local-demo/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33
"private": true,
44
"dependencies": {
55
"@trustin/txgraph": "workspace:*",
6+
"@trustin/txgraph-core": "workspace:*",
67
"react": "^18",
78
"react-dom": "^18"
89
},
910
"devDependencies": {
11+
"@types/react": "^18",
12+
"@types/react-dom": "^18",
1013
"@vitejs/plugin-react": "^4",
1114
"typescript": "^5",
1215
"vite": "^5"

examples/local-demo/src/App.tsx

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import React, { useState, useCallback, useEffect } from 'react'
22
import { GraphExplorer, GraphExplorerSigma } from '@trustin/txgraph'
33
import type { TxNode, TxGraph } from '@trustin/txgraph'
4-
import { exploreGraph } from './api'
4+
import { exploreGraph, expandNode } from './api'
5+
import type { DataSourceType } from './api'
56

67
type Renderer = 'reactflow' | 'sigma'
78
type Chain = 'Ethereum' | 'Tron'
@@ -70,6 +71,7 @@ export default function App() {
7071
const [token, setToken] = useState(qp.token)
7172
const [fromDate, setFromDate] = useState(qp.fromDate)
7273
const [toDate, setToDate] = useState(qp.toDate)
74+
const [dataSource, setDataSource] = useState<DataSourceType>('trustin')
7375
const [renderer, setRenderer] = useState<Renderer>('reactflow')
7476
const [graph, setGraph] = useState<TxGraph | null>(null)
7577
const [loading, setLoading] = useState(false)
@@ -106,14 +108,15 @@ export default function App() {
106108
token: token || undefined,
107109
fromDate: fromDate || undefined,
108110
toDate: toDate || undefined,
111+
dataSource,
109112
})
110113
setGraph(data)
111114
} catch (e) {
112115
setError(e instanceof Error ? e.message : String(e))
113116
} finally {
114117
setLoading(false)
115118
}
116-
}, [address, chain, direction, token, fromDate, toDate])
119+
}, [address, chain, direction, token, fromDate, toDate, dataSource])
117120

118121
// Auto-explore when opened with query params
119122
const autoExploreRef = React.useRef(qp.autoExplore)
@@ -128,32 +131,24 @@ export default function App() {
128131
if (!graph) return
129132
setExpandingNode(addr)
130133
try {
131-
const data = await exploreGraph({
132-
address: addr,
133-
chain,
134-
direction,
135-
token: token || undefined,
136-
maxDepth: 1,
137-
})
138-
const existingAddrs = new Set(graph.nodes.map((n) => n.address))
139-
const newNodes = data.nodes.filter((n) => !existingAddrs.has(n.address))
140-
const existingEdgeKeys = new Set(graph.edges.map((e) => `${e.from}->${e.to}`))
141-
const newEdges = data.edges.filter((e) => !existingEdgeKeys.has(`${e.from}->${e.to}`))
142-
setGraph({
143-
nodes: [...graph.nodes, ...newNodes],
144-
edges: [...graph.edges, ...newEdges],
145-
stats: {
146-
total_nodes: graph.nodes.length + newNodes.length,
147-
total_edges: graph.edges.length + newEdges.length,
148-
stopped_nodes: graph.stats?.stopped_nodes ?? 0,
134+
const merged = await expandNode(
135+
{
136+
address: addr,
137+
chain,
138+
direction,
139+
token: token || undefined,
140+
maxDepth: 1,
141+
dataSource,
149142
},
150-
})
143+
graph
144+
)
145+
setGraph(merged)
151146
} catch (e) {
152147
console.error('Expand failed:', e)
153148
} finally {
154149
setExpandingNode(null)
155150
}
156-
}, [graph, chain, direction, token])
151+
}, [graph, chain, direction, token, dataSource])
157152

158153
const handleNodeDelete = useCallback((addr: string) => {
159154
if (!graph) return
@@ -228,6 +223,16 @@ export default function App() {
228223
<option>Tron</option>
229224
</select>
230225

226+
{/* Data source */}
227+
<select
228+
value={dataSource}
229+
onChange={(e) => setDataSource(e.target.value as DataSourceType)}
230+
style={inputStyle}
231+
>
232+
<option value="trustin">TrustIn</option>
233+
<option value="onchain">On-Chain</option>
234+
</select>
235+
231236
{/* Direction */}
232237
<select
233238
value={direction}
@@ -321,7 +326,9 @@ export default function App() {
321326
<div style={{ height: '100%', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 12, color: c.dimmed }}>
322327
<div style={{ fontSize: 48 }}>🔍</div>
323328
<div style={{ fontSize: 15 }}>Enter an address and click <strong>Explore</strong></div>
324-
<div style={{ fontSize: 12, color: c.dimmed }}>Powered by TrustIn API</div>
329+
<div style={{ fontSize: 12, color: c.dimmed }}>
330+
{dataSource === 'trustin' ? 'Powered by TrustIn API' : `On-Chain via ${chain === 'Tron' ? 'Tronscan' : 'Etherscan'}`}
331+
</div>
325332
</div>
326333
)}
327334
{(graph || loading) && (

0 commit comments

Comments
 (0)