Smart Contract Interactions
Real-time monitoring of smart contract interactions across the Solana ecosystem, providing insights into on-chain activity, protocol usage, and transaction patterns.
Overview
The interactions WebSocket stream captures:
- Program invocations and cross-program calls
- Instruction execution details
- Account state changes
- Token transfers and movements
- Compute unit consumption
- Transaction success/failure status
Connection
WebSocket Endpoint:
wss://api.nolimitnodes.com/socket?apikey=YOUR_API_KEY
1
Subscription
Subscribe Request
json
{
"method": "dataSubscribe",
"params": {
"referenceId": "INTERACTIONS",
"streams": [
{
"stream": "interactionsSubscribe",
"params": {
"token": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"from_address": "optional_sender_address",
"to_address": "optional_recipient_address",
"program_id": "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8"
}
}
]
},
"id": 1
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Filter Parameters
Parameter | Type | Required | Description |
---|---|---|---|
from | string | No | Filter by sender wallet address |
to | string | No | Filter by recipient wallet address |
token | string | No | Filter by token type (e.g., "Solana") |
amount | number | No | Filter by specific amount |
program_id | string | No | Filter by specific program ID |
type | string | No | Filter by interaction type (e.g., "transfer") |
Response Messages
Subscription Confirmation
json
{
"status": "Subscribed to interactions",
"subscription_id": "4db6df25-fa4f-4325-8652-ee3a9f9690b4",
"stream": "interactionsSubscribe",
"reference_id": "INTERACTIONS"
}
1
2
3
4
5
6
2
3
4
5
6
Interaction Event
json
{
"method": "interactionsSubscribe",
"subscription_id": "4db6df25-fa4f-4325-8652-ee3a9f9690b4",
"result": {
"from": "28fdboacCPayNxToWNfgNpkVpUuuhN9LyxfQKFt8vXjm",
"to": "axmFmfqQwZGEUZeF3i3MqbRCDiGPfshtbdoBjk41k88",
"amount": 1000000,
"token": "Solana",
"transaction_signature": "4wBiX5Pw5QkJ7dmrZTSnqVP4axLsDNzB11f3vTHgbzcqLCKadBa48gCDoPe7CudLFHwwwnKDQMYXxCqmgFprVFAu",
"block_num": "367222399",
"block_time": "1758033052",
"program_id": "11111111111111111111111111111111",
"type": "transfer"
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Field Descriptions
from
: Sender wallet addressto
: Recipient wallet addressamount
: Transfer amount (in smallest unit)token
: Token type (e.g., "Solana")transaction_signature
: Solana transaction signatureblock_num
: Block numberblock_time
: Unix timestampprogram_id
: Program that executed the interactiontype
: Interaction type (e.g., "transfer")
Transfer Information
from
: Sender wallet addressto
: Recipient wallet addressamount
: Transfer amount in lamports (for SOL) or smallest unittoken
: Token type ("Solana" for SOL transfers)
Transaction Details
transaction_signature
: Solana transaction signatureblock_num
: Block number where interaction occurredblock_time
: Unix timestamp of the blockprogram_id
: Program that executed the interaction (11111111111111111111111111111111 for system program)type
: Type of interaction (e.g., "transfer")signer
: Transaction signer/initiatorfeePayer
: Account paying transaction feesinvolved
: Array of all accounts usedtype
: Account type (token_account, pool, program, etc.)writable
: Whether account is modifiedsigner
: Whether account is a signerowner
: Account owner (for token accounts)
Token Transfers
token
: Token mint addressfrom
: Source accountto
: Destination accountamount
: Transfer amount (in smallest unit)decimals
: Token decimal places
Execution Result
status
: success or failederror
: Error message if failedcomputeUnits
: Compute units consumedfee
: Transaction fee in lamportsinnerInstructions
: Count of nested instructions
Context
relatedPrograms
: Programs invokedcrossProgramInvocations
: CPI countlogs
: Transaction logs
Unsubscribe
To stop receiving interaction events, use the dataUnsubscribe
method with the subscription ID:
Unsubscribe Request
json
{
"method": "dataUnsubscribe",
"params": {
"subscriptionIds": ["your_subscription_id_here"],
"referenceId": "UNSUB_REF"
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
Unsubscribe Response
json
{
"status": "Unsubscribed from interactions",
"subscription_id": "your_subscription_id_here",
"stream": "interactionsSubscribe",
"reference_id": "UNSUB_REF"
}
1
2
3
4
5
6
2
3
4
5
6
Code Examples
JavaScript/Node.js
javascript
const WebSocket = require('ws');
class InteractionMonitor {
constructor(apiKey) {
this.ws = new WebSocket(`wss://api.nolimitnodes.com/socket?apikey=${apiKey}`);
this.setupHandlers();
}
setupHandlers() {
this.ws.on('open', () => {
this.subscribe();
});
this.ws.on('message', (data) => {
const message = JSON.parse(data);
if (message.method === 'interactionsSubscribe') {
this.processInteraction(message.result);
}
});
}
subscribe() {
this.ws.send(JSON.stringify({
method: 'dataSubscribe',
params: {
referenceId: 'INTERACTIONS',
streams: [{
stream: 'interactionsSubscribe',
params: {
token: 'Solana'
}
}]
}
}));
}
processInteraction(interaction) {
const amount = interaction.amount / 1e9; // Convert to SOL
console.log('\nInteraction Detected:');
console.log(` Type: ${interaction.type}`);
console.log(` From: ${interaction.from.slice(0, 8)}...`);
console.log(` To: ${interaction.to.slice(0, 8)}...`);
console.log(` Amount: ${amount} ${interaction.token}`);
console.log(` Block: ${interaction.block_num}`);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
Python
python
import json
import asyncio
import websockets
from collections import defaultdict
from datetime import datetime, timedelta
class InteractionMonitor:
def __init__(self, api_key):
self.api_key = api_key
self.uri = f"wss://api.nolimitnodes.com/pump-fun?apikey={api_key}"
self.interaction_history = []
self.program_stats = defaultdict(lambda: {
'calls': 0, 'failures': 0, 'compute_units': [], 'volume': 0
})
async def connect(self):
self.websocket = await websockets.connect(self.uri)
print("Connected to interactions stream")
async def subscribe(self, program_id=None):
params = {}
if program_id:
params["program_id"] = program_id
subscription = {
"method": "dataSubscribe",
"params": {
"referenceId": "INTERACT#1",
"streams": [{
"stream": "interactionsSubscribe",
"params": params
}]
}
}
await self.websocket.send(json.dumps(subscription))
async def listen(self):
async for message in self.websocket:
data = json.loads(message)
if data.get('stream') == 'interactions':
await self.process_interaction(data['data'])
async def process_interaction(self, interaction):
# Store interaction
self.interaction_history.append({
'timestamp': datetime.now(),
'data': interaction
})
# Update program statistics
program = interaction['program']['name']
stats = self.program_stats[program]
stats['calls'] += 1
if interaction['result']['status'] == 'failed':
stats['failures'] += 1
stats['compute_units'].append(interaction['result']['computeUnits'])
# Calculate volume from transfers
for transfer in interaction.get('tokenTransfers', []):
amount = float(transfer['amount']) / (10 ** transfer['decimals'])
stats['volume'] += amount
# Display interaction
await self.display_interaction(interaction)
# Analyze patterns
await self.analyze_patterns(interaction)
async def display_interaction(self, interaction):
status = "✅" if interaction['result']['status'] == 'success' else "❌"
print(f"\n{status} {interaction['program']['name']}: {interaction['instruction']['name']}")
print(f" Signature: {interaction['signature'][:16]}...")
print(f" Signer: {interaction['accounts']['signer'][:8]}...")
print(f" Compute: {interaction['result']['computeUnits']:,} units")
print(f" Fee: {int(interaction['result']['fee']) / 1e9:.6f} SOL")
# Show token transfers
if interaction.get('tokenTransfers'):
print(f" Transfers:")
for transfer in interaction['tokenTransfers']:
amount = float(transfer['amount']) / (10 ** transfer['decimals'])
print(f" • {amount:,.2f} tokens")
print(f" From: {transfer['from'][:8]}...")
print(f" To: {transfer['to'][:8]}...")
# Show error if failed
if interaction['result']['status'] == 'failed':
print(f" Error: {interaction['result'].get('error', 'Unknown')}")
async def analyze_patterns(self, interaction):
alerts = []
# High compute usage
if interaction['result']['computeUnits'] > 1000000:
alerts.append(f"⚠️ High compute usage: {interaction['result']['computeUnits']:,}")
# Many cross-program calls
cpi_count = interaction['context']['crossProgramInvocations']
if cpi_count > 5:
alerts.append(f"🔄 Complex transaction: {cpi_count} program calls")
# Failed transaction pattern
program = interaction['program']['name']
stats = self.program_stats[program]
if stats['calls'] > 10:
failure_rate = (stats['failures'] / stats['calls']) * 100
if failure_rate > 20:
alerts.append(f"⚠️ High failure rate for {program}: {failure_rate:.1f}%")
# Display alerts
if alerts:
print("\n🚨 ALERTS:")
for alert in alerts:
print(f" {alert}")
async def show_statistics(self):
"""Display accumulated statistics"""
print("\n" + "="*60)
print("📊 INTERACTION STATISTICS")
print("="*60)
total_interactions = len(self.interaction_history)
if total_interactions == 0:
print("No interactions recorded yet")
return
# Calculate time range
if self.interaction_history:
time_range = datetime.now() - self.interaction_history[0]['timestamp']
print(f"Time Range: {time_range}")
print(f"Total Interactions: {total_interactions}")
# Program statistics
print("\n🏆 Program Usage:")
sorted_programs = sorted(
self.program_stats.items(),
key=lambda x: x[1]['calls'],
reverse=True
)[:10]
for program, stats in sorted_programs:
failure_rate = (stats['failures'] / stats['calls']) * 100 if stats['calls'] > 0 else 0
avg_compute = sum(stats['compute_units']) / len(stats['compute_units']) if stats['compute_units'] else 0
print(f"\n {program}")
print(f" Calls: {stats['calls']}")
print(f" Failure Rate: {failure_rate:.1f}%")
print(f" Avg Compute: {avg_compute:,.0f} units")
print(f" Volume: {stats['volume']:,.2f} tokens")
async def main():
monitor = InteractionMonitor("YOUR_API_KEY")
await monitor.connect()
await monitor.subscribe()
# Show statistics every 60 seconds
async def periodic_stats():
while True:
await asyncio.sleep(60)
await monitor.show_statistics()
# Run both tasks concurrently
await asyncio.gather(
monitor.listen(),
periodic_stats()
)
if __name__ == "__main__":
asyncio.run(main())
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
Best Practices
1. Protocol Monitoring
- Track DeFi Health: Monitor popular protocols (Raydium, Orca, Jupiter) for unusual failure rates or compute spikes
- Detect Security Issues: Flag interactions with failed transactions, high compute usage, or unusual patterns
- Program Analysis: Build profiles of program usage, success rates, and common failure causes
2. Performance Optimization
- Filter by Program: Use
program_id
filters to focus on specific protocols you're monitoring - Batch Processing: Group interaction events for efficient analysis and storage
- Smart Sampling: Implement intelligent sampling during high-activity periods to manage data volume
3. Cross-Program Intelligence
- Composability Tracking: Monitor which programs are frequently used together in transactions
- User Behavior Analysis: Track how users interact across different DeFi protocols
- MEV Detection: Identify arbitrage patterns and sandwich attacks through cross-program analysis