@steerprotocol/sdk 4.0.0-next.7 → 4.0.0-next.8
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 +23 -6
- package/dist/index.cjs +86 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.mjs +86 -27
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -555,7 +555,8 @@ interface VaultMetadata {
|
|
|
555
555
|
readonly beaconName: string;
|
|
556
556
|
readonly createdAt: string;
|
|
557
557
|
readonly state: string | null;
|
|
558
|
-
|
|
558
|
+
/** Pool contract address or a 32-byte pool ID for singleton AMMs such as V4. */
|
|
559
|
+
readonly pool: Hex | null;
|
|
559
560
|
readonly poolKey?: string | null;
|
|
560
561
|
readonly token0: Address | null;
|
|
561
562
|
readonly token1: Address | null;
|
package/dist/index.d.mts
CHANGED
|
@@ -555,7 +555,8 @@ interface VaultMetadata {
|
|
|
555
555
|
readonly beaconName: string;
|
|
556
556
|
readonly createdAt: string;
|
|
557
557
|
readonly state: string | null;
|
|
558
|
-
|
|
558
|
+
/** Pool contract address or a 32-byte pool ID for singleton AMMs such as V4. */
|
|
559
|
+
readonly pool: Hex | null;
|
|
559
560
|
readonly poolKey?: string | null;
|
|
560
561
|
readonly token0: Address | null;
|
|
561
562
|
readonly token1: Address | null;
|
package/dist/index.mjs
CHANGED
|
@@ -139,12 +139,20 @@ var Operation = class {
|
|
|
139
139
|
};
|
|
140
140
|
//#endregion
|
|
141
141
|
//#region src/rpc/read-errors.ts
|
|
142
|
+
/** @internal Shared context or helper execution failed before a member outcome is available. */
|
|
143
|
+
var SharedRpcReadError = class extends Error {
|
|
144
|
+
constructor(message, options) {
|
|
145
|
+
super(message, options);
|
|
146
|
+
this.name = "SharedRpcReadError";
|
|
147
|
+
}
|
|
148
|
+
};
|
|
142
149
|
/** Transport failures are shared by the request, never successful per-item outcomes. */
|
|
143
150
|
function sharedReadError(error) {
|
|
144
151
|
const seen = /* @__PURE__ */ new Set();
|
|
145
152
|
let shared = false;
|
|
146
153
|
for (let cause = error; cause && typeof cause === "object" && !seen.has(cause);) {
|
|
147
154
|
seen.add(cause);
|
|
155
|
+
if (cause instanceof SharedRpcReadError) return true;
|
|
148
156
|
if (cause instanceof ContractFunctionRevertedError) return false;
|
|
149
157
|
const value = cause;
|
|
150
158
|
if (value.name === "ContractFunctionRevertedError") return false;
|
|
@@ -175,15 +183,15 @@ function sameAddress(left, right) {
|
|
|
175
183
|
return left.toLowerCase() === right.toLowerCase();
|
|
176
184
|
}
|
|
177
185
|
function quantity(value) {
|
|
178
|
-
if (typeof value !== "string" || !/^0x(?:0|[1-9a-f][\da-f]*)$/i.test(value)) throw new
|
|
186
|
+
if (typeof value !== "string" || !/^0x(?:0|[1-9a-f][\da-f]*)$/i.test(value)) throw new SharedRpcReadError("Invalid RPC quantity");
|
|
179
187
|
return BigInt(value);
|
|
180
188
|
}
|
|
181
189
|
async function readContext(context, options) {
|
|
182
190
|
const transport = context.transport;
|
|
183
|
-
if (!transport) throw new
|
|
184
|
-
if (quantity(await transport.request("eth_chainId", [])) !== BigInt(context.chainId)) throw new
|
|
191
|
+
if (!transport) throw new SharedRpcReadError(`No RPC transport configured for chain ${context.chainId}`);
|
|
192
|
+
if (quantity(await transport.request("eth_chainId", [])) !== BigInt(context.chainId)) throw new SharedRpcReadError("RPC chain does not match requested chain");
|
|
185
193
|
const blockNumber = options?.blockNumber ?? quantity(await transport.request("eth_blockNumber", []));
|
|
186
|
-
if (blockNumber < 0n) throw new
|
|
194
|
+
if (blockNumber < 0n) throw new SharedRpcReadError("Block number must be nonnegative");
|
|
187
195
|
return {
|
|
188
196
|
...context,
|
|
189
197
|
transport,
|
|
@@ -777,9 +785,8 @@ function readerUnsupported(error, mode) {
|
|
|
777
785
|
for (let cause = error; cause && typeof cause === "object" && !seen.has(cause);) {
|
|
778
786
|
seen.add(cause);
|
|
779
787
|
const value = cause;
|
|
780
|
-
if (cause
|
|
788
|
+
if (hasReaderRevert(cause)) return false;
|
|
781
789
|
const message = typeof value.message === "string" ? value.message : "";
|
|
782
|
-
if (/execution reverted|out of gas|invalid opcode/i.test(message)) return false;
|
|
783
790
|
if (value.code === -32602 || value.code === -32004 || value.code === -32e3) {
|
|
784
791
|
const feature = mode === "deployless" ? /contract creation|deployless|creation calls?/i : /state.?overrides?/i;
|
|
785
792
|
const rejection = /not supported|unsupported|disabled/i;
|
|
@@ -796,11 +803,27 @@ function hasRevertData(data) {
|
|
|
796
803
|
const wrapped = data;
|
|
797
804
|
return [wrapped.data, wrapped.originalError?.data].some((value) => typeof value === "string" && /^0x[\da-f]+$/i.test(value));
|
|
798
805
|
}
|
|
806
|
+
/** A failed member contract must not become a shared malformed-response error. */
|
|
807
|
+
function readerReverted(error) {
|
|
808
|
+
const seen = /* @__PURE__ */ new Set();
|
|
809
|
+
for (let cause = error; cause && typeof cause === "object" && !seen.has(cause);) {
|
|
810
|
+
seen.add(cause);
|
|
811
|
+
if (hasReaderRevert(cause)) return true;
|
|
812
|
+
cause = cause.cause;
|
|
813
|
+
}
|
|
814
|
+
return false;
|
|
815
|
+
}
|
|
816
|
+
function hasReaderRevert(error) {
|
|
817
|
+
const value = error;
|
|
818
|
+
if (value.name?.startsWith("AbiDecoding")) return false;
|
|
819
|
+
return error instanceof ContractFunctionRevertedError || hasRevertData(value.data) || typeof value.message === "string" && /execution reverted|out of gas|invalid opcode/i.test(value.message);
|
|
820
|
+
}
|
|
799
821
|
//#endregion
|
|
800
822
|
//#region src/rpc/reader.ts
|
|
801
823
|
/** Ephemeral code-only execution. Vault callers verify original proxy code before overriding it. */
|
|
802
|
-
function executeReader(context, code, mode, read) {
|
|
803
|
-
|
|
824
|
+
async function executeReader(context, code, mode, read) {
|
|
825
|
+
const client = createClient({ transport: custom({ request: ({ method, params }) => context.transport.request(method, params ?? []) }, { retryCount: 0 }) });
|
|
826
|
+
const execution = mode === "deployless" ? {
|
|
804
827
|
blockNumber: context.blockNumber,
|
|
805
828
|
code: code.bytecode
|
|
806
829
|
} : {
|
|
@@ -810,7 +833,13 @@ function executeReader(context, code, mode, read) {
|
|
|
810
833
|
address: code.address,
|
|
811
834
|
code: code.runtime
|
|
812
835
|
}]
|
|
813
|
-
}
|
|
836
|
+
};
|
|
837
|
+
try {
|
|
838
|
+
return await read(client, execution);
|
|
839
|
+
} catch (error) {
|
|
840
|
+
if (readerUnsupported(error, mode) || readerReverted(error) || sharedReadError(error)) throw error;
|
|
841
|
+
throw new SharedRpcReadError("Shared reader execution failed", { cause: error });
|
|
842
|
+
}
|
|
814
843
|
}
|
|
815
844
|
/** Compatibility is eligible only after both execution modes explicitly reject support. */
|
|
816
845
|
async function readWithFallback(read) {
|
|
@@ -12238,6 +12267,11 @@ function nullableString(value) {
|
|
|
12238
12267
|
if (value === null || typeof value === "string") return value;
|
|
12239
12268
|
throw new Error("Malformed vault metadata string");
|
|
12240
12269
|
}
|
|
12270
|
+
function poolIdentifier(value) {
|
|
12271
|
+
if (value === null) return null;
|
|
12272
|
+
if (typeof value === "string" && /^0x[0-9a-fA-F]{64}$/.test(value)) return value.toLowerCase();
|
|
12273
|
+
return indexedAddress(value, true);
|
|
12274
|
+
}
|
|
12241
12275
|
/** Validate and detach indexed data, preserving nulls and optional pool keys. */
|
|
12242
12276
|
function vaultMetadata(value) {
|
|
12243
12277
|
const row = record(value);
|
|
@@ -12254,7 +12288,7 @@ function vaultMetadata(value) {
|
|
|
12254
12288
|
beaconName: row.beaconName,
|
|
12255
12289
|
createdAt: row.createdAt,
|
|
12256
12290
|
state: nullableString(row.state),
|
|
12257
|
-
pool:
|
|
12291
|
+
pool: poolIdentifier(row.pool),
|
|
12258
12292
|
...row.poolKey === void 0 ? {} : { poolKey: nullableString(row.poolKey) },
|
|
12259
12293
|
token0: row.token0 === null ? null : indexedAddress(row.token0, true),
|
|
12260
12294
|
token1: row.token1 === null ? null : indexedAddress(row.token1, true),
|
|
@@ -12286,6 +12320,15 @@ function captureVaultMetadata(addresses, values) {
|
|
|
12286
12320
|
for (const address of requested) if (!records.has(address)) throw new Error(`Supplied vault metadata is missing address: ${address}`);
|
|
12287
12321
|
return records;
|
|
12288
12322
|
}
|
|
12323
|
+
/** @internal A valid indexed response can omit individual vaults. */
|
|
12324
|
+
var MissingVaultMetadataError = class extends Error {
|
|
12325
|
+
records;
|
|
12326
|
+
constructor(records) {
|
|
12327
|
+
super("Vault metadata is not indexed");
|
|
12328
|
+
this.name = "MissingVaultMetadataError";
|
|
12329
|
+
this.records = Object.freeze([...records]);
|
|
12330
|
+
}
|
|
12331
|
+
};
|
|
12289
12332
|
//#endregion
|
|
12290
12333
|
//#region src/vault/resolver-types.ts
|
|
12291
12334
|
let ProtocolContractRole = /* @__PURE__ */ function(ProtocolContractRole) {
|
|
@@ -12818,9 +12861,10 @@ var CatalogSteerDataAdapter = class extends SteerDataAdapter {
|
|
|
12818
12861
|
if (!unique.includes(metadata.id) || records.has(metadata.id)) throw new Error("Unexpected or duplicate vault metadata");
|
|
12819
12862
|
records.set(metadata.id, metadata);
|
|
12820
12863
|
}
|
|
12864
|
+
if (unique.some((id) => !records.has(id))) throw new MissingVaultMetadataError([...records.values()]);
|
|
12821
12865
|
return Object.freeze(ids.map((id) => {
|
|
12822
12866
|
const metadata = records.get(id);
|
|
12823
|
-
if (!metadata) throw new Error("
|
|
12867
|
+
if (!metadata) throw new Error("Missing validated vault metadata");
|
|
12824
12868
|
return metadata;
|
|
12825
12869
|
}));
|
|
12826
12870
|
}
|
|
@@ -23044,17 +23088,20 @@ async function readV4PoolKey(context, contracts, id, options) {
|
|
|
23044
23088
|
}
|
|
23045
23089
|
//#endregion
|
|
23046
23090
|
//#region src/amm/adapters/uniswap-v4/rpc-data-adapter.ts
|
|
23047
|
-
/**
|
|
23091
|
+
/** Onchain pool-key resolution with optional independent indexed listing. */
|
|
23048
23092
|
var UniswapV4RpcDataAdapter = class extends V4PoolDataAdapter {
|
|
23049
23093
|
context;
|
|
23050
23094
|
contracts;
|
|
23051
|
-
|
|
23052
|
-
|
|
23095
|
+
#listing;
|
|
23096
|
+
constructor(context, contracts, listing) {
|
|
23097
|
+
super(listing?.definition ?? { kind: "rpc" });
|
|
23053
23098
|
this.context = context;
|
|
23054
23099
|
this.contracts = contracts;
|
|
23100
|
+
this.#listing = listing;
|
|
23055
23101
|
}
|
|
23056
|
-
async listPools() {
|
|
23057
|
-
throw new Error("Uniswap V4 pool listing is not configured on this network");
|
|
23102
|
+
async listPools(request, options) {
|
|
23103
|
+
if (!this.#listing) throw new Error("Uniswap V4 pool listing is not configured on this network");
|
|
23104
|
+
return this.#listing.listPools(request, options);
|
|
23058
23105
|
}
|
|
23059
23106
|
getPoolKey(id, options) {
|
|
23060
23107
|
return readV4PoolKey(this.context, this.contracts, id, options);
|
|
@@ -23072,8 +23119,11 @@ const uniswapV4Bsc = /* @__PURE__ */ new Deployment({
|
|
|
23072
23119
|
stateView: { address: "0xd13dd3d6e93f276fafc9db9e6bb47c1180aee0c4" },
|
|
23073
23120
|
quoter: { address: "0x9f75dd27d6664c475b90e105573e550ff69437b0" }
|
|
23074
23121
|
},
|
|
23075
|
-
dataAdapter: {
|
|
23076
|
-
|
|
23122
|
+
dataAdapter: {
|
|
23123
|
+
kind: "subgraph",
|
|
23124
|
+
url: "https://gateway.thegraph.com/api/subgraphs/id/EAq1nJKgjnuKH6Gj4RFjCW7LcL7E2uipbncdwV7TTWkX"
|
|
23125
|
+
}
|
|
23126
|
+
}, (context, definition) => new UniswapV4(context, definition, new UniswapV4RpcDataAdapter(context, definition.contracts, new UniswapV4DataAdapter(definition.dataAdapter, definition.contracts.poolManager.address, context))));
|
|
23077
23127
|
//#endregion
|
|
23078
23128
|
//#region src/amm/deployments/uniswap-v4-robinhood.ts
|
|
23079
23129
|
/** Qualified Robinhood V4 deployment; full pool keys are available from vault contracts. */
|
|
@@ -24330,7 +24380,8 @@ var VaultResolver = class {
|
|
|
24330
24380
|
}) } : {}
|
|
24331
24381
|
});
|
|
24332
24382
|
}
|
|
24333
|
-
#metadata(steer, addresses,
|
|
24383
|
+
#metadata(steer, addresses, options = {}) {
|
|
24384
|
+
const { supplied, allowMissing, onRequestError } = options;
|
|
24334
24385
|
let pending;
|
|
24335
24386
|
return async (address) => {
|
|
24336
24387
|
if (supplied) {
|
|
@@ -24339,6 +24390,7 @@ var VaultResolver = class {
|
|
|
24339
24390
|
return metadata;
|
|
24340
24391
|
}
|
|
24341
24392
|
pending ??= steer.dataAdapter.getVaultMetadata(addresses).catch((error) => {
|
|
24393
|
+
if (allowMissing && error instanceof MissingVaultMetadataError) return error.records;
|
|
24342
24394
|
if (onRequestError) return onRequestError(error);
|
|
24343
24395
|
throw error;
|
|
24344
24396
|
});
|
|
@@ -24373,10 +24425,14 @@ var VaultResolver = class {
|
|
|
24373
24425
|
let bulkSupported = !!this.#reader.readMany;
|
|
24374
24426
|
for (let start = 0; start < inputs.length; start += 64) {
|
|
24375
24427
|
const batch = inputs.slice(start, start + 64);
|
|
24376
|
-
const loadMetadata = this.#metadata(steer, batch,
|
|
24377
|
-
|
|
24378
|
-
|
|
24379
|
-
|
|
24428
|
+
const loadMetadata = this.#metadata(steer, batch, {
|
|
24429
|
+
...metadata ? { supplied: metadata } : {},
|
|
24430
|
+
allowMissing: partial,
|
|
24431
|
+
onRequestError: (error) => {
|
|
24432
|
+
metadataFailed = true;
|
|
24433
|
+
metadataError = error;
|
|
24434
|
+
throw error;
|
|
24435
|
+
}
|
|
24380
24436
|
});
|
|
24381
24437
|
const contexts = batch.map((address) => Object.freeze({
|
|
24382
24438
|
steer,
|
|
@@ -24432,10 +24488,13 @@ var VaultResolver = class {
|
|
|
24432
24488
|
let bulkSupported = !!this.#reader.readSnapshots;
|
|
24433
24489
|
for (let start = 0; start < inputs.length; start += 16) {
|
|
24434
24490
|
const batch = inputs.slice(start, start + 16);
|
|
24435
|
-
const loadMetadata = this.#metadata(steer, batch,
|
|
24436
|
-
|
|
24437
|
-
|
|
24438
|
-
|
|
24491
|
+
const loadMetadata = this.#metadata(steer, batch, {
|
|
24492
|
+
allowMissing: partial,
|
|
24493
|
+
onRequestError: (error) => {
|
|
24494
|
+
metadataFailed = true;
|
|
24495
|
+
metadataError = error;
|
|
24496
|
+
throw error;
|
|
24497
|
+
}
|
|
24439
24498
|
});
|
|
24440
24499
|
const contexts = batch.map((address) => Object.freeze({
|
|
24441
24500
|
steer,
|