aavegotchi-cli 0.1.0 → 0.2.1
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/CHANGELOG.md +47 -0
- package/README.md +98 -1
- package/dist/command-runner.js +40 -0
- package/dist/commands/auction-subgraph.js +400 -0
- package/dist/commands/baazaar-subgraph.js +436 -0
- package/dist/commands/onchain.js +5 -0
- package/dist/commands/subgraph.js +172 -0
- package/dist/commands/tx.js +5 -0
- package/dist/output.js +13 -3
- package/dist/schemas.js +59 -1
- package/dist/subgraph/client.js +144 -0
- package/dist/subgraph/normalize.js +85 -0
- package/dist/subgraph/queries.js +256 -0
- package/dist/subgraph/sources.js +92 -0
- package/dist/tx-engine.js +41 -5
- package/package.json +4 -2
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runBaazaarListingGetSubgraphCommand = runBaazaarListingGetSubgraphCommand;
|
|
4
|
+
exports.runBaazaarListingActiveSubgraphCommand = runBaazaarListingActiveSubgraphCommand;
|
|
5
|
+
exports.runBaazaarListingMineSubgraphCommand = runBaazaarListingMineSubgraphCommand;
|
|
6
|
+
exports.runBaazaarListingSubgraphCommand = runBaazaarListingSubgraphCommand;
|
|
7
|
+
const viem_1 = require("viem");
|
|
8
|
+
const args_1 = require("../args");
|
|
9
|
+
const chains_1 = require("../chains");
|
|
10
|
+
const config_1 = require("../config");
|
|
11
|
+
const errors_1 = require("../errors");
|
|
12
|
+
const rpc_1 = require("../rpc");
|
|
13
|
+
const normalize_1 = require("../subgraph/normalize");
|
|
14
|
+
const queries_1 = require("../subgraph/queries");
|
|
15
|
+
const sources_1 = require("../subgraph/sources");
|
|
16
|
+
const client_1 = require("../subgraph/client");
|
|
17
|
+
const DEFAULT_FIRST = 20;
|
|
18
|
+
const MAX_FIRST = 200;
|
|
19
|
+
const DEFAULT_SKIP = 0;
|
|
20
|
+
const MAX_SKIP = 100000;
|
|
21
|
+
const BAAZAAR_VERIFY_ABI = (0, viem_1.parseAbi)([
|
|
22
|
+
"function getERC721Listing(uint256 _listingId) view returns ((uint256 listingId,address seller,address erc721TokenAddress,uint256 erc721TokenId,uint256 category,uint256 priceInWei,uint256 timeCreated,uint256 timePurchased,bool cancelled,uint16[2] principalSplit,address affiliate,uint32 whitelistId))",
|
|
23
|
+
"function getERC1155Listing(uint256 _listingId) view returns ((uint256 listingId,address seller,address erc1155TokenAddress,uint256 erc1155TypeId,uint256 category,uint256 quantity,uint256 priceInWei,uint256 timeCreated,uint256 timeLastPurchased,uint256 sourceListingId,bool sold,bool cancelled,uint16[2] principalSplit,address affiliate,uint32 whitelistId))",
|
|
24
|
+
]);
|
|
25
|
+
function parseKind(value) {
|
|
26
|
+
if (!value) {
|
|
27
|
+
throw new errors_1.CliError("MISSING_ARGUMENT", "--kind is required (erc721|erc1155).", 2);
|
|
28
|
+
}
|
|
29
|
+
const normalized = value.trim().toLowerCase();
|
|
30
|
+
if (normalized === "erc721" || normalized === "erc1155") {
|
|
31
|
+
return normalized;
|
|
32
|
+
}
|
|
33
|
+
throw new errors_1.CliError("INVALID_ARGUMENT", "--kind must be one of: erc721, erc1155.", 2, {
|
|
34
|
+
value,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
function parseRawFlag(ctx) {
|
|
38
|
+
return (0, args_1.getFlagBoolean)(ctx.args.flags, "raw");
|
|
39
|
+
}
|
|
40
|
+
function parseTimeoutMs(value) {
|
|
41
|
+
if (!value) {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
const timeout = Number(value);
|
|
45
|
+
if (!Number.isInteger(timeout) || timeout <= 0) {
|
|
46
|
+
throw new errors_1.CliError("INVALID_ARGUMENT", "--timeout-ms must be a positive integer.", 2, {
|
|
47
|
+
value,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
return timeout;
|
|
51
|
+
}
|
|
52
|
+
function parseListingId(value, flagName) {
|
|
53
|
+
if (!value) {
|
|
54
|
+
throw new errors_1.CliError("MISSING_ARGUMENT", `${flagName} is required.`, 2);
|
|
55
|
+
}
|
|
56
|
+
if (!/^\d+$/.test(value)) {
|
|
57
|
+
throw new errors_1.CliError("INVALID_ARGUMENT", `${flagName} must be an unsigned integer string.`, 2, {
|
|
58
|
+
value,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return value;
|
|
62
|
+
}
|
|
63
|
+
function parseAddress(value, flagName) {
|
|
64
|
+
if (!value || !/^0x[a-fA-F0-9]{40}$/.test(value)) {
|
|
65
|
+
throw new errors_1.CliError("INVALID_ARGUMENT", `${flagName} must be an EVM address.`, 2, {
|
|
66
|
+
value,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
return (0, normalize_1.toLowercaseAddress)(value);
|
|
70
|
+
}
|
|
71
|
+
function parseBoundedIntFlag(value, flagName, fallback, min, max) {
|
|
72
|
+
if (!value) {
|
|
73
|
+
return fallback;
|
|
74
|
+
}
|
|
75
|
+
const parsed = Number(value);
|
|
76
|
+
if (!Number.isInteger(parsed) || parsed < min || parsed > max) {
|
|
77
|
+
throw new errors_1.CliError("INVALID_ARGUMENT", `${flagName} must be an integer between ${min} and ${max}.`, 2, {
|
|
78
|
+
value,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
return parsed;
|
|
82
|
+
}
|
|
83
|
+
function parsePagination(ctx) {
|
|
84
|
+
const first = parseBoundedIntFlag((0, args_1.getFlagString)(ctx.args.flags, "first"), "--first", DEFAULT_FIRST, 1, MAX_FIRST);
|
|
85
|
+
const skip = parseBoundedIntFlag((0, args_1.getFlagString)(ctx.args.flags, "skip"), "--skip", DEFAULT_SKIP, 0, MAX_SKIP);
|
|
86
|
+
return {
|
|
87
|
+
first,
|
|
88
|
+
skip,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function parseCommonSubgraphOptions(ctx) {
|
|
92
|
+
const subgraphUrl = (0, args_1.getFlagString)(ctx.args.flags, "subgraph-url");
|
|
93
|
+
const allowUntrustedSubgraph = (0, args_1.getFlagBoolean)(ctx.args.flags, "allow-untrusted-subgraph");
|
|
94
|
+
if (allowUntrustedSubgraph && !subgraphUrl) {
|
|
95
|
+
throw new errors_1.CliError("INVALID_ARGUMENT", "--allow-untrusted-subgraph requires --subgraph-url.", 2);
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
source: "core-base",
|
|
99
|
+
timeoutMs: parseTimeoutMs((0, args_1.getFlagString)(ctx.args.flags, "timeout-ms")),
|
|
100
|
+
authEnvVar: (0, args_1.getFlagString)(ctx.args.flags, "auth-env-var"),
|
|
101
|
+
subgraphUrl,
|
|
102
|
+
allowUntrustedSubgraph,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
function parseVerifyOnchainFlag(ctx) {
|
|
106
|
+
return (0, args_1.getFlagBoolean)(ctx.args.flags, "verify-onchain");
|
|
107
|
+
}
|
|
108
|
+
function resolveReadRpcUrl(ctx) {
|
|
109
|
+
const explicitRpc = (0, args_1.getFlagString)(ctx.args.flags, "rpc-url");
|
|
110
|
+
if (explicitRpc) {
|
|
111
|
+
return explicitRpc;
|
|
112
|
+
}
|
|
113
|
+
const profileName = (0, args_1.getFlagString)(ctx.args.flags, "profile") || ctx.globals.profile;
|
|
114
|
+
if (profileName) {
|
|
115
|
+
const config = (0, config_1.loadConfig)();
|
|
116
|
+
const profile = (0, config_1.getProfileOrThrow)(config, profileName);
|
|
117
|
+
return profile.rpcUrl;
|
|
118
|
+
}
|
|
119
|
+
return (0, chains_1.resolveRpcUrl)((0, chains_1.resolveChain)("base"), undefined);
|
|
120
|
+
}
|
|
121
|
+
function createMismatchDiff(keys, subgraph, onchain) {
|
|
122
|
+
const diff = {};
|
|
123
|
+
for (const key of keys) {
|
|
124
|
+
if (subgraph[key] !== onchain[key]) {
|
|
125
|
+
diff[key] = {
|
|
126
|
+
subgraph: subgraph[key],
|
|
127
|
+
onchain: onchain[key],
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return diff;
|
|
132
|
+
}
|
|
133
|
+
function withNormalizeContext(response, normalize) {
|
|
134
|
+
try {
|
|
135
|
+
return normalize();
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
if (error instanceof errors_1.CliError && error.code === "SUBGRAPH_INVALID_RESPONSE") {
|
|
139
|
+
const extraDetails = error.details && typeof error.details === "object" ? error.details : {};
|
|
140
|
+
throw new errors_1.CliError(error.code, error.message, error.exitCode, {
|
|
141
|
+
source: response.source,
|
|
142
|
+
endpoint: response.endpoint,
|
|
143
|
+
queryName: response.queryName,
|
|
144
|
+
...extraDetails,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
throw error;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
async function verifyErc721ListingOnchain(ctx, listing) {
|
|
151
|
+
const chain = (0, chains_1.resolveChain)("base");
|
|
152
|
+
const rpcUrl = resolveReadRpcUrl(ctx);
|
|
153
|
+
const preflight = await (0, rpc_1.runRpcPreflight)(chain, rpcUrl);
|
|
154
|
+
const onchainRaw = (await preflight.client.readContract({
|
|
155
|
+
address: sources_1.BASE_AAVEGOTCHI_DIAMOND,
|
|
156
|
+
abi: BAAZAAR_VERIFY_ABI,
|
|
157
|
+
functionName: "getERC721Listing",
|
|
158
|
+
args: [BigInt(listing.id)],
|
|
159
|
+
}));
|
|
160
|
+
const onchainProjection = {
|
|
161
|
+
id: onchainRaw.listingId.toString(),
|
|
162
|
+
seller: (0, normalize_1.toLowercaseAddress)(onchainRaw.seller),
|
|
163
|
+
erc721TokenAddress: (0, normalize_1.toLowercaseAddress)(onchainRaw.erc721TokenAddress),
|
|
164
|
+
tokenId: onchainRaw.erc721TokenId.toString(),
|
|
165
|
+
category: onchainRaw.category.toString(),
|
|
166
|
+
priceInWei: onchainRaw.priceInWei.toString(),
|
|
167
|
+
timeCreated: onchainRaw.timeCreated.toString(),
|
|
168
|
+
timePurchased: onchainRaw.timePurchased.toString(),
|
|
169
|
+
cancelled: onchainRaw.cancelled,
|
|
170
|
+
};
|
|
171
|
+
const subgraphProjection = {
|
|
172
|
+
id: listing.id,
|
|
173
|
+
seller: listing.seller,
|
|
174
|
+
erc721TokenAddress: listing.erc721TokenAddress,
|
|
175
|
+
tokenId: listing.tokenId,
|
|
176
|
+
category: listing.category,
|
|
177
|
+
priceInWei: listing.priceInWei,
|
|
178
|
+
timeCreated: listing.timeCreated,
|
|
179
|
+
timePurchased: listing.timePurchased,
|
|
180
|
+
cancelled: listing.cancelled,
|
|
181
|
+
};
|
|
182
|
+
const diff = createMismatchDiff(["id", "seller", "erc721TokenAddress", "tokenId", "category", "priceInWei", "timeCreated", "timePurchased", "cancelled"], subgraphProjection, onchainProjection);
|
|
183
|
+
if (Object.keys(diff).length > 0) {
|
|
184
|
+
throw new errors_1.CliError("SUBGRAPH_VERIFY_MISMATCH", "Subgraph listing does not match onchain snapshot.", 2, {
|
|
185
|
+
source: "core-base",
|
|
186
|
+
endpoint: "onchain-verify",
|
|
187
|
+
queryName: "baazaar.listing.get.erc721",
|
|
188
|
+
listingId: listing.id,
|
|
189
|
+
rpcUrl,
|
|
190
|
+
contractAddress: sources_1.BASE_AAVEGOTCHI_DIAMOND,
|
|
191
|
+
diff,
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
verified: true,
|
|
196
|
+
rpcUrl,
|
|
197
|
+
chainId: preflight.chainId,
|
|
198
|
+
contractAddress: sources_1.BASE_AAVEGOTCHI_DIAMOND,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
async function verifyErc1155ListingOnchain(ctx, listing) {
|
|
202
|
+
const chain = (0, chains_1.resolveChain)("base");
|
|
203
|
+
const rpcUrl = resolveReadRpcUrl(ctx);
|
|
204
|
+
const preflight = await (0, rpc_1.runRpcPreflight)(chain, rpcUrl);
|
|
205
|
+
const onchainRaw = (await preflight.client.readContract({
|
|
206
|
+
address: sources_1.BASE_AAVEGOTCHI_DIAMOND,
|
|
207
|
+
abi: BAAZAAR_VERIFY_ABI,
|
|
208
|
+
functionName: "getERC1155Listing",
|
|
209
|
+
args: [BigInt(listing.id)],
|
|
210
|
+
}));
|
|
211
|
+
const onchainProjection = {
|
|
212
|
+
id: onchainRaw.listingId.toString(),
|
|
213
|
+
seller: (0, normalize_1.toLowercaseAddress)(onchainRaw.seller),
|
|
214
|
+
erc1155TokenAddress: (0, normalize_1.toLowercaseAddress)(onchainRaw.erc1155TokenAddress),
|
|
215
|
+
erc1155TypeId: onchainRaw.erc1155TypeId.toString(),
|
|
216
|
+
category: onchainRaw.category.toString(),
|
|
217
|
+
quantity: onchainRaw.quantity.toString(),
|
|
218
|
+
priceInWei: onchainRaw.priceInWei.toString(),
|
|
219
|
+
timeCreated: onchainRaw.timeCreated.toString(),
|
|
220
|
+
sold: onchainRaw.sold,
|
|
221
|
+
cancelled: onchainRaw.cancelled,
|
|
222
|
+
};
|
|
223
|
+
const subgraphProjection = {
|
|
224
|
+
id: listing.id,
|
|
225
|
+
seller: listing.seller,
|
|
226
|
+
erc1155TokenAddress: listing.erc1155TokenAddress,
|
|
227
|
+
erc1155TypeId: listing.erc1155TypeId,
|
|
228
|
+
category: listing.category,
|
|
229
|
+
quantity: listing.quantity,
|
|
230
|
+
priceInWei: listing.priceInWei,
|
|
231
|
+
timeCreated: listing.timeCreated,
|
|
232
|
+
sold: listing.sold,
|
|
233
|
+
cancelled: listing.cancelled,
|
|
234
|
+
};
|
|
235
|
+
const diff = createMismatchDiff(["id", "seller", "erc1155TokenAddress", "erc1155TypeId", "category", "quantity", "priceInWei", "timeCreated", "sold", "cancelled"], subgraphProjection, onchainProjection);
|
|
236
|
+
if (Object.keys(diff).length > 0) {
|
|
237
|
+
throw new errors_1.CliError("SUBGRAPH_VERIFY_MISMATCH", "Subgraph listing does not match onchain snapshot.", 2, {
|
|
238
|
+
source: "core-base",
|
|
239
|
+
endpoint: "onchain-verify",
|
|
240
|
+
queryName: "baazaar.listing.get.erc1155",
|
|
241
|
+
listingId: listing.id,
|
|
242
|
+
rpcUrl,
|
|
243
|
+
contractAddress: sources_1.BASE_AAVEGOTCHI_DIAMOND,
|
|
244
|
+
diff,
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
return {
|
|
248
|
+
verified: true,
|
|
249
|
+
rpcUrl,
|
|
250
|
+
chainId: preflight.chainId,
|
|
251
|
+
contractAddress: sources_1.BASE_AAVEGOTCHI_DIAMOND,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
async function runBaazaarListingGetSubgraphCommand(ctx) {
|
|
255
|
+
const kind = parseKind((0, args_1.getFlagString)(ctx.args.flags, "kind"));
|
|
256
|
+
const id = parseListingId((0, args_1.getFlagString)(ctx.args.flags, "id"), "--id");
|
|
257
|
+
const raw = parseRawFlag(ctx);
|
|
258
|
+
const verifyOnchain = parseVerifyOnchainFlag(ctx);
|
|
259
|
+
const common = parseCommonSubgraphOptions(ctx);
|
|
260
|
+
if (kind === "erc721") {
|
|
261
|
+
const response = await (0, client_1.executeSubgraphQuery)({
|
|
262
|
+
...common,
|
|
263
|
+
queryName: "baazaar.listing.get.erc721",
|
|
264
|
+
query: queries_1.BAAZAAR_ERC721_LISTING_BY_ID_QUERY,
|
|
265
|
+
variables: { id },
|
|
266
|
+
raw,
|
|
267
|
+
});
|
|
268
|
+
const listing = response.data.erc721Listing
|
|
269
|
+
? withNormalizeContext(response, () => (0, normalize_1.normalizeBaazaarErc721Listing)(response.data.erc721Listing))
|
|
270
|
+
: null;
|
|
271
|
+
const verification = verifyOnchain && listing ? await verifyErc721ListingOnchain(ctx, listing) : undefined;
|
|
272
|
+
return {
|
|
273
|
+
source: response.source,
|
|
274
|
+
endpoint: response.endpoint,
|
|
275
|
+
queryName: response.queryName,
|
|
276
|
+
listingKind: kind,
|
|
277
|
+
listing,
|
|
278
|
+
...(verification ? { verification } : {}),
|
|
279
|
+
...(raw ? { raw: response.raw } : {}),
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
const response = await (0, client_1.executeSubgraphQuery)({
|
|
283
|
+
...common,
|
|
284
|
+
queryName: "baazaar.listing.get.erc1155",
|
|
285
|
+
query: queries_1.BAAZAAR_ERC1155_LISTING_BY_ID_QUERY,
|
|
286
|
+
variables: { id },
|
|
287
|
+
raw,
|
|
288
|
+
});
|
|
289
|
+
const listing = response.data.erc1155Listing
|
|
290
|
+
? withNormalizeContext(response, () => (0, normalize_1.normalizeBaazaarErc1155Listing)(response.data.erc1155Listing))
|
|
291
|
+
: null;
|
|
292
|
+
const verification = verifyOnchain && listing ? await verifyErc1155ListingOnchain(ctx, listing) : undefined;
|
|
293
|
+
return {
|
|
294
|
+
source: response.source,
|
|
295
|
+
endpoint: response.endpoint,
|
|
296
|
+
queryName: response.queryName,
|
|
297
|
+
listingKind: kind,
|
|
298
|
+
listing,
|
|
299
|
+
...(verification ? { verification } : {}),
|
|
300
|
+
...(raw ? { raw: response.raw } : {}),
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
async function runBaazaarListingActiveSubgraphCommand(ctx) {
|
|
304
|
+
const kind = parseKind((0, args_1.getFlagString)(ctx.args.flags, "kind"));
|
|
305
|
+
const pagination = parsePagination(ctx);
|
|
306
|
+
const raw = parseRawFlag(ctx);
|
|
307
|
+
const common = parseCommonSubgraphOptions(ctx);
|
|
308
|
+
if (kind === "erc721") {
|
|
309
|
+
const response = await (0, client_1.executeSubgraphQuery)({
|
|
310
|
+
...common,
|
|
311
|
+
queryName: "baazaar.listing.active.erc721",
|
|
312
|
+
query: queries_1.BAAZAAR_ACTIVE_ERC721_QUERY,
|
|
313
|
+
variables: pagination,
|
|
314
|
+
raw,
|
|
315
|
+
});
|
|
316
|
+
if (!Array.isArray(response.data.erc721Listings)) {
|
|
317
|
+
throw new errors_1.CliError("SUBGRAPH_INVALID_RESPONSE", "Expected erc721Listings to be an array.", 2, {
|
|
318
|
+
source: response.source,
|
|
319
|
+
endpoint: response.endpoint,
|
|
320
|
+
queryName: response.queryName,
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
const erc721Listings = response.data.erc721Listings;
|
|
324
|
+
return {
|
|
325
|
+
source: response.source,
|
|
326
|
+
endpoint: response.endpoint,
|
|
327
|
+
queryName: response.queryName,
|
|
328
|
+
listingKind: kind,
|
|
329
|
+
pagination,
|
|
330
|
+
listings: withNormalizeContext(response, () => (0, normalize_1.normalizeBaazaarErc721Listings)(erc721Listings)),
|
|
331
|
+
...(raw ? { raw: response.raw } : {}),
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
const response = await (0, client_1.executeSubgraphQuery)({
|
|
335
|
+
...common,
|
|
336
|
+
queryName: "baazaar.listing.active.erc1155",
|
|
337
|
+
query: queries_1.BAAZAAR_ACTIVE_ERC1155_QUERY,
|
|
338
|
+
variables: pagination,
|
|
339
|
+
raw,
|
|
340
|
+
});
|
|
341
|
+
if (!Array.isArray(response.data.erc1155Listings)) {
|
|
342
|
+
throw new errors_1.CliError("SUBGRAPH_INVALID_RESPONSE", "Expected erc1155Listings to be an array.", 2, {
|
|
343
|
+
source: response.source,
|
|
344
|
+
endpoint: response.endpoint,
|
|
345
|
+
queryName: response.queryName,
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
const erc1155Listings = response.data.erc1155Listings;
|
|
349
|
+
return {
|
|
350
|
+
source: response.source,
|
|
351
|
+
endpoint: response.endpoint,
|
|
352
|
+
queryName: response.queryName,
|
|
353
|
+
listingKind: kind,
|
|
354
|
+
pagination,
|
|
355
|
+
listings: withNormalizeContext(response, () => (0, normalize_1.normalizeBaazaarErc1155Listings)(erc1155Listings)),
|
|
356
|
+
...(raw ? { raw: response.raw } : {}),
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
async function runBaazaarListingMineSubgraphCommand(ctx) {
|
|
360
|
+
const kind = parseKind((0, args_1.getFlagString)(ctx.args.flags, "kind"));
|
|
361
|
+
const seller = parseAddress((0, args_1.getFlagString)(ctx.args.flags, "seller"), "--seller");
|
|
362
|
+
const pagination = parsePagination(ctx);
|
|
363
|
+
const raw = parseRawFlag(ctx);
|
|
364
|
+
const common = parseCommonSubgraphOptions(ctx);
|
|
365
|
+
if (kind === "erc721") {
|
|
366
|
+
const response = await (0, client_1.executeSubgraphQuery)({
|
|
367
|
+
...common,
|
|
368
|
+
queryName: "baazaar.listing.mine.erc721",
|
|
369
|
+
query: queries_1.BAAZAAR_MINE_ERC721_QUERY,
|
|
370
|
+
variables: {
|
|
371
|
+
seller,
|
|
372
|
+
...pagination,
|
|
373
|
+
},
|
|
374
|
+
raw,
|
|
375
|
+
});
|
|
376
|
+
if (!Array.isArray(response.data.erc721Listings)) {
|
|
377
|
+
throw new errors_1.CliError("SUBGRAPH_INVALID_RESPONSE", "Expected erc721Listings to be an array.", 2, {
|
|
378
|
+
source: response.source,
|
|
379
|
+
endpoint: response.endpoint,
|
|
380
|
+
queryName: response.queryName,
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
const erc721Listings = response.data.erc721Listings;
|
|
384
|
+
return {
|
|
385
|
+
source: response.source,
|
|
386
|
+
endpoint: response.endpoint,
|
|
387
|
+
queryName: response.queryName,
|
|
388
|
+
listingKind: kind,
|
|
389
|
+
seller,
|
|
390
|
+
pagination,
|
|
391
|
+
listings: withNormalizeContext(response, () => (0, normalize_1.normalizeBaazaarErc721Listings)(erc721Listings)),
|
|
392
|
+
...(raw ? { raw: response.raw } : {}),
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
const response = await (0, client_1.executeSubgraphQuery)({
|
|
396
|
+
...common,
|
|
397
|
+
queryName: "baazaar.listing.mine.erc1155",
|
|
398
|
+
query: queries_1.BAAZAAR_MINE_ERC1155_QUERY,
|
|
399
|
+
variables: {
|
|
400
|
+
seller,
|
|
401
|
+
...pagination,
|
|
402
|
+
},
|
|
403
|
+
raw,
|
|
404
|
+
});
|
|
405
|
+
if (!Array.isArray(response.data.erc1155Listings)) {
|
|
406
|
+
throw new errors_1.CliError("SUBGRAPH_INVALID_RESPONSE", "Expected erc1155Listings to be an array.", 2, {
|
|
407
|
+
source: response.source,
|
|
408
|
+
endpoint: response.endpoint,
|
|
409
|
+
queryName: response.queryName,
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
const erc1155Listings = response.data.erc1155Listings;
|
|
413
|
+
return {
|
|
414
|
+
source: response.source,
|
|
415
|
+
endpoint: response.endpoint,
|
|
416
|
+
queryName: response.queryName,
|
|
417
|
+
listingKind: kind,
|
|
418
|
+
seller,
|
|
419
|
+
pagination,
|
|
420
|
+
listings: withNormalizeContext(response, () => (0, normalize_1.normalizeBaazaarErc1155Listings)(erc1155Listings)),
|
|
421
|
+
...(raw ? { raw: response.raw } : {}),
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
async function runBaazaarListingSubgraphCommand(ctx) {
|
|
425
|
+
const action = ctx.commandPath[2];
|
|
426
|
+
if (action === "get") {
|
|
427
|
+
return runBaazaarListingGetSubgraphCommand(ctx);
|
|
428
|
+
}
|
|
429
|
+
if (action === "active") {
|
|
430
|
+
return runBaazaarListingActiveSubgraphCommand(ctx);
|
|
431
|
+
}
|
|
432
|
+
if (action === "mine") {
|
|
433
|
+
return runBaazaarListingMineSubgraphCommand(ctx);
|
|
434
|
+
}
|
|
435
|
+
throw new errors_1.CliError("UNKNOWN_COMMAND", `Unknown command '${ctx.commandPath.join(" ")}'.`, 2);
|
|
436
|
+
}
|
package/dist/commands/onchain.js
CHANGED
|
@@ -184,6 +184,10 @@ async function runOnchainSendWithFunction(ctx, forcedFunctionName, commandOverri
|
|
|
184
184
|
});
|
|
185
185
|
}
|
|
186
186
|
const waitForReceipt = (0, args_1.getFlagBoolean)(ctx.args.flags, "wait");
|
|
187
|
+
const dryRun = (0, args_1.getFlagBoolean)(ctx.args.flags, "dry-run");
|
|
188
|
+
if (dryRun && waitForReceipt) {
|
|
189
|
+
throw new errors_1.CliError("INVALID_ARGUMENT", "--dry-run cannot be combined with --wait.", 2);
|
|
190
|
+
}
|
|
187
191
|
const intent = {
|
|
188
192
|
idempotencyKey: (0, args_1.getFlagString)(ctx.args.flags, "idempotency-key"),
|
|
189
193
|
profileName: profile.name,
|
|
@@ -197,6 +201,7 @@ async function runOnchainSendWithFunction(ctx, forcedFunctionName, commandOverri
|
|
|
197
201
|
noncePolicy: noncePolicyRaw,
|
|
198
202
|
nonce,
|
|
199
203
|
waitForReceipt,
|
|
204
|
+
dryRun,
|
|
200
205
|
timeoutMs: parseTimeoutMs((0, args_1.getFlagString)(ctx.args.flags, "timeout-ms")),
|
|
201
206
|
command: commandOverride || `onchain send ${functionName}`,
|
|
202
207
|
};
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.runSubgraphListCommand = runSubgraphListCommand;
|
|
37
|
+
exports.runSubgraphCheckCommand = runSubgraphCheckCommand;
|
|
38
|
+
exports.runSubgraphQueryCommand = runSubgraphQueryCommand;
|
|
39
|
+
const fs = __importStar(require("fs"));
|
|
40
|
+
const args_1 = require("../args");
|
|
41
|
+
const errors_1 = require("../errors");
|
|
42
|
+
const schemas_1 = require("../schemas");
|
|
43
|
+
const client_1 = require("../subgraph/client");
|
|
44
|
+
const queries_1 = require("../subgraph/queries");
|
|
45
|
+
const sources_1 = require("../subgraph/sources");
|
|
46
|
+
function parseTimeoutMs(value) {
|
|
47
|
+
if (!value) {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
const timeout = Number(value);
|
|
51
|
+
if (!Number.isInteger(timeout) || timeout <= 0) {
|
|
52
|
+
throw new errors_1.CliError("INVALID_ARGUMENT", "--timeout-ms must be a positive integer.", 2, {
|
|
53
|
+
value,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return timeout;
|
|
57
|
+
}
|
|
58
|
+
function parseVariablesJson(value) {
|
|
59
|
+
if (!value) {
|
|
60
|
+
return {};
|
|
61
|
+
}
|
|
62
|
+
let parsed;
|
|
63
|
+
try {
|
|
64
|
+
parsed = JSON.parse(value);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
throw new errors_1.CliError("INVALID_VARIABLES_JSON", "--variables-json must be valid JSON.", 2);
|
|
68
|
+
}
|
|
69
|
+
const result = schemas_1.subgraphVariablesSchema.safeParse(parsed);
|
|
70
|
+
if (!result.success) {
|
|
71
|
+
throw new errors_1.CliError("INVALID_VARIABLES_JSON", "--variables-json must be a JSON object.", 2, {
|
|
72
|
+
issues: result.error.issues,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
return result.data;
|
|
76
|
+
}
|
|
77
|
+
function readQueryFromInput(flags) {
|
|
78
|
+
const inline = (0, args_1.getFlagString)(flags, "query");
|
|
79
|
+
const queryFile = (0, args_1.getFlagString)(flags, "query-file");
|
|
80
|
+
if (!inline && !queryFile) {
|
|
81
|
+
throw new errors_1.CliError("MISSING_ARGUMENT", "subgraph query requires --query or --query-file.", 2);
|
|
82
|
+
}
|
|
83
|
+
if (inline && queryFile) {
|
|
84
|
+
throw new errors_1.CliError("INVALID_ARGUMENT", "Provide only one of --query or --query-file.", 2);
|
|
85
|
+
}
|
|
86
|
+
if (inline) {
|
|
87
|
+
return inline;
|
|
88
|
+
}
|
|
89
|
+
const filePath = queryFile;
|
|
90
|
+
if (!fs.existsSync(filePath)) {
|
|
91
|
+
throw new errors_1.CliError("MISSING_ARGUMENT", `Query file not found: ${filePath}`, 2);
|
|
92
|
+
}
|
|
93
|
+
const query = fs.readFileSync(filePath, "utf8").trim();
|
|
94
|
+
if (!query) {
|
|
95
|
+
throw new errors_1.CliError("INVALID_ARGUMENT", "Query file is empty.", 2, {
|
|
96
|
+
queryFile: filePath,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
return query;
|
|
100
|
+
}
|
|
101
|
+
function parseRawFlag(ctx) {
|
|
102
|
+
return (0, args_1.getFlagBoolean)(ctx.args.flags, "raw");
|
|
103
|
+
}
|
|
104
|
+
function parseCommonRequestOptions(ctx) {
|
|
105
|
+
const subgraphUrl = (0, args_1.getFlagString)(ctx.args.flags, "subgraph-url");
|
|
106
|
+
const allowUntrustedSubgraph = (0, args_1.getFlagBoolean)(ctx.args.flags, "allow-untrusted-subgraph");
|
|
107
|
+
if (allowUntrustedSubgraph && !subgraphUrl) {
|
|
108
|
+
throw new errors_1.CliError("INVALID_ARGUMENT", "--allow-untrusted-subgraph requires --subgraph-url.", 2);
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
source: (0, sources_1.parseSubgraphSourceAlias)((0, args_1.getFlagString)(ctx.args.flags, "source")),
|
|
112
|
+
timeoutMs: parseTimeoutMs((0, args_1.getFlagString)(ctx.args.flags, "timeout-ms")),
|
|
113
|
+
authEnvVar: (0, args_1.getFlagString)(ctx.args.flags, "auth-env-var"),
|
|
114
|
+
subgraphUrl,
|
|
115
|
+
allowUntrustedSubgraph,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
async function runSubgraphListCommand() {
|
|
119
|
+
return {
|
|
120
|
+
sources: (0, sources_1.listSubgraphSources)(),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
async function runSubgraphCheckCommand(ctx) {
|
|
124
|
+
const common = parseCommonRequestOptions(ctx);
|
|
125
|
+
const raw = parseRawFlag(ctx);
|
|
126
|
+
const response = await (0, client_1.executeSubgraphQuery)({
|
|
127
|
+
...common,
|
|
128
|
+
queryName: "introspection",
|
|
129
|
+
query: queries_1.SUBGRAPH_INTROSPECTION_QUERY,
|
|
130
|
+
variables: {},
|
|
131
|
+
raw,
|
|
132
|
+
});
|
|
133
|
+
const fields = response.data.__schema?.queryType?.fields;
|
|
134
|
+
if (!Array.isArray(fields)) {
|
|
135
|
+
throw new errors_1.CliError("SUBGRAPH_INVALID_RESPONSE", "Introspection response missing query fields.", 2, {
|
|
136
|
+
source: response.source,
|
|
137
|
+
endpoint: response.endpoint,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
const fieldNames = fields
|
|
141
|
+
.map((field) => field.name)
|
|
142
|
+
.filter((name) => typeof name === "string")
|
|
143
|
+
.sort((a, b) => a.localeCompare(b));
|
|
144
|
+
return {
|
|
145
|
+
source: response.source,
|
|
146
|
+
endpoint: response.endpoint,
|
|
147
|
+
queryName: response.queryName,
|
|
148
|
+
fieldCount: fieldNames.length,
|
|
149
|
+
fields: fieldNames,
|
|
150
|
+
...(raw ? { raw: response.raw } : {}),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
async function runSubgraphQueryCommand(ctx) {
|
|
154
|
+
const common = parseCommonRequestOptions(ctx);
|
|
155
|
+
const raw = parseRawFlag(ctx);
|
|
156
|
+
const query = readQueryFromInput(ctx.args.flags);
|
|
157
|
+
const variables = parseVariablesJson((0, args_1.getFlagString)(ctx.args.flags, "variables-json"));
|
|
158
|
+
const response = await (0, client_1.executeSubgraphQuery)({
|
|
159
|
+
...common,
|
|
160
|
+
queryName: "custom",
|
|
161
|
+
query,
|
|
162
|
+
variables,
|
|
163
|
+
raw,
|
|
164
|
+
});
|
|
165
|
+
return {
|
|
166
|
+
source: response.source,
|
|
167
|
+
endpoint: response.endpoint,
|
|
168
|
+
queryName: response.queryName,
|
|
169
|
+
data: response.data,
|
|
170
|
+
...(raw ? { raw: response.raw } : {}),
|
|
171
|
+
};
|
|
172
|
+
}
|
package/dist/commands/tx.js
CHANGED
|
@@ -75,10 +75,14 @@ async function runTxSendCommand(ctx) {
|
|
|
75
75
|
const nonceValue = (0, args_1.getFlagString)(ctx.args.flags, "nonce");
|
|
76
76
|
const nonce = nonceValue ? parseNumberFlag(nonceValue, "--nonce", 0) : undefined;
|
|
77
77
|
const waitForReceipt = (0, args_1.getFlagBoolean)(ctx.args.flags, "wait") || (0, args_1.getFlagBoolean)(ctx.args.flags, "confirm");
|
|
78
|
+
const dryRun = (0, args_1.getFlagBoolean)(ctx.args.flags, "dry-run");
|
|
78
79
|
const timeoutMs = parseNumberFlag((0, args_1.getFlagString)(ctx.args.flags, "timeout-ms"), "--timeout-ms", 120000);
|
|
79
80
|
if (noncePolicy === "manual" && nonce === undefined) {
|
|
80
81
|
throw new errors_1.CliError("MISSING_NONCE", "--nonce is required when --nonce-policy=manual.", 2);
|
|
81
82
|
}
|
|
83
|
+
if (dryRun && waitForReceipt) {
|
|
84
|
+
throw new errors_1.CliError("INVALID_ARGUMENT", "--dry-run cannot be combined with --wait/--confirm.", 2);
|
|
85
|
+
}
|
|
82
86
|
const intent = {
|
|
83
87
|
idempotencyKey,
|
|
84
88
|
profileName: profile.name,
|
|
@@ -92,6 +96,7 @@ async function runTxSendCommand(ctx) {
|
|
|
92
96
|
noncePolicy,
|
|
93
97
|
nonce,
|
|
94
98
|
waitForReceipt,
|
|
99
|
+
dryRun,
|
|
95
100
|
timeoutMs,
|
|
96
101
|
command: "tx send",
|
|
97
102
|
};
|
package/dist/output.js
CHANGED
|
@@ -69,7 +69,7 @@ Core commands:
|
|
|
69
69
|
rpc check Verify RPC connectivity + signer backend health
|
|
70
70
|
|
|
71
71
|
Tx commands:
|
|
72
|
-
tx send Send a raw EVM transaction
|
|
72
|
+
tx send Send a raw EVM transaction (or simulate only with --dry-run)
|
|
73
73
|
tx status Read tx status by idempotency key/hash or list recent
|
|
74
74
|
tx resume Resume waiting for a previously submitted tx
|
|
75
75
|
tx watch Poll journal until tx is confirmed
|
|
@@ -79,12 +79,18 @@ Automation commands:
|
|
|
79
79
|
|
|
80
80
|
Power-user commands:
|
|
81
81
|
onchain call Call any ABI function from --abi-file
|
|
82
|
-
onchain send Send any ABI function as a transaction
|
|
82
|
+
onchain send Send any ABI function as a transaction (or simulate with --dry-run)
|
|
83
|
+
subgraph list|check|query List/check/query canonical Goldsky subgraphs
|
|
83
84
|
|
|
84
85
|
Domain namespaces:
|
|
85
|
-
gotchi, portal, wearables, items, inventory, baazaar, lending, realm, alchemica, forge, token
|
|
86
|
+
gotchi, portal, wearables, items, inventory, baazaar, auction, lending, staking, gotchi-points, realm, alchemica, forge, token
|
|
86
87
|
(many write flows are mapped to onchain send aliases; unmatched commands return typed not-implemented)
|
|
87
88
|
|
|
89
|
+
Subgraph wrappers:
|
|
90
|
+
baazaar listing get|active|mine Read Baazaar listing data from core-base subgraph
|
|
91
|
+
auction get|active|mine|bids|bids-mine
|
|
92
|
+
Read GBM auction/bid data from gbm-base subgraph
|
|
93
|
+
|
|
88
94
|
Global flags:
|
|
89
95
|
--mode <agent|human> Agent mode implies --json --yes
|
|
90
96
|
--json, -j Emit JSON envelope output
|
|
@@ -106,6 +112,10 @@ Examples:
|
|
|
106
112
|
ag bootstrap --mode agent --profile prod --chain base --signer env:AGCLI_PRIVATE_KEY --json
|
|
107
113
|
AGCLI_KEYCHAIN_PASSPHRASE=... AGCLI_PRIVATE_KEY=0x... ag signer keychain import --account-id bot --private-key-env AGCLI_PRIVATE_KEY --json
|
|
108
114
|
ag tx send --profile prod --to 0xabc... --value-wei 1000000000000000 --wait --json
|
|
115
|
+
ag tx send --profile prod --to 0xabc... --value-wei 0 --dry-run --json
|
|
116
|
+
ag subgraph check --source core-base --json
|
|
117
|
+
ag baazaar listing active --kind erc721 --first 20 --json
|
|
118
|
+
ag auction active --first 20 --json
|
|
109
119
|
ag lending create --profile prod --abi-file ./abis/GotchiLendingFacet.json --address 0xabc... --args-json '[...]' --json
|
|
110
120
|
ag batch run --file ./plan.yaml --json
|
|
111
121
|
`);
|