@0xobelisk/graphql-client 1.2.0-pre.99 → 2.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/LICENSE +92 -0
- package/dist/client.d.ts +121 -1
- package/dist/decoders.d.ts +24 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +660 -16
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +647 -15
- package/dist/index.mjs.map +1 -1
- package/dist/types.d.ts +113 -0
- package/package.json +21 -21
- package/src/client.ts +688 -18
- package/src/decoders.ts +100 -0
- package/src/index.ts +1 -0
- package/src/types.ts +120 -0
package/src/client.ts
CHANGED
|
@@ -11,12 +11,98 @@ import {
|
|
|
11
11
|
FetchPolicy,
|
|
12
12
|
OperationVariables
|
|
13
13
|
} from '@apollo/client';
|
|
14
|
+
import { BatchHttpLink } from '@apollo/client/link/batch-http';
|
|
14
15
|
import { RetryLink } from '@apollo/client/link/retry';
|
|
15
16
|
import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
|
|
16
17
|
import { getMainDefinition } from '@apollo/client/utilities';
|
|
17
18
|
import { createClient } from 'graphql-ws';
|
|
18
19
|
import pluralize from 'pluralize';
|
|
19
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Static field registry for Dubhe system tables.
|
|
23
|
+
*
|
|
24
|
+
* These tables are exposed via `store_dubhe_*` views in the graphql-server.
|
|
25
|
+
* They are NOT in the DApp's dubhe.config schema, so `convertTableFields`
|
|
26
|
+
* cannot auto-discover their fields. Registering them here means callers
|
|
27
|
+
* can use `getAllTables('dubheDappMarketplaceFees', ...)` without passing
|
|
28
|
+
* `fields` explicitly.
|
|
29
|
+
*
|
|
30
|
+
* Key: the simplified GraphQL field name (after SimpleNamingPlugin strips
|
|
31
|
+
* the `storeDubhe` prefix and removes the `all` prefix).
|
|
32
|
+
* Value: camelCase GraphQL field names matching the PostGraphile schema.
|
|
33
|
+
*/
|
|
34
|
+
const SYSTEM_TABLE_FIELDS: Record<string, string[]> = {
|
|
35
|
+
dubheDappMarketplaceFees: [
|
|
36
|
+
'dappKey',
|
|
37
|
+
'listingId',
|
|
38
|
+
'coinType',
|
|
39
|
+
'totalFee',
|
|
40
|
+
'treasuryAmount',
|
|
41
|
+
'dappAmount',
|
|
42
|
+
'updatedAtCheckpoint',
|
|
43
|
+
'lastUpdateDigest'
|
|
44
|
+
],
|
|
45
|
+
dubheDappRuntimeState: [
|
|
46
|
+
'dappKey',
|
|
47
|
+
'admin',
|
|
48
|
+
'paused',
|
|
49
|
+
'settlementMode',
|
|
50
|
+
'creditPool',
|
|
51
|
+
'writeFeeShareBps',
|
|
52
|
+
'lastRuntimeEvent',
|
|
53
|
+
'lastRuntimeActor',
|
|
54
|
+
'lastRuntimeAmount',
|
|
55
|
+
'updatedAtCheckpoint',
|
|
56
|
+
'lastUpdateDigest'
|
|
57
|
+
],
|
|
58
|
+
dubheDappFeeState: [
|
|
59
|
+
'entityId',
|
|
60
|
+
'baseFeePerWrite',
|
|
61
|
+
'bytesFeePerByte',
|
|
62
|
+
'freeCredit',
|
|
63
|
+
'creditPool',
|
|
64
|
+
'totalSettled',
|
|
65
|
+
'updatedAtTimestampMs',
|
|
66
|
+
'lastUpdateDigest'
|
|
67
|
+
],
|
|
68
|
+
dubheDappRevenueState: [
|
|
69
|
+
'entityId',
|
|
70
|
+
'dappRevenue',
|
|
71
|
+
'coinType',
|
|
72
|
+
'updatedAtTimestampMs',
|
|
73
|
+
'lastUpdateDigest'
|
|
74
|
+
],
|
|
75
|
+
dubheMarketplaceListings: [
|
|
76
|
+
'dappKey',
|
|
77
|
+
'listingId',
|
|
78
|
+
'seller',
|
|
79
|
+
'recordType',
|
|
80
|
+
'price',
|
|
81
|
+
'coinType',
|
|
82
|
+
'isFungible',
|
|
83
|
+
'listedUntil',
|
|
84
|
+
'status',
|
|
85
|
+
'updatedAtCheckpoint',
|
|
86
|
+
'lastUpdateDigest'
|
|
87
|
+
],
|
|
88
|
+
dubheSessions: [
|
|
89
|
+
'dappKey',
|
|
90
|
+
'canonical',
|
|
91
|
+
'sessionWallet',
|
|
92
|
+
'expiresAt',
|
|
93
|
+
'active',
|
|
94
|
+
'updatedAtCheckpoint',
|
|
95
|
+
'lastUpdateDigest'
|
|
96
|
+
],
|
|
97
|
+
dubheUserStorages: [
|
|
98
|
+
'dappKey',
|
|
99
|
+
'canonicalOwner',
|
|
100
|
+
'userStorageId',
|
|
101
|
+
'updatedAtCheckpoint',
|
|
102
|
+
'lastUpdateDigest'
|
|
103
|
+
]
|
|
104
|
+
};
|
|
105
|
+
|
|
20
106
|
import {
|
|
21
107
|
DubheClientConfig,
|
|
22
108
|
Connection,
|
|
@@ -32,7 +118,14 @@ import {
|
|
|
32
118
|
MultiTableSubscriptionConfig,
|
|
33
119
|
MultiTableSubscriptionData,
|
|
34
120
|
ParsedTableInfo,
|
|
35
|
-
DubheMetadata
|
|
121
|
+
DubheMetadata,
|
|
122
|
+
MarketplaceListingRow,
|
|
123
|
+
DubheSessionRow,
|
|
124
|
+
DubheUserStorageRow,
|
|
125
|
+
DubheDappRuntimeStateRow,
|
|
126
|
+
SceneStorageRow,
|
|
127
|
+
SceneStorageFieldRow,
|
|
128
|
+
ObjectStorageRow
|
|
36
129
|
} from './types';
|
|
37
130
|
|
|
38
131
|
// Convert cache policy type
|
|
@@ -53,6 +146,37 @@ function mapCachePolicyToFetchPolicy(cachePolicy: CachePolicy): FetchPolicy {
|
|
|
53
146
|
}
|
|
54
147
|
}
|
|
55
148
|
|
|
149
|
+
/**
|
|
150
|
+
* Build the HTTP transport link.
|
|
151
|
+
*
|
|
152
|
+
* When `config.batchRequests` is true, returns a `BatchHttpLink` that collects
|
|
153
|
+
* queries fired within `batchInterval` ms (default 10 ms) and sends them as a
|
|
154
|
+
* single POST request. The PostGraphile server already has `enableQueryBatching`
|
|
155
|
+
* enabled, so no server-side changes are needed.
|
|
156
|
+
*
|
|
157
|
+
* Falls back to the standard `createHttpLink` when batching is disabled.
|
|
158
|
+
*/
|
|
159
|
+
function buildHttpLink(config: DubheClientConfig): ApolloLink {
|
|
160
|
+
const fetchFn = (input: RequestInfo | URL, init?: RequestInit) =>
|
|
161
|
+
fetch(input, { ...config.fetchOptions, ...(init ?? {}) });
|
|
162
|
+
|
|
163
|
+
if (config.batchRequests) {
|
|
164
|
+
return new BatchHttpLink({
|
|
165
|
+
uri: config.endpoint,
|
|
166
|
+
headers: config.headers,
|
|
167
|
+
fetch: fetchFn,
|
|
168
|
+
batchInterval: config.batchInterval ?? 10,
|
|
169
|
+
batchMax: config.batchMax ?? 20
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return createHttpLink({
|
|
174
|
+
uri: config.endpoint,
|
|
175
|
+
headers: config.headers,
|
|
176
|
+
fetch: fetchFn
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|
|
56
180
|
export class DubheGraphqlClient {
|
|
57
181
|
private apolloClient: ApolloClient<NormalizedCacheObject>;
|
|
58
182
|
private subscriptionClient?: any;
|
|
@@ -73,12 +197,8 @@ export class DubheGraphqlClient {
|
|
|
73
197
|
this.parseTableInfoFromConfig();
|
|
74
198
|
}
|
|
75
199
|
|
|
76
|
-
// Create HTTP
|
|
77
|
-
const httpLink =
|
|
78
|
-
uri: config.endpoint,
|
|
79
|
-
headers: config.headers,
|
|
80
|
-
fetch: (input, init) => fetch(input, { ...config.fetchOptions, ...init })
|
|
81
|
-
});
|
|
200
|
+
// Create HTTP link (batched or standard depending on config.batchRequests)
|
|
201
|
+
const httpLink = buildHttpLink(config);
|
|
82
202
|
|
|
83
203
|
// Create retry link
|
|
84
204
|
const retryLink = new RetryLink({
|
|
@@ -244,12 +364,8 @@ export class DubheGraphqlClient {
|
|
|
244
364
|
this.subscriptionClient = undefined;
|
|
245
365
|
}
|
|
246
366
|
|
|
247
|
-
// Recreate HTTP
|
|
248
|
-
const httpLink =
|
|
249
|
-
uri: this.currentConfig.endpoint,
|
|
250
|
-
headers: this.currentConfig.headers,
|
|
251
|
-
fetch: (input, init) => fetch(input, { ...this.currentConfig.fetchOptions, ...init })
|
|
252
|
-
});
|
|
367
|
+
// Recreate HTTP link (batched or standard depending on config)
|
|
368
|
+
const httpLink = buildHttpLink(this.currentConfig);
|
|
253
369
|
|
|
254
370
|
// Recreate retry link with current config
|
|
255
371
|
const retryLink = new RetryLink({
|
|
@@ -883,6 +999,480 @@ export class DubheGraphqlClient {
|
|
|
883
999
|
});
|
|
884
1000
|
}
|
|
885
1001
|
|
|
1002
|
+
/**
|
|
1003
|
+
* Query marketplace listings indexed by the Dubhe indexer.
|
|
1004
|
+
* Uses the marketplace_listings PostgreSQL table (exposed as dubheMarketplaceListings in GraphQL).
|
|
1005
|
+
* The record_type field is pre-decoded text ("wheat", "corn", …) and status tracks
|
|
1006
|
+
* active/sold/cancelled directly — no extra RPC calls needed.
|
|
1007
|
+
*/
|
|
1008
|
+
async getMarketplaceListings(options?: {
|
|
1009
|
+
dappKey?: string;
|
|
1010
|
+
status?: 'listed' | 'sold' | 'cancelled' | 'expired';
|
|
1011
|
+
recordType?: string;
|
|
1012
|
+
seller?: string;
|
|
1013
|
+
first?: number;
|
|
1014
|
+
after?: string;
|
|
1015
|
+
}): Promise<Connection<MarketplaceListingRow>> {
|
|
1016
|
+
const filter: Record<string, any> = {};
|
|
1017
|
+
if (options?.dappKey) filter.dappKey = { equalTo: options.dappKey };
|
|
1018
|
+
if (options?.status !== undefined) filter.status = { equalTo: options.status };
|
|
1019
|
+
if (options?.recordType) filter.recordType = { equalTo: options.recordType };
|
|
1020
|
+
if (options?.seller) filter.seller = { equalTo: options.seller };
|
|
1021
|
+
|
|
1022
|
+
const query = gql`
|
|
1023
|
+
query GetMarketplaceListings(
|
|
1024
|
+
$first: Int
|
|
1025
|
+
$after: Cursor
|
|
1026
|
+
$filter: StoreDubheMarketplaceListingFilter
|
|
1027
|
+
$orderBy: [StoreDubheMarketplaceListingsOrderBy!]
|
|
1028
|
+
) {
|
|
1029
|
+
dubheMarketplaceListings(first: $first, after: $after, filter: $filter, orderBy: $orderBy) {
|
|
1030
|
+
totalCount
|
|
1031
|
+
pageInfo {
|
|
1032
|
+
hasNextPage
|
|
1033
|
+
hasPreviousPage
|
|
1034
|
+
startCursor
|
|
1035
|
+
endCursor
|
|
1036
|
+
}
|
|
1037
|
+
edges {
|
|
1038
|
+
cursor
|
|
1039
|
+
node {
|
|
1040
|
+
listingId
|
|
1041
|
+
dappKey
|
|
1042
|
+
seller
|
|
1043
|
+
recordType
|
|
1044
|
+
recordDataRaw
|
|
1045
|
+
price
|
|
1046
|
+
coinType
|
|
1047
|
+
isFungible
|
|
1048
|
+
status
|
|
1049
|
+
buyer
|
|
1050
|
+
listedUntil
|
|
1051
|
+
createdAtCheckpoint
|
|
1052
|
+
updatedAtCheckpoint
|
|
1053
|
+
lastUpdateDigest
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
`;
|
|
1059
|
+
|
|
1060
|
+
const result = await this.apolloClient.query({
|
|
1061
|
+
query,
|
|
1062
|
+
variables: {
|
|
1063
|
+
first: options?.first ?? 100,
|
|
1064
|
+
after: options?.after,
|
|
1065
|
+
filter: Object.keys(filter).length > 0 ? filter : undefined,
|
|
1066
|
+
orderBy: ['CREATED_AT_CHECKPOINT_DESC']
|
|
1067
|
+
},
|
|
1068
|
+
fetchPolicy: 'network-only'
|
|
1069
|
+
});
|
|
1070
|
+
|
|
1071
|
+
if (result.error) throw result.error;
|
|
1072
|
+
return (
|
|
1073
|
+
(result.data as any)?.dubheMarketplaceListings ?? {
|
|
1074
|
+
edges: [],
|
|
1075
|
+
pageInfo: { hasNextPage: false, hasPreviousPage: false },
|
|
1076
|
+
totalCount: 0
|
|
1077
|
+
}
|
|
1078
|
+
);
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
/**
|
|
1082
|
+
* Query session keys indexed by the Dubhe indexer (dubheSessions in GraphQL).
|
|
1083
|
+
*/
|
|
1084
|
+
async getDubheSessions(options?: {
|
|
1085
|
+
dappKey?: string;
|
|
1086
|
+
canonical?: string;
|
|
1087
|
+
active?: boolean;
|
|
1088
|
+
first?: number;
|
|
1089
|
+
after?: string;
|
|
1090
|
+
}): Promise<Connection<DubheSessionRow>> {
|
|
1091
|
+
const filter: Record<string, any> = {};
|
|
1092
|
+
if (options?.dappKey) filter.dappKey = { equalTo: options.dappKey };
|
|
1093
|
+
if (options?.canonical) filter.canonical = { equalTo: options.canonical };
|
|
1094
|
+
if (options?.active !== undefined) filter.active = { equalTo: options.active };
|
|
1095
|
+
|
|
1096
|
+
const query = gql`
|
|
1097
|
+
query GetDubheSessions(
|
|
1098
|
+
$first: Int
|
|
1099
|
+
$after: Cursor
|
|
1100
|
+
$filter: StoreDubheSessionFilter
|
|
1101
|
+
$orderBy: [StoreDubheSessionsOrderBy!]
|
|
1102
|
+
) {
|
|
1103
|
+
dubheSessions(first: $first, after: $after, filter: $filter, orderBy: $orderBy) {
|
|
1104
|
+
totalCount
|
|
1105
|
+
pageInfo {
|
|
1106
|
+
hasNextPage
|
|
1107
|
+
hasPreviousPage
|
|
1108
|
+
startCursor
|
|
1109
|
+
endCursor
|
|
1110
|
+
}
|
|
1111
|
+
edges {
|
|
1112
|
+
cursor
|
|
1113
|
+
node {
|
|
1114
|
+
dappKey
|
|
1115
|
+
canonical
|
|
1116
|
+
sessionWallet
|
|
1117
|
+
expiresAt
|
|
1118
|
+
active
|
|
1119
|
+
updatedAtCheckpoint
|
|
1120
|
+
lastUpdateDigest
|
|
1121
|
+
lastEventSeq
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
`;
|
|
1127
|
+
|
|
1128
|
+
const result = await this.apolloClient.query({
|
|
1129
|
+
query,
|
|
1130
|
+
variables: {
|
|
1131
|
+
first: options?.first ?? 100,
|
|
1132
|
+
after: options?.after,
|
|
1133
|
+
filter: Object.keys(filter).length > 0 ? filter : undefined,
|
|
1134
|
+
orderBy: ['UPDATED_AT_CHECKPOINT_DESC']
|
|
1135
|
+
},
|
|
1136
|
+
fetchPolicy: 'network-only'
|
|
1137
|
+
});
|
|
1138
|
+
|
|
1139
|
+
if (result.error) throw result.error;
|
|
1140
|
+
return (
|
|
1141
|
+
(result.data as any)?.dubheSessions ?? {
|
|
1142
|
+
edges: [],
|
|
1143
|
+
pageInfo: { hasNextPage: false, hasPreviousPage: false },
|
|
1144
|
+
totalCount: 0
|
|
1145
|
+
}
|
|
1146
|
+
);
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
/**
|
|
1150
|
+
* Query user storage registrations indexed by the Dubhe indexer (dubheUserStorages in GraphQL).
|
|
1151
|
+
*/
|
|
1152
|
+
async getDubheUserStorages(options?: {
|
|
1153
|
+
dappKey?: string;
|
|
1154
|
+
canonicalOwner?: string;
|
|
1155
|
+
first?: number;
|
|
1156
|
+
after?: string;
|
|
1157
|
+
}): Promise<Connection<DubheUserStorageRow>> {
|
|
1158
|
+
const filter: Record<string, any> = {};
|
|
1159
|
+
if (options?.dappKey) filter.dappKey = { equalTo: options.dappKey };
|
|
1160
|
+
if (options?.canonicalOwner) filter.canonicalOwner = { equalTo: options.canonicalOwner };
|
|
1161
|
+
|
|
1162
|
+
const query = gql`
|
|
1163
|
+
query GetDubheUserStorages(
|
|
1164
|
+
$first: Int
|
|
1165
|
+
$after: Cursor
|
|
1166
|
+
$filter: StoreDubheUserStorageFilter
|
|
1167
|
+
$orderBy: [StoreDubheUserStoragesOrderBy!]
|
|
1168
|
+
) {
|
|
1169
|
+
dubheUserStorages(first: $first, after: $after, filter: $filter, orderBy: $orderBy) {
|
|
1170
|
+
totalCount
|
|
1171
|
+
pageInfo {
|
|
1172
|
+
hasNextPage
|
|
1173
|
+
hasPreviousPage
|
|
1174
|
+
startCursor
|
|
1175
|
+
endCursor
|
|
1176
|
+
}
|
|
1177
|
+
edges {
|
|
1178
|
+
cursor
|
|
1179
|
+
node {
|
|
1180
|
+
dappKey
|
|
1181
|
+
canonicalOwner
|
|
1182
|
+
userStorageId
|
|
1183
|
+
createdAtCheckpoint
|
|
1184
|
+
updatedAtCheckpoint
|
|
1185
|
+
lastUpdateDigest
|
|
1186
|
+
lastEventSeq
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
`;
|
|
1192
|
+
|
|
1193
|
+
const result = await this.apolloClient.query({
|
|
1194
|
+
query,
|
|
1195
|
+
variables: {
|
|
1196
|
+
first: options?.first ?? 100,
|
|
1197
|
+
after: options?.after,
|
|
1198
|
+
filter: Object.keys(filter).length > 0 ? filter : undefined,
|
|
1199
|
+
orderBy: ['CREATED_AT_CHECKPOINT_DESC']
|
|
1200
|
+
},
|
|
1201
|
+
fetchPolicy: 'network-only'
|
|
1202
|
+
});
|
|
1203
|
+
|
|
1204
|
+
if (result.error) throw result.error;
|
|
1205
|
+
return (
|
|
1206
|
+
(result.data as any)?.dubheUserStorages ?? {
|
|
1207
|
+
edges: [],
|
|
1208
|
+
pageInfo: { hasNextPage: false, hasPreviousPage: false },
|
|
1209
|
+
totalCount: 0
|
|
1210
|
+
}
|
|
1211
|
+
);
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
/**
|
|
1215
|
+
* Query SceneStorage system rows indexed by the Dubhe indexer
|
|
1216
|
+
* (scene_storages table, exposed as dubheSceneStorages in GraphQL).
|
|
1217
|
+
* Field values live in the companion scene_storage_fields table —
|
|
1218
|
+
* see getSceneStorageFields.
|
|
1219
|
+
*/
|
|
1220
|
+
async getSceneStorages(options?: {
|
|
1221
|
+
dappKey?: string;
|
|
1222
|
+
sceneType?: string;
|
|
1223
|
+
sceneId?: string;
|
|
1224
|
+
isDestroyed?: boolean;
|
|
1225
|
+
first?: number;
|
|
1226
|
+
after?: string;
|
|
1227
|
+
}): Promise<Connection<SceneStorageRow>> {
|
|
1228
|
+
const filter: Record<string, any> = {};
|
|
1229
|
+
if (options?.dappKey) filter.dappKey = { equalTo: options.dappKey };
|
|
1230
|
+
if (options?.sceneType) filter.sceneType = { equalTo: options.sceneType };
|
|
1231
|
+
if (options?.sceneId) filter.sceneId = { equalTo: options.sceneId };
|
|
1232
|
+
if (options?.isDestroyed !== undefined) filter.isDestroyed = { equalTo: options.isDestroyed };
|
|
1233
|
+
|
|
1234
|
+
const query = gql`
|
|
1235
|
+
query GetSceneStorages(
|
|
1236
|
+
$first: Int
|
|
1237
|
+
$after: Cursor
|
|
1238
|
+
$filter: StoreDubheSceneStorageFilter
|
|
1239
|
+
$orderBy: [StoreDubheSceneStoragesOrderBy!]
|
|
1240
|
+
) {
|
|
1241
|
+
dubheSceneStorages(first: $first, after: $after, filter: $filter, orderBy: $orderBy) {
|
|
1242
|
+
totalCount
|
|
1243
|
+
pageInfo {
|
|
1244
|
+
hasNextPage
|
|
1245
|
+
hasPreviousPage
|
|
1246
|
+
startCursor
|
|
1247
|
+
endCursor
|
|
1248
|
+
}
|
|
1249
|
+
edges {
|
|
1250
|
+
cursor
|
|
1251
|
+
node {
|
|
1252
|
+
sceneId
|
|
1253
|
+
dappKey
|
|
1254
|
+
sceneType
|
|
1255
|
+
authorizationKind
|
|
1256
|
+
authorizedPermitId
|
|
1257
|
+
isDestroyed
|
|
1258
|
+
createdAtCheckpoint
|
|
1259
|
+
updatedAtCheckpoint
|
|
1260
|
+
lastUpdateDigest
|
|
1261
|
+
lastEventSeq
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
`;
|
|
1267
|
+
|
|
1268
|
+
const result = await this.apolloClient.query({
|
|
1269
|
+
query,
|
|
1270
|
+
variables: {
|
|
1271
|
+
first: options?.first ?? 100,
|
|
1272
|
+
after: options?.after,
|
|
1273
|
+
filter: Object.keys(filter).length > 0 ? filter : undefined,
|
|
1274
|
+
orderBy: ['UPDATED_AT_CHECKPOINT_DESC']
|
|
1275
|
+
},
|
|
1276
|
+
fetchPolicy: 'network-only'
|
|
1277
|
+
});
|
|
1278
|
+
|
|
1279
|
+
if (result.error) throw result.error;
|
|
1280
|
+
return (
|
|
1281
|
+
(result.data as any)?.dubheSceneStorages ?? {
|
|
1282
|
+
edges: [],
|
|
1283
|
+
pageInfo: { hasNextPage: false, hasPreviousPage: false },
|
|
1284
|
+
totalCount: 0
|
|
1285
|
+
}
|
|
1286
|
+
);
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
/**
|
|
1290
|
+
* Query raw field rows of SceneStorages (scene_storage_fields table,
|
|
1291
|
+
* exposed as dubheSceneStorageFields in GraphQL). Values are hex-encoded
|
|
1292
|
+
* BCS — decode with the decoders exported from this package.
|
|
1293
|
+
*/
|
|
1294
|
+
async getSceneStorageFields(options?: {
|
|
1295
|
+
dappKey?: string;
|
|
1296
|
+
sceneIds?: string[];
|
|
1297
|
+
sceneId?: string;
|
|
1298
|
+
fieldName?: string;
|
|
1299
|
+
isDeleted?: boolean;
|
|
1300
|
+
first?: number;
|
|
1301
|
+
after?: string;
|
|
1302
|
+
}): Promise<Connection<SceneStorageFieldRow>> {
|
|
1303
|
+
const filter: Record<string, any> = {};
|
|
1304
|
+
if (options?.dappKey) filter.dappKey = { equalTo: options.dappKey };
|
|
1305
|
+
if (options?.sceneIds && options.sceneIds.length > 0) filter.sceneId = { in: options.sceneIds };
|
|
1306
|
+
if (options?.sceneId) filter.sceneId = { equalTo: options.sceneId };
|
|
1307
|
+
if (options?.fieldName) filter.fieldName = { equalTo: options.fieldName };
|
|
1308
|
+
if (options?.isDeleted !== undefined) filter.isDeleted = { equalTo: options.isDeleted };
|
|
1309
|
+
|
|
1310
|
+
const query = gql`
|
|
1311
|
+
query GetSceneStorageFields(
|
|
1312
|
+
$first: Int
|
|
1313
|
+
$after: Cursor
|
|
1314
|
+
$filter: StoreDubheSceneStorageFieldFilter
|
|
1315
|
+
$orderBy: [StoreDubheSceneStorageFieldsOrderBy!]
|
|
1316
|
+
) {
|
|
1317
|
+
dubheSceneStorageFields(first: $first, after: $after, filter: $filter, orderBy: $orderBy) {
|
|
1318
|
+
totalCount
|
|
1319
|
+
pageInfo {
|
|
1320
|
+
hasNextPage
|
|
1321
|
+
hasPreviousPage
|
|
1322
|
+
startCursor
|
|
1323
|
+
endCursor
|
|
1324
|
+
}
|
|
1325
|
+
edges {
|
|
1326
|
+
cursor
|
|
1327
|
+
node {
|
|
1328
|
+
sceneId
|
|
1329
|
+
dappKey
|
|
1330
|
+
sceneType
|
|
1331
|
+
fieldName
|
|
1332
|
+
fieldValueRaw
|
|
1333
|
+
isDeleted
|
|
1334
|
+
updatedAtCheckpoint
|
|
1335
|
+
lastUpdateDigest
|
|
1336
|
+
lastEventSeq
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
`;
|
|
1342
|
+
|
|
1343
|
+
const result = await this.apolloClient.query({
|
|
1344
|
+
query,
|
|
1345
|
+
variables: {
|
|
1346
|
+
first: options?.first ?? 1000,
|
|
1347
|
+
after: options?.after,
|
|
1348
|
+
filter: Object.keys(filter).length > 0 ? filter : undefined,
|
|
1349
|
+
orderBy: ['UPDATED_AT_CHECKPOINT_DESC']
|
|
1350
|
+
},
|
|
1351
|
+
fetchPolicy: 'network-only'
|
|
1352
|
+
});
|
|
1353
|
+
|
|
1354
|
+
if (result.error) throw result.error;
|
|
1355
|
+
return (
|
|
1356
|
+
(result.data as any)?.dubheSceneStorageFields ?? {
|
|
1357
|
+
edges: [],
|
|
1358
|
+
pageInfo: { hasNextPage: false, hasPreviousPage: false },
|
|
1359
|
+
totalCount: 0
|
|
1360
|
+
}
|
|
1361
|
+
);
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
/**
|
|
1365
|
+
* Query ObjectStorage system rows indexed by the Dubhe indexer
|
|
1366
|
+
* (object_storages table, exposed as dubheObjectStorages in GraphQL).
|
|
1367
|
+
*/
|
|
1368
|
+
async getObjectStorages(options?: {
|
|
1369
|
+
dappKey?: string;
|
|
1370
|
+
objectType?: string;
|
|
1371
|
+
objectId?: string;
|
|
1372
|
+
isDestroyed?: boolean;
|
|
1373
|
+
first?: number;
|
|
1374
|
+
after?: string;
|
|
1375
|
+
}): Promise<Connection<ObjectStorageRow>> {
|
|
1376
|
+
const filter: Record<string, any> = {};
|
|
1377
|
+
if (options?.dappKey) filter.dappKey = { equalTo: options.dappKey };
|
|
1378
|
+
if (options?.objectType) filter.objectType = { equalTo: options.objectType };
|
|
1379
|
+
if (options?.objectId) filter.objectId = { equalTo: options.objectId };
|
|
1380
|
+
if (options?.isDestroyed !== undefined) filter.isDestroyed = { equalTo: options.isDestroyed };
|
|
1381
|
+
|
|
1382
|
+
const query = gql`
|
|
1383
|
+
query GetObjectStorages(
|
|
1384
|
+
$first: Int
|
|
1385
|
+
$after: Cursor
|
|
1386
|
+
$filter: StoreDubheObjectStorageFilter
|
|
1387
|
+
$orderBy: [StoreDubheObjectStoragesOrderBy!]
|
|
1388
|
+
) {
|
|
1389
|
+
dubheObjectStorages(first: $first, after: $after, filter: $filter, orderBy: $orderBy) {
|
|
1390
|
+
totalCount
|
|
1391
|
+
pageInfo {
|
|
1392
|
+
hasNextPage
|
|
1393
|
+
hasPreviousPage
|
|
1394
|
+
startCursor
|
|
1395
|
+
endCursor
|
|
1396
|
+
}
|
|
1397
|
+
edges {
|
|
1398
|
+
cursor
|
|
1399
|
+
node {
|
|
1400
|
+
objectId
|
|
1401
|
+
dappKey
|
|
1402
|
+
objectType
|
|
1403
|
+
entityIdRaw
|
|
1404
|
+
isDestroyed
|
|
1405
|
+
createdAtCheckpoint
|
|
1406
|
+
updatedAtCheckpoint
|
|
1407
|
+
lastUpdateDigest
|
|
1408
|
+
lastEventSeq
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
`;
|
|
1414
|
+
|
|
1415
|
+
const result = await this.apolloClient.query({
|
|
1416
|
+
query,
|
|
1417
|
+
variables: {
|
|
1418
|
+
first: options?.first ?? 100,
|
|
1419
|
+
after: options?.after,
|
|
1420
|
+
filter: Object.keys(filter).length > 0 ? filter : undefined,
|
|
1421
|
+
orderBy: ['UPDATED_AT_CHECKPOINT_DESC']
|
|
1422
|
+
},
|
|
1423
|
+
fetchPolicy: 'network-only'
|
|
1424
|
+
});
|
|
1425
|
+
|
|
1426
|
+
if (result.error) throw result.error;
|
|
1427
|
+
return (
|
|
1428
|
+
(result.data as any)?.dubheObjectStorages ?? {
|
|
1429
|
+
edges: [],
|
|
1430
|
+
pageInfo: { hasNextPage: false, hasPreviousPage: false },
|
|
1431
|
+
totalCount: 0
|
|
1432
|
+
}
|
|
1433
|
+
);
|
|
1434
|
+
}
|
|
1435
|
+
|
|
1436
|
+
/**
|
|
1437
|
+
* Query DApp runtime state (credit pool, admin, package version, etc.).
|
|
1438
|
+
* Exposed as dubheDappRuntimeStates in GraphQL.
|
|
1439
|
+
*/
|
|
1440
|
+
async getDubheDappRuntimeState(dappKey: string): Promise<DubheDappRuntimeStateRow | null> {
|
|
1441
|
+
const query = gql`
|
|
1442
|
+
query GetDubheDappRuntimeState($filter: StoreDubheDappRuntimeStateFilter) {
|
|
1443
|
+
dubheDappRuntimeStates(first: 1, filter: $filter) {
|
|
1444
|
+
edges {
|
|
1445
|
+
node {
|
|
1446
|
+
dappKey
|
|
1447
|
+
admin
|
|
1448
|
+
dappStorageId
|
|
1449
|
+
packageId
|
|
1450
|
+
version
|
|
1451
|
+
creditPool
|
|
1452
|
+
paused
|
|
1453
|
+
settlementMode
|
|
1454
|
+
createdAt
|
|
1455
|
+
createdAtCheckpoint
|
|
1456
|
+
updatedAtCheckpoint
|
|
1457
|
+
lastUpdateDigest
|
|
1458
|
+
lastEventSeq
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
`;
|
|
1464
|
+
|
|
1465
|
+
const result = await this.apolloClient.query({
|
|
1466
|
+
query,
|
|
1467
|
+
variables: { filter: { dappKey: { equalTo: dappKey } } },
|
|
1468
|
+
fetchPolicy: 'network-only'
|
|
1469
|
+
});
|
|
1470
|
+
|
|
1471
|
+
if (result.error) throw result.error;
|
|
1472
|
+
const edges = (result.data as any)?.dubheDappRuntimeStates?.edges ?? [];
|
|
1473
|
+
return edges[0]?.node ?? null;
|
|
1474
|
+
}
|
|
1475
|
+
|
|
886
1476
|
// Improved table name handling methods
|
|
887
1477
|
private getFilterTypeName(tableName: string): string {
|
|
888
1478
|
// Convert to singular form and apply PascalCase conversion
|
|
@@ -1235,12 +1825,24 @@ export class DubheGraphqlClient {
|
|
|
1235
1825
|
if (customFields && customFields.length > 0) {
|
|
1236
1826
|
fields = customFields;
|
|
1237
1827
|
} else {
|
|
1238
|
-
//
|
|
1239
|
-
const
|
|
1240
|
-
if (
|
|
1241
|
-
fields =
|
|
1828
|
+
// 1. Check system table registry first
|
|
1829
|
+
const systemFields = SYSTEM_TABLE_FIELDS[tableName];
|
|
1830
|
+
if (systemFields) {
|
|
1831
|
+
fields = systemFields;
|
|
1242
1832
|
} else {
|
|
1243
|
-
fields
|
|
1833
|
+
// 2. Try to get fields from dubhe configuration (DApp store tables)
|
|
1834
|
+
const autoFields = this.getTableFields(tableName);
|
|
1835
|
+
if (autoFields.length > 0) {
|
|
1836
|
+
fields = autoFields;
|
|
1837
|
+
} else {
|
|
1838
|
+
// 3. Generic fallback for store_* tables
|
|
1839
|
+
fields = [
|
|
1840
|
+
'createdAtTimestampMs',
|
|
1841
|
+
'updatedAtTimestampMs',
|
|
1842
|
+
'isDeleted',
|
|
1843
|
+
'lastUpdateDigest'
|
|
1844
|
+
];
|
|
1845
|
+
}
|
|
1244
1846
|
}
|
|
1245
1847
|
}
|
|
1246
1848
|
|
|
@@ -1248,6 +1850,74 @@ export class DubheGraphqlClient {
|
|
|
1248
1850
|
|
|
1249
1851
|
return fields.join('\n ');
|
|
1250
1852
|
}
|
|
1853
|
+
|
|
1854
|
+
// ── Typed system-table query methods ─────────────────────────────────────
|
|
1855
|
+
|
|
1856
|
+
/** Latest DApp fee state snapshot (credit_pool, total_settled, fee rates). */
|
|
1857
|
+
async getDappFeeState(): Promise<{
|
|
1858
|
+
entityId: string;
|
|
1859
|
+
baseFeePerWrite: string;
|
|
1860
|
+
bytesFeePerByte: string;
|
|
1861
|
+
freeCredit: string;
|
|
1862
|
+
creditPool: string;
|
|
1863
|
+
totalSettled: string;
|
|
1864
|
+
updatedAtTimestampMs: string;
|
|
1865
|
+
} | null> {
|
|
1866
|
+
const result = await this.getAllTables<any>('dubheDappFeeState', { first: 1 }).catch(
|
|
1867
|
+
() => null
|
|
1868
|
+
);
|
|
1869
|
+
return result?.edges?.[0]?.node ?? null;
|
|
1870
|
+
}
|
|
1871
|
+
|
|
1872
|
+
/** Latest DApp revenue balance (USER_PAYS mode collected revenue). */
|
|
1873
|
+
async getDappRevenueState(): Promise<{
|
|
1874
|
+
entityId: string;
|
|
1875
|
+
dappRevenue: string;
|
|
1876
|
+
coinType: string;
|
|
1877
|
+
updatedAtTimestampMs: string;
|
|
1878
|
+
} | null> {
|
|
1879
|
+
const result = await this.getAllTables<any>('dubheDappRevenueState', { first: 1 }).catch(
|
|
1880
|
+
() => null
|
|
1881
|
+
);
|
|
1882
|
+
return result?.edges?.[0]?.node ?? null;
|
|
1883
|
+
}
|
|
1884
|
+
|
|
1885
|
+
/** Latest DApp runtime state (admin, settlement mode, last event). */
|
|
1886
|
+
async getDappRuntimeState(): Promise<{
|
|
1887
|
+
dappKey: string;
|
|
1888
|
+
admin: string;
|
|
1889
|
+
paused: boolean;
|
|
1890
|
+
settlementMode: number;
|
|
1891
|
+
creditPool: string;
|
|
1892
|
+
writeFeeShareBps: number;
|
|
1893
|
+
lastRuntimeEvent: string;
|
|
1894
|
+
lastRuntimeActor: string;
|
|
1895
|
+
lastRuntimeAmount: string;
|
|
1896
|
+
} | null> {
|
|
1897
|
+
const result = await this.getAllTables<any>('dubheDappRuntimeState', { first: 1 }).catch(
|
|
1898
|
+
() => null
|
|
1899
|
+
);
|
|
1900
|
+
return result?.edges?.[0]?.node ?? null;
|
|
1901
|
+
}
|
|
1902
|
+
|
|
1903
|
+
/** Marketplace fee records (one row per listing sold). */
|
|
1904
|
+
async getDappMarketplaceFees(options?: { first?: number; after?: string }): Promise<
|
|
1905
|
+
Connection<{
|
|
1906
|
+
dappKey: string;
|
|
1907
|
+
listingId: string;
|
|
1908
|
+
coinType: string;
|
|
1909
|
+
totalFee: string;
|
|
1910
|
+
treasuryAmount: string;
|
|
1911
|
+
dappAmount: string;
|
|
1912
|
+
updatedAtCheckpoint: string;
|
|
1913
|
+
}>
|
|
1914
|
+
> {
|
|
1915
|
+
return this.getAllTables<any>('dubheDappMarketplaceFees', {
|
|
1916
|
+
first: options?.first ?? 20,
|
|
1917
|
+
after: options?.after,
|
|
1918
|
+
orderBy: [{ field: 'updatedAtCheckpoint', direction: 'DESC' }]
|
|
1919
|
+
});
|
|
1920
|
+
}
|
|
1251
1921
|
}
|
|
1252
1922
|
|
|
1253
1923
|
// Export convenience function
|