@subsquid/solana-stream 0.0.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 +4 -0
- package/lib/archive/schema.d.ts +167 -0
- package/lib/archive/schema.d.ts.map +1 -0
- package/lib/archive/schema.js +117 -0
- package/lib/archive/schema.js.map +1 -0
- package/lib/archive/source.d.ts +15 -0
- package/lib/archive/source.d.ts.map +1 -0
- package/lib/archive/source.js +98 -0
- package/lib/archive/source.js.map +1 -0
- package/lib/data/fields.d.ts +8 -0
- package/lib/data/fields.d.ts.map +1 -0
- package/lib/data/fields.js +47 -0
- package/lib/data/fields.js.map +1 -0
- package/lib/data/model.d.ts +79 -0
- package/lib/data/model.d.ts.map +1 -0
- package/lib/data/model.js +44 -0
- package/lib/data/model.js.map +1 -0
- package/lib/data/partial.d.ts +26 -0
- package/lib/data/partial.d.ts.map +1 -0
- package/lib/data/partial.js +3 -0
- package/lib/data/partial.js.map +1 -0
- package/lib/data/request.d.ts +104 -0
- package/lib/data/request.d.ts.map +1 -0
- package/lib/data/request.js +3 -0
- package/lib/data/request.js.map +1 -0
- package/lib/data/type-util.d.ts +20 -0
- package/lib/data/type-util.d.ts.map +1 -0
- package/lib/data/type-util.js +3 -0
- package/lib/data/type-util.js.map +1 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +21 -0
- package/lib/index.js.map +1 -0
- package/lib/instruction.d.ts +13 -0
- package/lib/instruction.d.ts.map +1 -0
- package/lib/instruction.js +24 -0
- package/lib/instruction.js.map +1 -0
- package/lib/rpc/client.d.ts +17 -0
- package/lib/rpc/client.d.ts.map +1 -0
- package/lib/rpc/client.js +15 -0
- package/lib/rpc/client.js.map +1 -0
- package/lib/rpc/filter.d.ts +4 -0
- package/lib/rpc/filter.d.ts.map +1 -0
- package/lib/rpc/filter.js +337 -0
- package/lib/rpc/filter.js.map +1 -0
- package/lib/rpc/mapping.d.ts +5 -0
- package/lib/rpc/mapping.d.ts.map +1 -0
- package/lib/rpc/mapping.js +13 -0
- package/lib/rpc/mapping.js.map +1 -0
- package/lib/rpc/project.d.ts +5 -0
- package/lib/rpc/project.d.ts.map +1 -0
- package/lib/rpc/project.js +61 -0
- package/lib/rpc/project.js.map +1 -0
- package/lib/rpc/source.d.ts +15 -0
- package/lib/rpc/source.d.ts.map +1 -0
- package/lib/rpc/source.js +82 -0
- package/lib/rpc/source.js.map +1 -0
- package/lib/source.d.ts +107 -0
- package/lib/source.d.ts.map +1 -0
- package/lib/source.js +280 -0
- package/lib/source.js.map +1 -0
- package/package.json +38 -0
- package/src/archive/schema.ts +137 -0
- package/src/archive/source.ts +105 -0
- package/src/data/fields.ts +50 -0
- package/src/data/model.ts +154 -0
- package/src/data/partial.ts +31 -0
- package/src/data/request.ts +138 -0
- package/src/data/type-util.ts +42 -0
- package/src/index.ts +4 -0
- package/src/instruction.ts +28 -0
- package/src/rpc/client.ts +26 -0
- package/src/rpc/filter.ts +351 -0
- package/src/rpc/mapping.ts +13 -0
- package/src/rpc/project.ts +61 -0
- package/src/rpc/source.ts +90 -0
- package/src/source.ts +392 -0
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@subsquid/solana-stream",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"description": "Solana block data streamer",
|
|
5
|
+
"license": "GPL-3.0-or-later",
|
|
6
|
+
"repository": "git@github.com:subsquid/squid.git",
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"access": "public"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"lib",
|
|
12
|
+
"src"
|
|
13
|
+
],
|
|
14
|
+
"main": "lib/index.js",
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@subsquid/http-client": "^1.4.0",
|
|
17
|
+
"@subsquid/logger": "^1.3.3",
|
|
18
|
+
"@subsquid/rpc-client": "^4.9.0",
|
|
19
|
+
"@subsquid/solana-normalization": "^0.0.0",
|
|
20
|
+
"@subsquid/solana-rpc": "^0.0.0",
|
|
21
|
+
"@subsquid/solana-rpc-data": "^0.0.0",
|
|
22
|
+
"@subsquid/util-internal": "^3.2.0",
|
|
23
|
+
"@subsquid/util-internal-archive-client": "^0.1.2",
|
|
24
|
+
"@subsquid/util-internal-hex": "^1.2.2",
|
|
25
|
+
"@subsquid/util-internal-ingest-tools": "^1.1.2",
|
|
26
|
+
"@subsquid/util-internal-processor-tools": "^4.1.1",
|
|
27
|
+
"@subsquid/util-internal-range": "^0.3.0",
|
|
28
|
+
"@subsquid/util-internal-validation": "^0.4.0",
|
|
29
|
+
"bs58": "^5.0.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/node": "^18.18.14",
|
|
33
|
+
"typescript": "~5.3.2"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "rm -rf lib && tsc"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import {AddressTableLookup} from '@subsquid/solana-rpc-data'
|
|
2
|
+
import {weakMemo} from '@subsquid/util-internal'
|
|
3
|
+
import {
|
|
4
|
+
ANY_OBJECT,
|
|
5
|
+
array,
|
|
6
|
+
B58,
|
|
7
|
+
BIG_NAT,
|
|
8
|
+
BOOLEAN,
|
|
9
|
+
BYTES,
|
|
10
|
+
constant,
|
|
11
|
+
NAT,
|
|
12
|
+
nullable,
|
|
13
|
+
object,
|
|
14
|
+
oneOf,
|
|
15
|
+
option,
|
|
16
|
+
STRING
|
|
17
|
+
} from '@subsquid/util-internal-validation'
|
|
18
|
+
import {project} from '../data/fields'
|
|
19
|
+
import {FieldSelection} from '../data/model'
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
export const getDataSchema = weakMemo((fields: FieldSelection) => {
|
|
23
|
+
let BlockHeader = object({
|
|
24
|
+
number: NAT,
|
|
25
|
+
hash: B58,
|
|
26
|
+
parentHash: B58,
|
|
27
|
+
...project(fields.block, {
|
|
28
|
+
slot: NAT,
|
|
29
|
+
parentSlot: NAT,
|
|
30
|
+
timestamp: NAT
|
|
31
|
+
})
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
let Transaction = object({
|
|
35
|
+
transactionIndex: NAT,
|
|
36
|
+
...project(fields.transaction, {
|
|
37
|
+
version: oneOf({
|
|
38
|
+
legacy: constant('legacy'),
|
|
39
|
+
versionNumber: NAT
|
|
40
|
+
}),
|
|
41
|
+
accountKeys: array(B58),
|
|
42
|
+
addressTableLookups: array(AddressTableLookup),
|
|
43
|
+
numReadonlySignedAccounts: NAT,
|
|
44
|
+
numReadonlyUnsignedAccounts: NAT,
|
|
45
|
+
numRequiredSignatures: NAT,
|
|
46
|
+
recentBlockhash: B58,
|
|
47
|
+
signatures: array(B58),
|
|
48
|
+
err: nullable(ANY_OBJECT),
|
|
49
|
+
computeUnitsConsumed: BIG_NAT,
|
|
50
|
+
fee: BIG_NAT,
|
|
51
|
+
loadedAddresses: option(object({
|
|
52
|
+
readonly: array(B58),
|
|
53
|
+
writable: array(B58)
|
|
54
|
+
})),
|
|
55
|
+
hasDroppedLogMessages: BOOLEAN
|
|
56
|
+
})
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
let Instruction = object({
|
|
60
|
+
transactionIndex: NAT,
|
|
61
|
+
instructionAddress: array(NAT),
|
|
62
|
+
...project(fields.instruction, {
|
|
63
|
+
programId: B58,
|
|
64
|
+
accounts: array(B58),
|
|
65
|
+
data: B58,
|
|
66
|
+
computeUnitsConsumed: option(BIG_NAT),
|
|
67
|
+
d1: BYTES,
|
|
68
|
+
d2: BYTES,
|
|
69
|
+
d4: BYTES,
|
|
70
|
+
d8: BYTES,
|
|
71
|
+
error: option(STRING),
|
|
72
|
+
isCommitted: BOOLEAN,
|
|
73
|
+
hasDroppedLogMessages: BOOLEAN
|
|
74
|
+
})
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
let LogMessage = object({
|
|
78
|
+
transactionIndex: NAT,
|
|
79
|
+
logIndex: NAT,
|
|
80
|
+
instructionAddress: array(NAT),
|
|
81
|
+
...project(fields.log, {
|
|
82
|
+
programId: B58,
|
|
83
|
+
kind: oneOf({
|
|
84
|
+
log: constant('log'),
|
|
85
|
+
data: constant('data'),
|
|
86
|
+
other: constant('other')
|
|
87
|
+
}),
|
|
88
|
+
message: STRING
|
|
89
|
+
})
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
let Balance = object({
|
|
93
|
+
transactionIndex: NAT,
|
|
94
|
+
account: B58,
|
|
95
|
+
...project(fields.balance, {
|
|
96
|
+
pre: BIG_NAT,
|
|
97
|
+
post: BIG_NAT
|
|
98
|
+
})
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
let TokenBalance = object({
|
|
102
|
+
transactionIndex: NAT,
|
|
103
|
+
account: B58,
|
|
104
|
+
...project(fields.tokenBalance, {
|
|
105
|
+
preProgramId: option(B58),
|
|
106
|
+
postProgramId: option(B58),
|
|
107
|
+
preMint: option(B58),
|
|
108
|
+
postMint: option(B58),
|
|
109
|
+
preDecimals: option(NAT),
|
|
110
|
+
postDecimals: option(NAT),
|
|
111
|
+
preOwner: option(B58),
|
|
112
|
+
postOwner: option(B58),
|
|
113
|
+
preAmount: option(BIG_NAT),
|
|
114
|
+
postAmount: option(BIG_NAT)
|
|
115
|
+
})
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
let Reward = object({
|
|
119
|
+
pubkey: B58,
|
|
120
|
+
...project(fields.reward, {
|
|
121
|
+
lamports: BIG_NAT,
|
|
122
|
+
postBalance: BIG_NAT,
|
|
123
|
+
rewardType: option(STRING),
|
|
124
|
+
commission: option(NAT)
|
|
125
|
+
})
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
return object({
|
|
129
|
+
header: BlockHeader,
|
|
130
|
+
transactions: option(array(Transaction)),
|
|
131
|
+
instructions: option(array(Instruction)),
|
|
132
|
+
logs: option(array(LogMessage)),
|
|
133
|
+
balances: option(array(Balance)),
|
|
134
|
+
tokenBalances: option(array(TokenBalance)),
|
|
135
|
+
rewards: option(array(Reward))
|
|
136
|
+
})
|
|
137
|
+
})
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import {BlockHeader} from '@subsquid/solana-normalization'
|
|
2
|
+
import {Base58Bytes} from '@subsquid/solana-rpc-data'
|
|
3
|
+
import {assertNotNull} from '@subsquid/util-internal'
|
|
4
|
+
import {ArchiveClient} from '@subsquid/util-internal-archive-client'
|
|
5
|
+
import {archiveIngest} from '@subsquid/util-internal-ingest-tools'
|
|
6
|
+
import {getRequestAt, mapRangeRequestList, RangeRequestList} from '@subsquid/util-internal-range'
|
|
7
|
+
import {array, cast} from '@subsquid/util-internal-validation'
|
|
8
|
+
import assert from 'assert'
|
|
9
|
+
import {PartialBlock} from '../data/partial'
|
|
10
|
+
import {DataRequest} from '../data/request'
|
|
11
|
+
import {getDataSchema} from './schema'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
export class SolanaArchive {
|
|
15
|
+
constructor(private client: ArchiveClient) {}
|
|
16
|
+
|
|
17
|
+
getFinalizedHeight(): Promise<number> {
|
|
18
|
+
return this.client.getHeight()
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async getBlockHash(height: number): Promise<Base58Bytes | undefined> {
|
|
22
|
+
let blocks = await this.client.query({
|
|
23
|
+
type: 'solana',
|
|
24
|
+
fromBlock: height,
|
|
25
|
+
toBlock: height,
|
|
26
|
+
includeAllBlocks: true
|
|
27
|
+
})
|
|
28
|
+
assert(blocks.length == 1)
|
|
29
|
+
return blocks[0].header.hash
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async getBlockHeader(height: number): Promise<BlockHeader> {
|
|
33
|
+
let blocks = await this.client.query({
|
|
34
|
+
type: 'solana',
|
|
35
|
+
fromBlock: height,
|
|
36
|
+
toBlock: height,
|
|
37
|
+
includeAllBlocks: true,
|
|
38
|
+
fields: {
|
|
39
|
+
block: {
|
|
40
|
+
slot: true,
|
|
41
|
+
parentSlot: true,
|
|
42
|
+
parentHash: true,
|
|
43
|
+
timestamp: true
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
})
|
|
47
|
+
assert(blocks.length == 1)
|
|
48
|
+
let {number, ...rest} = blocks[0].header
|
|
49
|
+
return {
|
|
50
|
+
height: number,
|
|
51
|
+
...rest
|
|
52
|
+
} as BlockHeader
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async *getBlockStream(requests: RangeRequestList<DataRequest>, stopOnHead?: boolean | undefined): AsyncIterable<PartialBlock[]> {
|
|
56
|
+
let archiveRequests = mapRangeRequestList(requests, req => {
|
|
57
|
+
let {fields, includeAllBlocks, ...items} = req
|
|
58
|
+
let archiveItems: any = {}
|
|
59
|
+
let key: keyof typeof items
|
|
60
|
+
for (key in items) {
|
|
61
|
+
archiveItems[key] = items[key]?.map(it => ({...it.where, ...it.include}))
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
type: 'solana',
|
|
65
|
+
fields: {
|
|
66
|
+
block: {parentHash: true, ...fields?.block},
|
|
67
|
+
transaction: fields?.transaction,
|
|
68
|
+
instruction: fields?.instruction,
|
|
69
|
+
log: {instructionAddress: true, ...fields?.log},
|
|
70
|
+
balance: fields?.balance,
|
|
71
|
+
tokenBalance: fields?.tokenBalance,
|
|
72
|
+
reward: fields?.reward
|
|
73
|
+
},
|
|
74
|
+
includeAllBlocks,
|
|
75
|
+
...archiveItems
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
for await (let batch of archiveIngest({
|
|
80
|
+
client: this.client,
|
|
81
|
+
requests: archiveRequests,
|
|
82
|
+
stopOnHead
|
|
83
|
+
})) {
|
|
84
|
+
let req = getRequestAt(requests, batch.blocks[0].header.number)
|
|
85
|
+
|
|
86
|
+
let blocks = cast(
|
|
87
|
+
array(getDataSchema(assertNotNull(req?.fields))),
|
|
88
|
+
batch.blocks
|
|
89
|
+
).map(b => {
|
|
90
|
+
let {header: {number, ...hdr}, ...items} = b
|
|
91
|
+
return {
|
|
92
|
+
header: {height: number, ...hdr},
|
|
93
|
+
transactions: items.transactions || [],
|
|
94
|
+
instructions: items.instructions || [],
|
|
95
|
+
logs: items.logs || [],
|
|
96
|
+
balances: items.balances || [],
|
|
97
|
+
tokenBalances: items.tokenBalances || [],
|
|
98
|
+
rewards: items.rewards || []
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
yield blocks
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import {DEFAULT_FIELDS, FieldSelection} from './model'
|
|
2
|
+
import {Selector} from './type-util'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Get effective set of selected fields.
|
|
7
|
+
*/
|
|
8
|
+
export function getFields(fields: FieldSelection | undefined): FieldSelection {
|
|
9
|
+
return {
|
|
10
|
+
block: merge(DEFAULT_FIELDS.block, fields?.block),
|
|
11
|
+
transaction: merge(DEFAULT_FIELDS.transaction, fields?.transaction),
|
|
12
|
+
instruction: merge(DEFAULT_FIELDS.instruction, fields?.instruction),
|
|
13
|
+
log: merge(DEFAULT_FIELDS.log, fields?.log),
|
|
14
|
+
balance: merge(DEFAULT_FIELDS.balance, fields?.balance),
|
|
15
|
+
tokenBalance: merge(DEFAULT_FIELDS.tokenBalance, fields?.tokenBalance),
|
|
16
|
+
reward: merge(DEFAULT_FIELDS.reward, fields?.reward)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
function merge<Keys extends string>(def: Selector<Keys>, requested: Selector<Keys> = {}): Selector<Keys> {
|
|
22
|
+
let fields: Selector<Keys> = {}
|
|
23
|
+
|
|
24
|
+
for (let key in def) {
|
|
25
|
+
if (requested[key] !== false) {
|
|
26
|
+
fields[key] = def[key]
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
for (let key in requested) {
|
|
31
|
+
if (requested[key]) {
|
|
32
|
+
fields[key] = true
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return fields
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
export function project<T>(fields: Selector<keyof T> | undefined, obj: T): Partial<T> {
|
|
41
|
+
if (fields == null) return {}
|
|
42
|
+
let result: Partial<T> = {}
|
|
43
|
+
let key: keyof T
|
|
44
|
+
for (key in obj) {
|
|
45
|
+
if (fields[key]) {
|
|
46
|
+
result[key] = obj[key]
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return result
|
|
50
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import type * as data from '@subsquid/solana-normalization'
|
|
2
|
+
import type {
|
|
3
|
+
BalanceRequiredFields,
|
|
4
|
+
BlockRequiredFields,
|
|
5
|
+
InstructionRequiredFields,
|
|
6
|
+
LogRequiredFields,
|
|
7
|
+
RewardRequiredFields,
|
|
8
|
+
TokenBalanceRequiredFields,
|
|
9
|
+
TransactionRequiredFields
|
|
10
|
+
} from './partial'
|
|
11
|
+
import type {GetFields, Select, Selector, Simplify} from './type-util'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Hex encoded binary string
|
|
16
|
+
*/
|
|
17
|
+
export type Bytes = string
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Base58 encoded binary string
|
|
22
|
+
*/
|
|
23
|
+
export type Base58Bytes = string
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
export interface FieldSelection {
|
|
27
|
+
block?: Selector<Exclude<keyof data.BlockHeader, BlockRequiredFields>>
|
|
28
|
+
transaction?: Selector<Exclude<keyof data.Transaction, TransactionRequiredFields>>
|
|
29
|
+
instruction?: Selector<Exclude<keyof data.Instruction, InstructionRequiredFields>>
|
|
30
|
+
log?: Selector<Exclude<keyof data.LogMessage, LogRequiredFields>>
|
|
31
|
+
balance?: Selector<Exclude<keyof data.Balance, BalanceRequiredFields>>
|
|
32
|
+
tokenBalance?: Selector<Exclude<keyof data.TokenBalance, TokenBalanceRequiredFields>>
|
|
33
|
+
reward?: Selector<Exclude<keyof data.Reward, RewardRequiredFields>>
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
export const DEFAULT_FIELDS = {
|
|
38
|
+
block: {
|
|
39
|
+
slot: true,
|
|
40
|
+
parentSlot: true,
|
|
41
|
+
timestamp: true
|
|
42
|
+
},
|
|
43
|
+
transaction: {
|
|
44
|
+
signatures: true,
|
|
45
|
+
err: true
|
|
46
|
+
},
|
|
47
|
+
instruction: {
|
|
48
|
+
programId: true,
|
|
49
|
+
accounts: true,
|
|
50
|
+
data: true,
|
|
51
|
+
isCommitted: true
|
|
52
|
+
},
|
|
53
|
+
log: {
|
|
54
|
+
programId: true,
|
|
55
|
+
kind: true,
|
|
56
|
+
message: true
|
|
57
|
+
},
|
|
58
|
+
balance: {
|
|
59
|
+
pre: true,
|
|
60
|
+
post: true
|
|
61
|
+
},
|
|
62
|
+
tokenBalance: {
|
|
63
|
+
preMint: true,
|
|
64
|
+
preDecimals: true,
|
|
65
|
+
preOwner: true,
|
|
66
|
+
preAmount: true,
|
|
67
|
+
postMint: true,
|
|
68
|
+
postDecimals: true,
|
|
69
|
+
postOwner: true,
|
|
70
|
+
postAmount: true
|
|
71
|
+
},
|
|
72
|
+
reward: {
|
|
73
|
+
lamports: true,
|
|
74
|
+
rewardType: true
|
|
75
|
+
}
|
|
76
|
+
} as const
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
type Item<
|
|
80
|
+
Data,
|
|
81
|
+
RequiredFields extends keyof Data,
|
|
82
|
+
F extends FieldSelection,
|
|
83
|
+
K extends keyof FieldSelection
|
|
84
|
+
> = Simplify<
|
|
85
|
+
Pick<Data, RequiredFields> &
|
|
86
|
+
Select<Data, GetFields<FieldSelection, typeof DEFAULT_FIELDS, F, K>>
|
|
87
|
+
>
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
export type BlockHeader<F extends FieldSelection = {}> = Item<
|
|
91
|
+
data.BlockHeader,
|
|
92
|
+
BlockRequiredFields,
|
|
93
|
+
F,
|
|
94
|
+
'block'
|
|
95
|
+
>
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
export type Transaction<F extends FieldSelection = {}> = Item<
|
|
99
|
+
data.Transaction,
|
|
100
|
+
TransactionRequiredFields,
|
|
101
|
+
F,
|
|
102
|
+
'transaction'
|
|
103
|
+
>
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
export type Instruction<F extends FieldSelection = {}> = Item<
|
|
107
|
+
data.Instruction,
|
|
108
|
+
InstructionRequiredFields,
|
|
109
|
+
F,
|
|
110
|
+
'instruction'
|
|
111
|
+
>
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
export type LogMessage<F extends FieldSelection = {}> = Item<
|
|
115
|
+
data.LogMessage,
|
|
116
|
+
LogRequiredFields,
|
|
117
|
+
F,
|
|
118
|
+
'log'
|
|
119
|
+
>
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
export type Balance<F extends FieldSelection = {}> = Item<
|
|
123
|
+
data.Balance,
|
|
124
|
+
BalanceRequiredFields,
|
|
125
|
+
F,
|
|
126
|
+
'balance'
|
|
127
|
+
>
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
export type TokenBalance<F extends FieldSelection = {}> = Item<
|
|
131
|
+
data.TokenBalance,
|
|
132
|
+
TokenBalanceRequiredFields,
|
|
133
|
+
F,
|
|
134
|
+
'tokenBalance'
|
|
135
|
+
>
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
export type Reward<F extends FieldSelection = {}> = Item<
|
|
139
|
+
data.Reward,
|
|
140
|
+
RewardRequiredFields,
|
|
141
|
+
F,
|
|
142
|
+
'reward'
|
|
143
|
+
>
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
export interface Block<F extends FieldSelection = {}> {
|
|
147
|
+
header: BlockHeader<F>
|
|
148
|
+
transactions: Transaction<F>[]
|
|
149
|
+
instructions: Instruction<F>[]
|
|
150
|
+
logs: LogMessage<F>[]
|
|
151
|
+
balances: Balance<F>[]
|
|
152
|
+
tokenBalances: TokenBalance<F>[]
|
|
153
|
+
rewards: Reward<F>[]
|
|
154
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type * as data from '@subsquid/solana-normalization'
|
|
2
|
+
import type {MakePartial} from './type-util'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export type BlockRequiredFields = 'height' | 'hash' | 'parentHash'
|
|
6
|
+
export type TransactionRequiredFields = 'transactionIndex'
|
|
7
|
+
export type InstructionRequiredFields = 'transactionIndex' | 'instructionAddress'
|
|
8
|
+
export type LogRequiredFields = 'transactionIndex' | 'logIndex' | 'instructionAddress'
|
|
9
|
+
export type BalanceRequiredFields = 'transactionIndex' | 'account'
|
|
10
|
+
export type TokenBalanceRequiredFields = 'transactionIndex' | 'account'
|
|
11
|
+
export type RewardRequiredFields = 'pubkey'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
export type PartialBlockHeader = MakePartial<data.BlockHeader, BlockRequiredFields>
|
|
15
|
+
export type PartialTransaction = MakePartial<data.Transaction, TransactionRequiredFields>
|
|
16
|
+
export type PartialInstruction = MakePartial<data.Instruction, InstructionRequiredFields>
|
|
17
|
+
export type PartialLogMessage = MakePartial<data.LogMessage, LogRequiredFields>
|
|
18
|
+
export type PartialBalance = MakePartial<data.Balance, BalanceRequiredFields>
|
|
19
|
+
export type PartialTokenBalance = MakePartial<data.PrePostTokenBalance, TokenBalanceRequiredFields>
|
|
20
|
+
export type PartialReward = MakePartial<data.Reward, RewardRequiredFields>
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
export interface PartialBlock {
|
|
24
|
+
header: PartialBlockHeader
|
|
25
|
+
transactions: PartialTransaction[]
|
|
26
|
+
instructions: PartialInstruction[]
|
|
27
|
+
logs: PartialLogMessage[]
|
|
28
|
+
balances: PartialBalance[]
|
|
29
|
+
tokenBalances: PartialTokenBalance[]
|
|
30
|
+
rewards: PartialReward[]
|
|
31
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import {Base58Bytes} from '@subsquid/solana-rpc'
|
|
2
|
+
import {LogMessage} from '@subsquid/solana-normalization'
|
|
3
|
+
import {FieldSelection} from './model'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
export interface DataRequest {
|
|
7
|
+
fields?: FieldSelection
|
|
8
|
+
includeAllBlocks?: boolean
|
|
9
|
+
transactions?: TransactionRequest[]
|
|
10
|
+
instructions?: InstructionRequest[]
|
|
11
|
+
logs?: LogRequest[]
|
|
12
|
+
balances?: BalanceRequest[]
|
|
13
|
+
tokenBalances?: TokenBalanceRequest[]
|
|
14
|
+
rewards?: RewardRequest[]
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
export interface TransactionRequest {
|
|
19
|
+
where?: TransactionRequestWhere
|
|
20
|
+
include?: TransactionRequestRelations
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
export interface TransactionRequestWhere {
|
|
25
|
+
feePayer?: Base58Bytes[]
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
export interface TransactionRequestRelations {
|
|
30
|
+
instructions?: boolean
|
|
31
|
+
logs?: boolean
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Hex encoded prefix of instruction data
|
|
36
|
+
*/
|
|
37
|
+
export type Discriminator = string
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
export interface InstructionRequest {
|
|
41
|
+
where?: InstructionRequestWhere
|
|
42
|
+
include?: InstructionRequestRelations
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
export interface InstructionRequestWhere {
|
|
47
|
+
programId?: Base58Bytes[]
|
|
48
|
+
d1?: Discriminator[]
|
|
49
|
+
d2?: Discriminator[]
|
|
50
|
+
d3?: Discriminator[]
|
|
51
|
+
d4?: Discriminator[]
|
|
52
|
+
d8?: Discriminator[]
|
|
53
|
+
a0?: Base58Bytes[]
|
|
54
|
+
a1?: Base58Bytes[]
|
|
55
|
+
a2?: Base58Bytes[]
|
|
56
|
+
a3?: Base58Bytes[]
|
|
57
|
+
a4?: Base58Bytes[]
|
|
58
|
+
a5?: Base58Bytes[]
|
|
59
|
+
a6?: Base58Bytes[]
|
|
60
|
+
a7?: Base58Bytes[]
|
|
61
|
+
a8?: Base58Bytes[]
|
|
62
|
+
a9?: Base58Bytes[]
|
|
63
|
+
isCommitted?: boolean
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
export interface InstructionRequestRelations {
|
|
68
|
+
transaction?: boolean
|
|
69
|
+
transactionTokenBalances?: boolean
|
|
70
|
+
logs?: boolean
|
|
71
|
+
innerInstructions?: boolean
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
export interface LogRequest {
|
|
76
|
+
where?: LogRequestWhere
|
|
77
|
+
include?: LogRequestRelations
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
export interface LogRequestWhere {
|
|
82
|
+
programId?: Base58Bytes[]
|
|
83
|
+
kind?: LogMessage['kind'][]
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
export interface LogRequestRelations {
|
|
88
|
+
transaction?: boolean
|
|
89
|
+
instruction?: boolean
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
export interface BalanceRequest {
|
|
94
|
+
where?: BalanceRequestWhere
|
|
95
|
+
include?: BalanceRequestRelations
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
export interface BalanceRequestWhere {
|
|
100
|
+
account?: Base58Bytes[]
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
export interface BalanceRequestRelations {
|
|
105
|
+
transaction?: boolean
|
|
106
|
+
transactionInstructions?: boolean
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
export interface TokenBalanceRequest {
|
|
111
|
+
where?: TokenBalanceRequestWhere
|
|
112
|
+
include?: TokenBalanceRequestRelations
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
export interface TokenBalanceRequestWhere {
|
|
117
|
+
account?: Base58Bytes[]
|
|
118
|
+
preProgramId?: Base58Bytes[]
|
|
119
|
+
postProgramId?: Base58Bytes[]
|
|
120
|
+
preMint?: Base58Bytes[]
|
|
121
|
+
postMint?: Base58Bytes[]
|
|
122
|
+
preOwner?: Base58Bytes[]
|
|
123
|
+
postOwner?: Base58Bytes[]
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
export interface TokenBalanceRequestRelations {
|
|
128
|
+
transaction?: boolean
|
|
129
|
+
transactionInstructions?: boolean
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
export interface RewardRequest {
|
|
134
|
+
where?: {
|
|
135
|
+
pubkey?: Base58Bytes[]
|
|
136
|
+
}
|
|
137
|
+
include?: undefined
|
|
138
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export type Simplify<T> = {
|
|
2
|
+
[K in keyof T]: T[K]
|
|
3
|
+
} & {}
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
export type ExcludeUndefined<T> = {
|
|
7
|
+
[K in keyof T as undefined extends T[K] ? never : K]: T[K]
|
|
8
|
+
} & {}
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
export type GetFields<
|
|
12
|
+
FieldSelectionType,
|
|
13
|
+
Defaults extends FieldSelectionType,
|
|
14
|
+
Selection extends FieldSelectionType,
|
|
15
|
+
K extends keyof FieldSelectionType
|
|
16
|
+
> = TrueFields<MergeDefault<Selection[K], Defaults[K]>>
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
type MergeDefault<T, D> = Simplify<
|
|
20
|
+
undefined extends T ? D : Omit<D, keyof ExcludeUndefined<T>> & ExcludeUndefined<T>
|
|
21
|
+
>
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
type TrueFields<F> = keyof {
|
|
25
|
+
[K in keyof F as true extends F[K] ? K : never]: true
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
export type Select<T, Fields> = T extends any ? Simplify<Pick<T, Extract<keyof T, Fields>>> : never
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
export type Selector<Fields extends string | number | symbol> = {
|
|
33
|
+
[P in Fields]?: boolean
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
export type MakePartial<T, Required extends keyof T> = Simplify<
|
|
38
|
+
Pick<T, Required> &
|
|
39
|
+
{
|
|
40
|
+
[K in keyof T as K extends Required ? never : K]+?: T[K]
|
|
41
|
+
}
|
|
42
|
+
>
|
package/src/index.ts
ADDED