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
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.2.1 - 2026-02-27
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- `--dry-run` mode for write surfaces:
|
|
8
|
+
- `ag tx send --dry-run`
|
|
9
|
+
- `ag onchain send --dry-run`
|
|
10
|
+
- mapped writes (for example `ag token approve --dry-run`)
|
|
11
|
+
- `scripts/smoke-write-dryrun.sh` and npm script `smoke:write-dryrun` for automated write-path smoke checks without broadcasting.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- Dry-run execution now returns `status: "simulated"` with simulation details and skips journal mutation and transaction submission.
|
|
16
|
+
- `--dry-run` is explicitly blocked with `--wait` / `--confirm`.
|
|
17
|
+
|
|
18
|
+
## 0.2.0 - 2026-02-27
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- Generic subgraph command family:
|
|
23
|
+
- `ag subgraph list`
|
|
24
|
+
- `ag subgraph check --source core-base|gbm-base [--raw]`
|
|
25
|
+
- `ag subgraph query --source <alias> ...`
|
|
26
|
+
- Baazaar subgraph wrappers:
|
|
27
|
+
- `ag baazaar listing get --kind erc721|erc1155 --id <listingId> [--verify-onchain]`
|
|
28
|
+
- `ag baazaar listing active --kind erc721|erc1155 [--first] [--skip]`
|
|
29
|
+
- `ag baazaar listing mine --kind erc721|erc1155 --seller <0x...> [--first] [--skip]`
|
|
30
|
+
- GBM subgraph wrappers:
|
|
31
|
+
- `ag auction get --id <auctionId> [--verify-onchain]`
|
|
32
|
+
- `ag auction active [--first] [--skip] [--at-time <unix>]`
|
|
33
|
+
- `ag auction mine --seller <0x...> [--first] [--skip]`
|
|
34
|
+
- `ag auction bids --auction-id <id> [--first] [--skip]`
|
|
35
|
+
- `ag auction bids-mine --bidder <0x...> [--first] [--skip]`
|
|
36
|
+
- Optional `--raw` GraphQL payload passthrough while preserving typed projections.
|
|
37
|
+
- New docs under `docs/subgraph/` for endpoint policy and query matrix.
|
|
38
|
+
|
|
39
|
+
### Security and policy
|
|
40
|
+
|
|
41
|
+
- Strict endpoint allowlist by default for canonical sources only.
|
|
42
|
+
- Custom endpoint override requires both `--subgraph-url` and `--allow-untrusted-subgraph`.
|
|
43
|
+
- Non-HTTPS custom subgraph endpoints are rejected.
|
|
44
|
+
|
|
45
|
+
### Notes
|
|
46
|
+
|
|
47
|
+
- Existing `onchain`, `tx`, mapped write aliases, and `baazaar read` onchain call behavior are preserved.
|
package/README.md
CHANGED
|
@@ -32,7 +32,7 @@ For read-only automation:
|
|
|
32
32
|
npm run ag -- bootstrap --mode agent --profile prod --chain base --signer readonly --json
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
## Command surface (
|
|
35
|
+
## Command surface (v0.2.0)
|
|
36
36
|
|
|
37
37
|
- `bootstrap`
|
|
38
38
|
- `profile list|show|use|export`
|
|
@@ -43,6 +43,9 @@ npm run ag -- bootstrap --mode agent --profile prod --chain base --signer readon
|
|
|
43
43
|
- `tx send|status|resume|watch`
|
|
44
44
|
- `batch run --file plan.yaml`
|
|
45
45
|
- `onchain call|send`
|
|
46
|
+
- `subgraph list|check|query`
|
|
47
|
+
- `baazaar listing get|active|mine` (subgraph-first read wrappers)
|
|
48
|
+
- `auction get|active|mine|bids|bids-mine` (subgraph-first read wrappers)
|
|
46
49
|
- `<domain> read` (routes to generic onchain call for that domain)
|
|
47
50
|
|
|
48
51
|
Planned domain namespaces are stubbed for parity tracking:
|
|
@@ -52,6 +55,91 @@ Planned domain namespaces are stubbed for parity tracking:
|
|
|
52
55
|
Many Base-era write flows are already executable as mapped aliases in those namespaces (internally routed through `onchain send`).
|
|
53
56
|
Example: `ag lending create --abi-file ./abis/GotchiLendingFacet.json --address 0x... --args-json '[...]' --json`
|
|
54
57
|
|
|
58
|
+
## Dry-run writes
|
|
59
|
+
|
|
60
|
+
Use `--dry-run` on write commands to run full preflight without broadcasting:
|
|
61
|
+
|
|
62
|
+
- runs simulation (`eth_call`)
|
|
63
|
+
- runs gas + fee estimation
|
|
64
|
+
- enforces policy checks
|
|
65
|
+
- resolves nonce
|
|
66
|
+
- returns `status: \"simulated\"` with simulation details
|
|
67
|
+
|
|
68
|
+
Supported write surfaces:
|
|
69
|
+
|
|
70
|
+
- `tx send --dry-run`
|
|
71
|
+
- `onchain send --dry-run`
|
|
72
|
+
- mapped write aliases (for example: `token approve --dry-run`)
|
|
73
|
+
|
|
74
|
+
Safety rule:
|
|
75
|
+
|
|
76
|
+
- `--dry-run` cannot be combined with `--wait` / `--confirm`
|
|
77
|
+
|
|
78
|
+
## Subgraph sources and endpoint policy
|
|
79
|
+
|
|
80
|
+
Canonical source aliases:
|
|
81
|
+
|
|
82
|
+
- `core-base` -> `https://api.goldsky.com/api/public/project_cmh3flagm0001r4p25foufjtt/subgraphs/aavegotchi-core-base/prod/gn`
|
|
83
|
+
- `gbm-base` -> `https://api.goldsky.com/api/public/project_cmh3flagm0001r4p25foufjtt/subgraphs/aavegotchi-gbm-baazaar-base/prod/gn`
|
|
84
|
+
|
|
85
|
+
Default policy is strict allowlist:
|
|
86
|
+
|
|
87
|
+
- Non-canonical subgraph URLs are blocked by default (`SUBGRAPH_ENDPOINT_BLOCKED`)
|
|
88
|
+
- Override is explicit and per-command only: pass both `--subgraph-url <https-url>` and `--allow-untrusted-subgraph`
|
|
89
|
+
- Non-HTTPS custom URLs are rejected
|
|
90
|
+
|
|
91
|
+
Auth:
|
|
92
|
+
|
|
93
|
+
- Public Goldsky endpoints work without auth
|
|
94
|
+
- If `GOLDSKY_API_KEY` is set, CLI injects `Authorization: Bearer <token>`
|
|
95
|
+
- Override env var name per command with `--auth-env-var <ENV>`
|
|
96
|
+
|
|
97
|
+
## Subgraph command examples
|
|
98
|
+
|
|
99
|
+
List configured canonical sources:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
npm run ag -- subgraph list --json
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Check source reachability/introspection:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
npm run ag -- subgraph check --source core-base --json
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Run custom GraphQL query:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
npm run ag -- subgraph query \
|
|
115
|
+
--source gbm-base \
|
|
116
|
+
--query 'query($first:Int!){ auctions(first:$first){ id } }' \
|
|
117
|
+
--variables-json '{"first":5}' \
|
|
118
|
+
--json
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Baazaar wrappers:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
npm run ag -- baazaar listing active --kind erc721 --first 20 --skip 0 --json
|
|
125
|
+
npm run ag -- baazaar listing mine --kind erc1155 --seller 0x... --json
|
|
126
|
+
npm run ag -- baazaar listing get --kind erc721 --id 123 --verify-onchain --json
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
GBM wrappers:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
npm run ag -- auction active --first 20 --json
|
|
133
|
+
npm run ag -- auction bids --auction-id 123 --json
|
|
134
|
+
npm run ag -- auction get --id 123 --verify-onchain --json
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Raw GraphQL passthrough (typed projection remains included):
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
npm run ag -- auction active --first 5 --raw --json
|
|
141
|
+
```
|
|
142
|
+
|
|
55
143
|
## Signer backends
|
|
56
144
|
|
|
57
145
|
- `readonly` (read-only mode)
|
|
@@ -106,6 +194,8 @@ All successful/error responses use a stable envelope:
|
|
|
106
194
|
|
|
107
195
|
- Method inventory: [`docs/parity/base-method-inventory.md`](docs/parity/base-method-inventory.md)
|
|
108
196
|
- Command mapping: [`docs/parity/base-command-matrix.md`](docs/parity/base-command-matrix.md)
|
|
197
|
+
- Subgraph endpoints/policy: [`docs/subgraph/endpoints-and-policy.md`](docs/subgraph/endpoints-and-policy.md)
|
|
198
|
+
- Subgraph query matrix: [`docs/subgraph/query-matrix.md`](docs/subgraph/query-matrix.md)
|
|
109
199
|
|
|
110
200
|
Raffle/ticket flows are intentionally excluded for Base-era scope.
|
|
111
201
|
|
|
@@ -116,5 +206,12 @@ npm run typecheck
|
|
|
116
206
|
npm test
|
|
117
207
|
npm run build
|
|
118
208
|
npm run parity:check
|
|
209
|
+
npm run smoke:write-dryrun
|
|
119
210
|
npm run ag -- help
|
|
120
211
|
```
|
|
212
|
+
|
|
213
|
+
Write dry-run smoke test notes:
|
|
214
|
+
|
|
215
|
+
- `npm run smoke:write-dryrun` validates write paths without broadcasting any transaction.
|
|
216
|
+
- To run against an installed binary instead of local source:
|
|
217
|
+
- `AG_BIN=/absolute/path/to/ag npm run smoke:write-dryrun`
|
package/dist/command-runner.js
CHANGED
|
@@ -7,11 +7,14 @@ const batch_1 = require("./commands/batch");
|
|
|
7
7
|
const bootstrap_1 = require("./commands/bootstrap");
|
|
8
8
|
const mapped_1 = require("./commands/mapped");
|
|
9
9
|
const onchain_1 = require("./commands/onchain");
|
|
10
|
+
const auction_subgraph_1 = require("./commands/auction-subgraph");
|
|
11
|
+
const baazaar_subgraph_1 = require("./commands/baazaar-subgraph");
|
|
10
12
|
const policy_1 = require("./commands/policy");
|
|
11
13
|
const profile_1 = require("./commands/profile");
|
|
12
14
|
const rpc_1 = require("./commands/rpc");
|
|
13
15
|
const signer_1 = require("./commands/signer");
|
|
14
16
|
const stubs_1 = require("./commands/stubs");
|
|
17
|
+
const subgraph_1 = require("./commands/subgraph");
|
|
15
18
|
const tx_1 = require("./commands/tx");
|
|
16
19
|
function normalizeCommandPath(positionals) {
|
|
17
20
|
if (positionals.length === 0 || positionals[0] === "help") {
|
|
@@ -156,6 +159,43 @@ async function executeCommand(ctx) {
|
|
|
156
159
|
};
|
|
157
160
|
}
|
|
158
161
|
}
|
|
162
|
+
if (root === "subgraph") {
|
|
163
|
+
if (!sub || sub === "list") {
|
|
164
|
+
return {
|
|
165
|
+
commandName: "subgraph list",
|
|
166
|
+
data: await (0, subgraph_1.runSubgraphListCommand)(),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
if (sub === "check") {
|
|
170
|
+
return {
|
|
171
|
+
commandName: "subgraph check",
|
|
172
|
+
data: await (0, subgraph_1.runSubgraphCheckCommand)(ctx),
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
if (sub === "query") {
|
|
176
|
+
return {
|
|
177
|
+
commandName: "subgraph query",
|
|
178
|
+
data: await (0, subgraph_1.runSubgraphQueryCommand)(ctx),
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
if (root === "baazaar" && sub === "listing") {
|
|
183
|
+
const action = ctx.commandPath[2];
|
|
184
|
+
if (action === "get" || action === "active" || action === "mine") {
|
|
185
|
+
return {
|
|
186
|
+
commandName: ctx.commandPath.join(" "),
|
|
187
|
+
data: await (0, baazaar_subgraph_1.runBaazaarListingSubgraphCommand)(ctx),
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (root === "auction") {
|
|
192
|
+
if (sub === "get" || sub === "active" || sub === "mine" || sub === "bids" || sub === "bids-mine") {
|
|
193
|
+
return {
|
|
194
|
+
commandName: ctx.commandPath.join(" "),
|
|
195
|
+
data: await (0, auction_subgraph_1.runAuctionSubgraphCommand)(ctx),
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
}
|
|
159
199
|
if (root === "batch" && (!sub || sub === "run")) {
|
|
160
200
|
return {
|
|
161
201
|
commandName: "batch run",
|
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runAuctionGetSubgraphCommand = runAuctionGetSubgraphCommand;
|
|
4
|
+
exports.runAuctionActiveSubgraphCommand = runAuctionActiveSubgraphCommand;
|
|
5
|
+
exports.runAuctionMineSubgraphCommand = runAuctionMineSubgraphCommand;
|
|
6
|
+
exports.runAuctionBidsSubgraphCommand = runAuctionBidsSubgraphCommand;
|
|
7
|
+
exports.runAuctionBidsMineSubgraphCommand = runAuctionBidsMineSubgraphCommand;
|
|
8
|
+
exports.runAuctionSubgraphCommand = runAuctionSubgraphCommand;
|
|
9
|
+
const viem_1 = require("viem");
|
|
10
|
+
const args_1 = require("../args");
|
|
11
|
+
const chains_1 = require("../chains");
|
|
12
|
+
const config_1 = require("../config");
|
|
13
|
+
const errors_1 = require("../errors");
|
|
14
|
+
const rpc_1 = require("../rpc");
|
|
15
|
+
const normalize_1 = require("../subgraph/normalize");
|
|
16
|
+
const queries_1 = require("../subgraph/queries");
|
|
17
|
+
const sources_1 = require("../subgraph/sources");
|
|
18
|
+
const client_1 = require("../subgraph/client");
|
|
19
|
+
const DEFAULT_FIRST = 20;
|
|
20
|
+
const MAX_FIRST = 200;
|
|
21
|
+
const DEFAULT_SKIP = 0;
|
|
22
|
+
const MAX_SKIP = 100000;
|
|
23
|
+
const GBM_VERIFY_ABI = (0, viem_1.parseAbi)([
|
|
24
|
+
"function getAuctionHighestBid(uint256 _auctionId) view returns (uint256)",
|
|
25
|
+
"function getContractAddress(uint256 _auctionId) view returns (address)",
|
|
26
|
+
"function getTokenId(uint256 _auctionId) view returns (uint256)",
|
|
27
|
+
"function getAuctionStartTime(uint256 _auctionId) view returns (uint256)",
|
|
28
|
+
"function getAuctionEndTime(uint256 _auctionId) view returns (uint256)",
|
|
29
|
+
]);
|
|
30
|
+
function parseRawFlag(ctx) {
|
|
31
|
+
return (0, args_1.getFlagBoolean)(ctx.args.flags, "raw");
|
|
32
|
+
}
|
|
33
|
+
function parseTimeoutMs(value) {
|
|
34
|
+
if (!value) {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
const timeout = Number(value);
|
|
38
|
+
if (!Number.isInteger(timeout) || timeout <= 0) {
|
|
39
|
+
throw new errors_1.CliError("INVALID_ARGUMENT", "--timeout-ms must be a positive integer.", 2, {
|
|
40
|
+
value,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return timeout;
|
|
44
|
+
}
|
|
45
|
+
function parseBoundedIntFlag(value, flagName, fallback, min, max) {
|
|
46
|
+
if (!value) {
|
|
47
|
+
return fallback;
|
|
48
|
+
}
|
|
49
|
+
const parsed = Number(value);
|
|
50
|
+
if (!Number.isInteger(parsed) || parsed < min || parsed > max) {
|
|
51
|
+
throw new errors_1.CliError("INVALID_ARGUMENT", `${flagName} must be an integer between ${min} and ${max}.`, 2, {
|
|
52
|
+
value,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
return parsed;
|
|
56
|
+
}
|
|
57
|
+
function parsePagination(ctx) {
|
|
58
|
+
const first = parseBoundedIntFlag((0, args_1.getFlagString)(ctx.args.flags, "first"), "--first", DEFAULT_FIRST, 1, MAX_FIRST);
|
|
59
|
+
const skip = parseBoundedIntFlag((0, args_1.getFlagString)(ctx.args.flags, "skip"), "--skip", DEFAULT_SKIP, 0, MAX_SKIP);
|
|
60
|
+
return {
|
|
61
|
+
first,
|
|
62
|
+
skip,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function parseAddress(value, flagName) {
|
|
66
|
+
if (!value || !/^0x[a-fA-F0-9]{40}$/.test(value)) {
|
|
67
|
+
throw new errors_1.CliError("INVALID_ARGUMENT", `${flagName} must be an EVM address.`, 2, {
|
|
68
|
+
value,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return (0, normalize_1.toLowercaseAddress)(value);
|
|
72
|
+
}
|
|
73
|
+
function parseAuctionId(value, flagName) {
|
|
74
|
+
if (!value) {
|
|
75
|
+
throw new errors_1.CliError("MISSING_ARGUMENT", `${flagName} is required.`, 2);
|
|
76
|
+
}
|
|
77
|
+
if (!/^\d+$/.test(value)) {
|
|
78
|
+
throw new errors_1.CliError("INVALID_ARGUMENT", `${flagName} must be an unsigned integer string.`, 2, {
|
|
79
|
+
value,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return value;
|
|
83
|
+
}
|
|
84
|
+
function parseActiveTime(ctx) {
|
|
85
|
+
const atTime = (0, args_1.getFlagString)(ctx.args.flags, "at-time");
|
|
86
|
+
if (!atTime) {
|
|
87
|
+
return Math.floor(Date.now() / 1000).toString();
|
|
88
|
+
}
|
|
89
|
+
if (!/^\d+$/.test(atTime)) {
|
|
90
|
+
throw new errors_1.CliError("INVALID_ARGUMENT", "--at-time must be a unix timestamp (seconds).", 2, {
|
|
91
|
+
value: atTime,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
return atTime;
|
|
95
|
+
}
|
|
96
|
+
function parseCommonSubgraphOptions(ctx) {
|
|
97
|
+
const subgraphUrl = (0, args_1.getFlagString)(ctx.args.flags, "subgraph-url");
|
|
98
|
+
const allowUntrustedSubgraph = (0, args_1.getFlagBoolean)(ctx.args.flags, "allow-untrusted-subgraph");
|
|
99
|
+
if (allowUntrustedSubgraph && !subgraphUrl) {
|
|
100
|
+
throw new errors_1.CliError("INVALID_ARGUMENT", "--allow-untrusted-subgraph requires --subgraph-url.", 2);
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
source: "gbm-base",
|
|
104
|
+
timeoutMs: parseTimeoutMs((0, args_1.getFlagString)(ctx.args.flags, "timeout-ms")),
|
|
105
|
+
authEnvVar: (0, args_1.getFlagString)(ctx.args.flags, "auth-env-var"),
|
|
106
|
+
subgraphUrl,
|
|
107
|
+
allowUntrustedSubgraph,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
function parseVerifyOnchainFlag(ctx) {
|
|
111
|
+
return (0, args_1.getFlagBoolean)(ctx.args.flags, "verify-onchain");
|
|
112
|
+
}
|
|
113
|
+
function resolveReadRpcUrl(ctx) {
|
|
114
|
+
const explicitRpc = (0, args_1.getFlagString)(ctx.args.flags, "rpc-url");
|
|
115
|
+
if (explicitRpc) {
|
|
116
|
+
return explicitRpc;
|
|
117
|
+
}
|
|
118
|
+
const profileName = (0, args_1.getFlagString)(ctx.args.flags, "profile") || ctx.globals.profile;
|
|
119
|
+
if (profileName) {
|
|
120
|
+
const config = (0, config_1.loadConfig)();
|
|
121
|
+
const profile = (0, config_1.getProfileOrThrow)(config, profileName);
|
|
122
|
+
return profile.rpcUrl;
|
|
123
|
+
}
|
|
124
|
+
return (0, chains_1.resolveRpcUrl)((0, chains_1.resolveChain)("base"), undefined);
|
|
125
|
+
}
|
|
126
|
+
function createMismatchDiff(keys, subgraph, onchain) {
|
|
127
|
+
const diff = {};
|
|
128
|
+
for (const key of keys) {
|
|
129
|
+
if (subgraph[key] !== onchain[key]) {
|
|
130
|
+
diff[key] = {
|
|
131
|
+
subgraph: subgraph[key],
|
|
132
|
+
onchain: onchain[key],
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return diff;
|
|
137
|
+
}
|
|
138
|
+
function withNormalizeContext(response, normalize) {
|
|
139
|
+
try {
|
|
140
|
+
return normalize();
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
if (error instanceof errors_1.CliError && error.code === "SUBGRAPH_INVALID_RESPONSE") {
|
|
144
|
+
const extraDetails = error.details && typeof error.details === "object" ? error.details : {};
|
|
145
|
+
throw new errors_1.CliError(error.code, error.message, error.exitCode, {
|
|
146
|
+
source: response.source,
|
|
147
|
+
endpoint: response.endpoint,
|
|
148
|
+
queryName: response.queryName,
|
|
149
|
+
...extraDetails,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
throw error;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
async function verifyAuctionOnchain(ctx, auction) {
|
|
156
|
+
const chain = (0, chains_1.resolveChain)("base");
|
|
157
|
+
const rpcUrl = resolveReadRpcUrl(ctx);
|
|
158
|
+
const preflight = await (0, rpc_1.runRpcPreflight)(chain, rpcUrl);
|
|
159
|
+
const auctionId = BigInt(auction.id);
|
|
160
|
+
const [highestBid, contractAddress, tokenId, startsAt, endsAt] = await Promise.all([
|
|
161
|
+
preflight.client.readContract({
|
|
162
|
+
address: sources_1.BASE_GBM_DIAMOND,
|
|
163
|
+
abi: GBM_VERIFY_ABI,
|
|
164
|
+
functionName: "getAuctionHighestBid",
|
|
165
|
+
args: [auctionId],
|
|
166
|
+
}),
|
|
167
|
+
preflight.client.readContract({
|
|
168
|
+
address: sources_1.BASE_GBM_DIAMOND,
|
|
169
|
+
abi: GBM_VERIFY_ABI,
|
|
170
|
+
functionName: "getContractAddress",
|
|
171
|
+
args: [auctionId],
|
|
172
|
+
}),
|
|
173
|
+
preflight.client.readContract({
|
|
174
|
+
address: sources_1.BASE_GBM_DIAMOND,
|
|
175
|
+
abi: GBM_VERIFY_ABI,
|
|
176
|
+
functionName: "getTokenId",
|
|
177
|
+
args: [auctionId],
|
|
178
|
+
}),
|
|
179
|
+
preflight.client.readContract({
|
|
180
|
+
address: sources_1.BASE_GBM_DIAMOND,
|
|
181
|
+
abi: GBM_VERIFY_ABI,
|
|
182
|
+
functionName: "getAuctionStartTime",
|
|
183
|
+
args: [auctionId],
|
|
184
|
+
}),
|
|
185
|
+
preflight.client.readContract({
|
|
186
|
+
address: sources_1.BASE_GBM_DIAMOND,
|
|
187
|
+
abi: GBM_VERIFY_ABI,
|
|
188
|
+
functionName: "getAuctionEndTime",
|
|
189
|
+
args: [auctionId],
|
|
190
|
+
}),
|
|
191
|
+
]);
|
|
192
|
+
const onchainProjection = {
|
|
193
|
+
highestBid: highestBid.toString(),
|
|
194
|
+
contractAddress: (0, normalize_1.toLowercaseAddress)(contractAddress),
|
|
195
|
+
tokenId: tokenId.toString(),
|
|
196
|
+
startsAt: startsAt.toString(),
|
|
197
|
+
endsAt: endsAt.toString(),
|
|
198
|
+
};
|
|
199
|
+
const subgraphProjection = {
|
|
200
|
+
highestBid: auction.highestBid,
|
|
201
|
+
contractAddress: auction.contractAddress,
|
|
202
|
+
tokenId: auction.tokenId,
|
|
203
|
+
startsAt: auction.startsAt,
|
|
204
|
+
endsAt: auction.endsAt,
|
|
205
|
+
};
|
|
206
|
+
const diff = createMismatchDiff(["highestBid", "contractAddress", "tokenId", "startsAt", "endsAt"], subgraphProjection, onchainProjection);
|
|
207
|
+
if (Object.keys(diff).length > 0) {
|
|
208
|
+
throw new errors_1.CliError("SUBGRAPH_VERIFY_MISMATCH", "Subgraph auction does not match onchain snapshot.", 2, {
|
|
209
|
+
source: "gbm-base",
|
|
210
|
+
endpoint: "onchain-verify",
|
|
211
|
+
queryName: "auction.get",
|
|
212
|
+
auctionId: auction.id,
|
|
213
|
+
rpcUrl,
|
|
214
|
+
contractAddress: sources_1.BASE_GBM_DIAMOND,
|
|
215
|
+
diff,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
return {
|
|
219
|
+
verified: true,
|
|
220
|
+
rpcUrl,
|
|
221
|
+
chainId: preflight.chainId,
|
|
222
|
+
contractAddress: sources_1.BASE_GBM_DIAMOND,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
async function runAuctionGetSubgraphCommand(ctx) {
|
|
226
|
+
const id = parseAuctionId((0, args_1.getFlagString)(ctx.args.flags, "id"), "--id");
|
|
227
|
+
const raw = parseRawFlag(ctx);
|
|
228
|
+
const verifyOnchain = parseVerifyOnchainFlag(ctx);
|
|
229
|
+
const common = parseCommonSubgraphOptions(ctx);
|
|
230
|
+
const response = await (0, client_1.executeSubgraphQuery)({
|
|
231
|
+
...common,
|
|
232
|
+
queryName: "auction.get",
|
|
233
|
+
query: queries_1.GBM_AUCTION_BY_ID_QUERY,
|
|
234
|
+
variables: { id },
|
|
235
|
+
raw,
|
|
236
|
+
});
|
|
237
|
+
const auction = response.data.auction
|
|
238
|
+
? withNormalizeContext(response, () => (0, normalize_1.normalizeGbmAuction)(response.data.auction))
|
|
239
|
+
: null;
|
|
240
|
+
const verification = verifyOnchain && auction ? await verifyAuctionOnchain(ctx, auction) : undefined;
|
|
241
|
+
return {
|
|
242
|
+
source: response.source,
|
|
243
|
+
endpoint: response.endpoint,
|
|
244
|
+
queryName: response.queryName,
|
|
245
|
+
auction,
|
|
246
|
+
...(verification ? { verification } : {}),
|
|
247
|
+
...(raw ? { raw: response.raw } : {}),
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
async function runAuctionActiveSubgraphCommand(ctx) {
|
|
251
|
+
const pagination = parsePagination(ctx);
|
|
252
|
+
const now = parseActiveTime(ctx);
|
|
253
|
+
const raw = parseRawFlag(ctx);
|
|
254
|
+
const common = parseCommonSubgraphOptions(ctx);
|
|
255
|
+
const response = await (0, client_1.executeSubgraphQuery)({
|
|
256
|
+
...common,
|
|
257
|
+
queryName: "auction.active",
|
|
258
|
+
query: queries_1.GBM_ACTIVE_AUCTIONS_QUERY,
|
|
259
|
+
variables: {
|
|
260
|
+
now,
|
|
261
|
+
...pagination,
|
|
262
|
+
},
|
|
263
|
+
raw,
|
|
264
|
+
});
|
|
265
|
+
if (!Array.isArray(response.data.auctions)) {
|
|
266
|
+
throw new errors_1.CliError("SUBGRAPH_INVALID_RESPONSE", "Expected auctions to be an array.", 2, {
|
|
267
|
+
source: response.source,
|
|
268
|
+
endpoint: response.endpoint,
|
|
269
|
+
queryName: response.queryName,
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
const auctions = response.data.auctions;
|
|
273
|
+
return {
|
|
274
|
+
source: response.source,
|
|
275
|
+
endpoint: response.endpoint,
|
|
276
|
+
queryName: response.queryName,
|
|
277
|
+
atTime: now,
|
|
278
|
+
pagination,
|
|
279
|
+
auctions: withNormalizeContext(response, () => (0, normalize_1.normalizeGbmAuctions)(auctions)),
|
|
280
|
+
...(raw ? { raw: response.raw } : {}),
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
async function runAuctionMineSubgraphCommand(ctx) {
|
|
284
|
+
const seller = parseAddress((0, args_1.getFlagString)(ctx.args.flags, "seller"), "--seller");
|
|
285
|
+
const pagination = parsePagination(ctx);
|
|
286
|
+
const raw = parseRawFlag(ctx);
|
|
287
|
+
const common = parseCommonSubgraphOptions(ctx);
|
|
288
|
+
const response = await (0, client_1.executeSubgraphQuery)({
|
|
289
|
+
...common,
|
|
290
|
+
queryName: "auction.mine",
|
|
291
|
+
query: queries_1.GBM_MINE_AUCTIONS_QUERY,
|
|
292
|
+
variables: {
|
|
293
|
+
seller,
|
|
294
|
+
...pagination,
|
|
295
|
+
},
|
|
296
|
+
raw,
|
|
297
|
+
});
|
|
298
|
+
if (!Array.isArray(response.data.auctions)) {
|
|
299
|
+
throw new errors_1.CliError("SUBGRAPH_INVALID_RESPONSE", "Expected auctions to be an array.", 2, {
|
|
300
|
+
source: response.source,
|
|
301
|
+
endpoint: response.endpoint,
|
|
302
|
+
queryName: response.queryName,
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
const auctions = response.data.auctions;
|
|
306
|
+
return {
|
|
307
|
+
source: response.source,
|
|
308
|
+
endpoint: response.endpoint,
|
|
309
|
+
queryName: response.queryName,
|
|
310
|
+
seller,
|
|
311
|
+
pagination,
|
|
312
|
+
auctions: withNormalizeContext(response, () => (0, normalize_1.normalizeGbmAuctions)(auctions)),
|
|
313
|
+
...(raw ? { raw: response.raw } : {}),
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
async function runAuctionBidsSubgraphCommand(ctx) {
|
|
317
|
+
const auctionId = parseAuctionId((0, args_1.getFlagString)(ctx.args.flags, "auction-id"), "--auction-id");
|
|
318
|
+
const pagination = parsePagination(ctx);
|
|
319
|
+
const raw = parseRawFlag(ctx);
|
|
320
|
+
const common = parseCommonSubgraphOptions(ctx);
|
|
321
|
+
const response = await (0, client_1.executeSubgraphQuery)({
|
|
322
|
+
...common,
|
|
323
|
+
queryName: "auction.bids",
|
|
324
|
+
query: queries_1.GBM_BIDS_BY_AUCTION_QUERY,
|
|
325
|
+
variables: {
|
|
326
|
+
auctionId,
|
|
327
|
+
...pagination,
|
|
328
|
+
},
|
|
329
|
+
raw,
|
|
330
|
+
});
|
|
331
|
+
if (!Array.isArray(response.data.bids)) {
|
|
332
|
+
throw new errors_1.CliError("SUBGRAPH_INVALID_RESPONSE", "Expected bids to be an array.", 2, {
|
|
333
|
+
source: response.source,
|
|
334
|
+
endpoint: response.endpoint,
|
|
335
|
+
queryName: response.queryName,
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
const bids = response.data.bids;
|
|
339
|
+
return {
|
|
340
|
+
source: response.source,
|
|
341
|
+
endpoint: response.endpoint,
|
|
342
|
+
queryName: response.queryName,
|
|
343
|
+
auctionId,
|
|
344
|
+
pagination,
|
|
345
|
+
bids: withNormalizeContext(response, () => (0, normalize_1.normalizeGbmBids)(bids)),
|
|
346
|
+
...(raw ? { raw: response.raw } : {}),
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
async function runAuctionBidsMineSubgraphCommand(ctx) {
|
|
350
|
+
const bidder = parseAddress((0, args_1.getFlagString)(ctx.args.flags, "bidder"), "--bidder");
|
|
351
|
+
const pagination = parsePagination(ctx);
|
|
352
|
+
const raw = parseRawFlag(ctx);
|
|
353
|
+
const common = parseCommonSubgraphOptions(ctx);
|
|
354
|
+
const response = await (0, client_1.executeSubgraphQuery)({
|
|
355
|
+
...common,
|
|
356
|
+
queryName: "auction.bids-mine",
|
|
357
|
+
query: queries_1.GBM_BIDS_BY_BIDDER_QUERY,
|
|
358
|
+
variables: {
|
|
359
|
+
bidder,
|
|
360
|
+
...pagination,
|
|
361
|
+
},
|
|
362
|
+
raw,
|
|
363
|
+
});
|
|
364
|
+
if (!Array.isArray(response.data.bids)) {
|
|
365
|
+
throw new errors_1.CliError("SUBGRAPH_INVALID_RESPONSE", "Expected bids to be an array.", 2, {
|
|
366
|
+
source: response.source,
|
|
367
|
+
endpoint: response.endpoint,
|
|
368
|
+
queryName: response.queryName,
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
const bids = response.data.bids;
|
|
372
|
+
return {
|
|
373
|
+
source: response.source,
|
|
374
|
+
endpoint: response.endpoint,
|
|
375
|
+
queryName: response.queryName,
|
|
376
|
+
bidder,
|
|
377
|
+
pagination,
|
|
378
|
+
bids: withNormalizeContext(response, () => (0, normalize_1.normalizeGbmBids)(bids)),
|
|
379
|
+
...(raw ? { raw: response.raw } : {}),
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
async function runAuctionSubgraphCommand(ctx) {
|
|
383
|
+
const action = ctx.commandPath[1];
|
|
384
|
+
if (action === "get") {
|
|
385
|
+
return runAuctionGetSubgraphCommand(ctx);
|
|
386
|
+
}
|
|
387
|
+
if (action === "active") {
|
|
388
|
+
return runAuctionActiveSubgraphCommand(ctx);
|
|
389
|
+
}
|
|
390
|
+
if (action === "mine") {
|
|
391
|
+
return runAuctionMineSubgraphCommand(ctx);
|
|
392
|
+
}
|
|
393
|
+
if (action === "bids") {
|
|
394
|
+
return runAuctionBidsSubgraphCommand(ctx);
|
|
395
|
+
}
|
|
396
|
+
if (action === "bids-mine") {
|
|
397
|
+
return runAuctionBidsMineSubgraphCommand(ctx);
|
|
398
|
+
}
|
|
399
|
+
throw new errors_1.CliError("UNKNOWN_COMMAND", `Unknown command '${ctx.commandPath.join(" ")}'.`, 2);
|
|
400
|
+
}
|