@validators-dao/solana-stream-sdk 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +152 -7
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -16,23 +16,168 @@ pnpm add @validators-dao/solana-stream-sdk
|
|
|
16
16
|
|
|
17
17
|
## Usage
|
|
18
18
|
|
|
19
|
+
Example of using the GeyserClient to subscribe to Solana Pump Fun transactions and accounts:
|
|
20
|
+
|
|
19
21
|
```typescript
|
|
20
22
|
import {
|
|
21
23
|
GeyserClient,
|
|
22
24
|
bs58,
|
|
23
25
|
CommitmentLevel,
|
|
26
|
+
SubscribeRequestAccountsDataSlice,
|
|
24
27
|
SubscribeRequestFilterAccounts,
|
|
28
|
+
SubscribeRequestFilterBlocks,
|
|
29
|
+
SubscribeRequestFilterBlocksMeta,
|
|
30
|
+
SubscribeRequestFilterEntry,
|
|
31
|
+
SubscribeRequestFilterSlots,
|
|
25
32
|
SubscribeRequestFilterTransactions,
|
|
26
|
-
// ... other exports
|
|
27
33
|
} from '@validators-dao/solana-stream-sdk'
|
|
34
|
+
import 'dotenv/config'
|
|
35
|
+
|
|
36
|
+
interface SubscribeRequest {
|
|
37
|
+
accounts: {
|
|
38
|
+
[key: string]: SubscribeRequestFilterAccounts
|
|
39
|
+
}
|
|
40
|
+
slots: {
|
|
41
|
+
[key: string]: SubscribeRequestFilterSlots
|
|
42
|
+
}
|
|
43
|
+
transactions: {
|
|
44
|
+
[key: string]: SubscribeRequestFilterTransactions
|
|
45
|
+
}
|
|
46
|
+
transactionsStatus: {
|
|
47
|
+
[key: string]: SubscribeRequestFilterTransactions
|
|
48
|
+
}
|
|
49
|
+
blocks: {
|
|
50
|
+
[key: string]: SubscribeRequestFilterBlocks
|
|
51
|
+
}
|
|
52
|
+
blocksMeta: {
|
|
53
|
+
[key: string]: SubscribeRequestFilterBlocksMeta
|
|
54
|
+
}
|
|
55
|
+
entry: {
|
|
56
|
+
[key: string]: SubscribeRequestFilterEntry
|
|
57
|
+
}
|
|
58
|
+
commitment?: CommitmentLevel | undefined
|
|
59
|
+
accountsDataSlice: SubscribeRequestAccountsDataSlice[]
|
|
60
|
+
ping?: any
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// const PUMP_FUN_MINT_AUTHORITY = 'TSLvdd1pWpHVjahSpsvCXUbgwsL3JAcvokwaKt1eokM'
|
|
64
|
+
const PUMP_FUN_PROGRAM_ID = '6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P'
|
|
65
|
+
|
|
66
|
+
const tran: SubscribeRequestFilterTransactions = {
|
|
67
|
+
accountInclude: [PUMP_FUN_PROGRAM_ID],
|
|
68
|
+
accountExclude: [],
|
|
69
|
+
accountRequired: [],
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const request: SubscribeRequest = {
|
|
73
|
+
accounts: {
|
|
74
|
+
pumpfun: {
|
|
75
|
+
account: [],
|
|
76
|
+
owner: [],
|
|
77
|
+
filters: [],
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
slots: {},
|
|
81
|
+
transactions: { elsol: tran },
|
|
82
|
+
transactionsStatus: {},
|
|
83
|
+
blocks: {},
|
|
84
|
+
blocksMeta: {},
|
|
85
|
+
entry: {},
|
|
86
|
+
accountsDataSlice: [],
|
|
87
|
+
commitment: CommitmentLevel.PROCESSED,
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const geyser = async () => {
|
|
91
|
+
console.log('Starting geyser client...')
|
|
92
|
+
const maxRetries = 2000000
|
|
93
|
+
|
|
94
|
+
const createClient = () => {
|
|
95
|
+
const token = process.env.X_TOKEN || ''
|
|
96
|
+
console.log('X_TOKEN:', token)
|
|
97
|
+
if (token === '') {
|
|
98
|
+
throw new Error('X_TOKEN environment variable is not set')
|
|
99
|
+
}
|
|
100
|
+
const endpoint = `https://grpc-ams-3.erpc.global`
|
|
101
|
+
console.log('Connecting to', endpoint)
|
|
102
|
+
|
|
103
|
+
// @ts-ignore ignore
|
|
104
|
+
return new GeyserClient(endpoint, token, undefined)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const connect = async (retries: number = 0): Promise<void> => {
|
|
108
|
+
if (retries > maxRetries) {
|
|
109
|
+
throw new Error('Max retries reached')
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
try {
|
|
113
|
+
const client = createClient()
|
|
114
|
+
const version = await client.getVersion()
|
|
115
|
+
console.log('version: ', version)
|
|
116
|
+
const stream = await client.subscribe()
|
|
117
|
+
stream.on('data', async (data: any) => {
|
|
118
|
+
if (data.transaction !== undefined) {
|
|
119
|
+
const transaction = data.transaction
|
|
120
|
+
const txnSignature = transaction.transaction.signature
|
|
121
|
+
const tx = bs58.encode(new Uint8Array(txnSignature))
|
|
122
|
+
console.log('tx:', tx)
|
|
123
|
+
return
|
|
124
|
+
}
|
|
125
|
+
if (data.account === undefined) {
|
|
126
|
+
return
|
|
127
|
+
}
|
|
128
|
+
// console.log('data:', JSON.stringify(data, null, 2))
|
|
129
|
+
|
|
130
|
+
const accounts = data.account
|
|
131
|
+
const rawPubkey = accounts.account.pubkey
|
|
132
|
+
const rawTxnSignature = accounts.account.txnSignature
|
|
133
|
+
const pubkey = bs58.encode(new Uint8Array(rawPubkey))
|
|
134
|
+
const txnSignature = bs58.encode(new Uint8Array(rawTxnSignature))
|
|
135
|
+
console.log('pubkey:', pubkey)
|
|
136
|
+
console.log('txnSignature:', txnSignature)
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
stream.on('error', async (e: any) => {
|
|
140
|
+
console.error('Stream error:', e)
|
|
141
|
+
console.log(`Reconnecting ...`)
|
|
142
|
+
await connect(retries + 1)
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
await new Promise<void>((resolve, reject) => {
|
|
146
|
+
stream.write(request, (err: any) => {
|
|
147
|
+
if (!err) {
|
|
148
|
+
resolve()
|
|
149
|
+
} else {
|
|
150
|
+
console.error('Request error:', err)
|
|
151
|
+
reject(err)
|
|
152
|
+
}
|
|
153
|
+
})
|
|
154
|
+
}).catch((reason) => {
|
|
155
|
+
console.error(reason)
|
|
156
|
+
throw reason
|
|
157
|
+
})
|
|
158
|
+
} catch (error) {
|
|
159
|
+
console.error(`Connection failed. Retrying ...`, error)
|
|
160
|
+
await connect(retries + 1)
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
await connect()
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const main = async () => {
|
|
168
|
+
try {
|
|
169
|
+
await geyser()
|
|
170
|
+
} catch (error) {
|
|
171
|
+
console.log(error)
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
main()
|
|
176
|
+
```
|
|
28
177
|
|
|
29
|
-
|
|
30
|
-
const client = new GeyserClient('https://your-geyser-endpoint')
|
|
178
|
+
Please ensure you have the `X_TOKEN` environment variable set with your gRPC token for authentication.
|
|
31
179
|
|
|
32
|
-
|
|
33
|
-
const decoded = bs58.decode('base58string')
|
|
34
|
-
const encoded = bs58.encode(buffer)
|
|
35
|
-
```
|
|
180
|
+
Please note that the url endpoint in the example is for demonstration purposes. You should replace it with the actual endpoint you are using.
|
|
36
181
|
|
|
37
182
|
## Features
|
|
38
183
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@validators-dao/solana-stream-sdk",
|
|
3
3
|
"description": "Solana Stream SDK by Validators DAO",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.2.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"format": "prettier --write ."
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@triton-one/yellowstone-grpc": "
|
|
35
|
-
"bs58": "
|
|
34
|
+
"@triton-one/yellowstone-grpc": "4.0.2",
|
|
35
|
+
"bs58": "6.0.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"prettier": "3.5.3",
|