@somnia-chain/contracts-sdk 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -1
- package/dist/abis.d.ts +21 -1
- package/dist/abis.js +17 -1
- package/dist/enumerate.d.ts +56 -0
- package/dist/enumerate.js +70 -0
- package/dist/gen/meta.d.ts +2 -2
- package/dist/gen/meta.js +2 -2
- package/dist/gen/registry.d.ts +9 -0
- package/dist/gen/registry.js +9 -0
- package/dist/index.d.ts +54 -4
- package/dist/index.js +16 -22
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -28,8 +28,18 @@ tryAddress("hideki-testnet", "somnia-markets", "MarketsCore"); // Address | null
|
|
|
28
28
|
|
|
29
29
|
contracts("somnia-mainnet", "somnia-markets"); // enumerate, for admin screens
|
|
30
30
|
identify("somnia-mainnet", "0x1a47…"); // reverse lookup: project, name, kind
|
|
31
|
+
|
|
32
|
+
allContracts();
|
|
33
|
+
// every current deployment across every live network — the dashboard form.
|
|
34
|
+
// Retired networks and superseded deployments are excluded by default, so a
|
|
35
|
+
// wiped testnet's addresses cannot be rendered as current by forgetting to
|
|
36
|
+
// filter: { includeRetiredNetworks, includeSuperseded, project } to widen it.
|
|
31
37
|
```
|
|
32
38
|
|
|
39
|
+
Entries carry `address`, `kind`, `status`, `version`, and `contract` — the
|
|
40
|
+
Solidity contract name, where a source stated one. `kind` and `status` are
|
|
41
|
+
unions (`DeploymentKind`, `ContractStatus`), not `string`.
|
|
42
|
+
|
|
33
43
|
Networks: `networks` (all, retired included), `network(slug)`,
|
|
34
44
|
`liveNetworks()`, and `toChain(slug, { rpcUrl })` for a viem-`Chain`-shaped
|
|
35
45
|
object — you supply the RPC URL, the registry deliberately records no public
|
|
@@ -60,8 +70,23 @@ abiByHash("sha256:…"); // historical ABIs too — decode an old tx corr
|
|
|
60
70
|
verifyAbi("sha256:…", abi); // sha256 over key-sorted compact JSON — verify, don't trust filenames
|
|
61
71
|
writeFunctions("somnia-mainnet", "somnia-markets", "MarketsCore");
|
|
62
72
|
// all state-changing functions — allowlists are application policy, not deployment facts
|
|
73
|
+
|
|
74
|
+
allContractsWithAbi();
|
|
75
|
+
// allContracts() with each ABI resolved to `abiJson` — addresses, networks and
|
|
76
|
+
// ABIs in one call. Costs the whole corpus, which is why it lives here.
|
|
63
77
|
```
|
|
64
78
|
|
|
79
|
+
### Not every deployment has an ABI
|
|
80
|
+
|
|
81
|
+
`abiFor` returns `null`, and `abiJson` is `null`, for a real share of what the
|
|
82
|
+
registry holds — around half, concentrated in the testnets. That is a fact
|
|
83
|
+
about the records, not a gap in the package: the registry records a contract
|
|
84
|
+
name only where a broadcast log stated it or the repo declared one, and an ABI
|
|
85
|
+
is looked up by that name. Deployments created from a shared script as
|
|
86
|
+
per-asset instances — `BTC_reader`, `ADA_oracle` — name a role rather than a
|
|
87
|
+
contract, so they carry an address and no ABI. `contract` is set on exactly
|
|
88
|
+
the entries that have one, so it is the field to branch on.
|
|
89
|
+
|
|
65
90
|
## Decoding calldata
|
|
66
91
|
|
|
67
92
|
Requires `viem` (optional peer dependency; only this entry needs it).
|
|
@@ -82,6 +107,12 @@ decodeBySelector(data); // 4-byte fallback across every ABI the registry holds
|
|
|
82
107
|
|
|
83
108
|
## Versioning
|
|
84
109
|
|
|
85
|
-
The package is a snapshot of the registry, published when
|
|
110
|
+
The package is a snapshot of the registry, and it is published when that
|
|
111
|
+
snapshot changes rather than when someone remembers to publish it. The
|
|
112
|
+
reconciliation lane compares the surface it would generate against the one the
|
|
113
|
+
last release shipped, and cuts a patch version whenever addresses, ABIs or
|
|
114
|
+
chain information moved — so a contract deployed today reaches npm on the next
|
|
115
|
+
lane run. Minor and major versions are cut by hand, for API changes.
|
|
116
|
+
|
|
86
117
|
Update the dependency to pick up newly deployed contracts — nothing is fetched
|
|
87
118
|
at runtime.
|
package/dist/abis.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { abisByHash } from "./gen/abis-index.js";
|
|
2
|
-
import { type NetworkSlug } from "./index.js";
|
|
2
|
+
import { type AllContractsOptions, type ListedContract, type NetworkSlug } from "./index.js";
|
|
3
3
|
export { abisByHash };
|
|
4
4
|
export { abiDigest, verifyAbi } from "./digest.js";
|
|
5
5
|
/**
|
|
@@ -24,6 +24,26 @@ export type AbiFunction = AbiItem & {
|
|
|
24
24
|
export declare function abiFor(net: NetworkSlug, project: string, name: string): readonly AbiItem[] | null;
|
|
25
25
|
/** Resolve a digest — including a historical one no current deployment points at — to its ABI. */
|
|
26
26
|
export declare function abiByHash(digest: string): readonly AbiItem[] | null;
|
|
27
|
+
export interface ResolvedContract extends ListedContract {
|
|
28
|
+
/**
|
|
29
|
+
* The recorded ABI, or null where the registry has none. Null is common and
|
|
30
|
+
* is a fact about the registry, not an error: an ABI is recorded only where
|
|
31
|
+
* a source named the contract, so per-asset instances deployed from a shared
|
|
32
|
+
* script — `BTC_reader`, `ADA_router` — usually carry an address and no ABI.
|
|
33
|
+
*/
|
|
34
|
+
abiJson: readonly AbiItem[] | null;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Every current deployment with its ABI already resolved — addresses,
|
|
38
|
+
* networks and ABIs in one call.
|
|
39
|
+
*
|
|
40
|
+
* This is the whole-corpus convenience, and it costs the whole corpus: it
|
|
41
|
+
* lives here rather than in the root entry so that importing it is a decision.
|
|
42
|
+
* A server or admin surface rendering every contract wants exactly this; a
|
|
43
|
+
* client bundle wants `allContracts()` from the root and a per-contract
|
|
44
|
+
* `./abi/*` module for the one ABI it actually needs.
|
|
45
|
+
*/
|
|
46
|
+
export declare function allContractsWithAbi(opts?: AllContractsOptions): ResolvedContract[];
|
|
27
47
|
/**
|
|
28
48
|
* The state-changing functions of one deployment's ABI. Deliberately the
|
|
29
49
|
* whole set: trimming it to an allowlist is operational policy, and policy
|
package/dist/abis.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { abisByHash } from "./gen/abis-index.js";
|
|
2
|
-
import { registry } from "./index.js";
|
|
2
|
+
import { allContracts, registry, } from "./index.js";
|
|
3
3
|
export { abisByHash };
|
|
4
4
|
export { abiDigest, verifyAbi } from "./digest.js";
|
|
5
5
|
/** The recorded ABI for one deployment, or null where the registry has none — including an unknown name, because the decoder path treats absence as an answer. For literal types, import the contract's `./abi/*` module. */
|
|
@@ -12,6 +12,22 @@ export function abiFor(net, project, name) {
|
|
|
12
12
|
export function abiByHash(digest) {
|
|
13
13
|
return abisByHash[digest] ?? null;
|
|
14
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Every current deployment with its ABI already resolved — addresses,
|
|
17
|
+
* networks and ABIs in one call.
|
|
18
|
+
*
|
|
19
|
+
* This is the whole-corpus convenience, and it costs the whole corpus: it
|
|
20
|
+
* lives here rather than in the root entry so that importing it is a decision.
|
|
21
|
+
* A server or admin surface rendering every contract wants exactly this; a
|
|
22
|
+
* client bundle wants `allContracts()` from the root and a per-contract
|
|
23
|
+
* `./abi/*` module for the one ABI it actually needs.
|
|
24
|
+
*/
|
|
25
|
+
export function allContractsWithAbi(opts = {}) {
|
|
26
|
+
return allContracts(opts).map((entry) => ({
|
|
27
|
+
...entry,
|
|
28
|
+
abiJson: entry.abi ? abiByHash(entry.abi) : null,
|
|
29
|
+
}));
|
|
30
|
+
}
|
|
15
31
|
/**
|
|
16
32
|
* The state-changing functions of one deployment's ABI. Deliberately the
|
|
17
33
|
* whole set: trimming it to an allowlist is operational policy, and policy
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enumeration over the address books, with no generated data in sight.
|
|
3
|
+
*
|
|
4
|
+
* Split out for the same reason `decode-core.ts` is: the generated modules are
|
|
5
|
+
* a build product, so anything that imports them cannot be tested until they
|
|
6
|
+
* exist — and the filtering here is precisely what a dashboard relies on to
|
|
7
|
+
* not render a wiped testnet's addresses as current. Structural types rather
|
|
8
|
+
* than the package's public ones, so this file depends on nothing.
|
|
9
|
+
*/
|
|
10
|
+
export interface BookEntry {
|
|
11
|
+
address: string;
|
|
12
|
+
kind: string;
|
|
13
|
+
status: string;
|
|
14
|
+
version: string;
|
|
15
|
+
contract?: string;
|
|
16
|
+
implementation?: string;
|
|
17
|
+
startBlock?: number;
|
|
18
|
+
abi?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface NetworkBook {
|
|
21
|
+
status: string;
|
|
22
|
+
contracts: Record<string, Record<string, BookEntry>>;
|
|
23
|
+
}
|
|
24
|
+
export type Books = Record<string, NetworkBook>;
|
|
25
|
+
export interface Listed extends BookEntry {
|
|
26
|
+
network: string;
|
|
27
|
+
project: string;
|
|
28
|
+
name: string;
|
|
29
|
+
}
|
|
30
|
+
export interface EnumerateOptions {
|
|
31
|
+
includeRetiredNetworks?: boolean;
|
|
32
|
+
includeSuperseded?: boolean;
|
|
33
|
+
project?: string;
|
|
34
|
+
}
|
|
35
|
+
/** One network's deployments, optionally one project's. Throws on an unknown slug. */
|
|
36
|
+
export declare function listContracts(books: Books, net: string, project?: string): Listed[];
|
|
37
|
+
/**
|
|
38
|
+
* Every current deployment across every live network.
|
|
39
|
+
*
|
|
40
|
+
* Both exclusions are defaults rather than the caller's job on purpose: a
|
|
41
|
+
* retired network's addresses answer on a chain that was wiped, and a
|
|
42
|
+
* superseded deployment is one a later release replaced. Requiring each call
|
|
43
|
+
* site to remember that is how one of them forgets.
|
|
44
|
+
*/
|
|
45
|
+
export declare function listAll(books: Books, opts?: EnumerateOptions): Listed[];
|
|
46
|
+
/**
|
|
47
|
+
* Address -> deployment, for one network.
|
|
48
|
+
*
|
|
49
|
+
* Proxy implementations resolve to their proxy's identity so that a signer
|
|
50
|
+
* looking at an implementation address learns which proxy it serves. The
|
|
51
|
+
* proxy's own entry always wins: `set` runs for every deployment first, and
|
|
52
|
+
* an implementation only claims an address nothing has claimed already.
|
|
53
|
+
*/
|
|
54
|
+
export declare function buildIdentityIndex(books: Books, net: string): Map<string, Listed & {
|
|
55
|
+
matchedBy: "address" | "implementation";
|
|
56
|
+
}>;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enumeration over the address books, with no generated data in sight.
|
|
3
|
+
*
|
|
4
|
+
* Split out for the same reason `decode-core.ts` is: the generated modules are
|
|
5
|
+
* a build product, so anything that imports them cannot be tested until they
|
|
6
|
+
* exist — and the filtering here is precisely what a dashboard relies on to
|
|
7
|
+
* not render a wiped testnet's addresses as current. Structural types rather
|
|
8
|
+
* than the package's public ones, so this file depends on nothing.
|
|
9
|
+
*/
|
|
10
|
+
/** One network's deployments, optionally one project's. Throws on an unknown slug. */
|
|
11
|
+
export function listContracts(books, net, project) {
|
|
12
|
+
const book = books[net];
|
|
13
|
+
if (!book)
|
|
14
|
+
throw new Error(`unknown network: ${net}`);
|
|
15
|
+
const out = [];
|
|
16
|
+
for (const [proj, entries] of Object.entries(book.contracts)) {
|
|
17
|
+
if (project !== undefined && proj !== project)
|
|
18
|
+
continue;
|
|
19
|
+
for (const [name, entry] of Object.entries(entries)) {
|
|
20
|
+
out.push({ network: net, project: proj, name, ...entry });
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return out;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Every current deployment across every live network.
|
|
27
|
+
*
|
|
28
|
+
* Both exclusions are defaults rather than the caller's job on purpose: a
|
|
29
|
+
* retired network's addresses answer on a chain that was wiped, and a
|
|
30
|
+
* superseded deployment is one a later release replaced. Requiring each call
|
|
31
|
+
* site to remember that is how one of them forgets.
|
|
32
|
+
*/
|
|
33
|
+
export function listAll(books, opts = {}) {
|
|
34
|
+
const out = [];
|
|
35
|
+
for (const net of Object.keys(books).sort()) {
|
|
36
|
+
if (!opts.includeRetiredNetworks && books[net].status !== "live")
|
|
37
|
+
continue;
|
|
38
|
+
for (const entry of listContracts(books, net, opts.project)) {
|
|
39
|
+
if (!opts.includeSuperseded && entry.status !== "active")
|
|
40
|
+
continue;
|
|
41
|
+
out.push(entry);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return out.sort((a, b) => a.network.localeCompare(b.network) ||
|
|
45
|
+
a.project.localeCompare(b.project) ||
|
|
46
|
+
a.name.localeCompare(b.name));
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Address -> deployment, for one network.
|
|
50
|
+
*
|
|
51
|
+
* Proxy implementations resolve to their proxy's identity so that a signer
|
|
52
|
+
* looking at an implementation address learns which proxy it serves. The
|
|
53
|
+
* proxy's own entry always wins: `set` runs for every deployment first, and
|
|
54
|
+
* an implementation only claims an address nothing has claimed already.
|
|
55
|
+
*/
|
|
56
|
+
export function buildIdentityIndex(books, net) {
|
|
57
|
+
const index = new Map();
|
|
58
|
+
const entries = listContracts(books, net);
|
|
59
|
+
for (const entry of entries) {
|
|
60
|
+
index.set(entry.address.toLowerCase(), { ...entry, matchedBy: "address" });
|
|
61
|
+
}
|
|
62
|
+
for (const entry of entries) {
|
|
63
|
+
if (!entry.implementation)
|
|
64
|
+
continue;
|
|
65
|
+
const key = entry.implementation.toLowerCase();
|
|
66
|
+
if (!index.has(key))
|
|
67
|
+
index.set(key, { ...entry, matchedBy: "implementation" });
|
|
68
|
+
}
|
|
69
|
+
return index;
|
|
70
|
+
}
|
package/dist/gen/meta.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const registryVersion: {
|
|
2
|
-
readonly commit: "
|
|
3
|
-
readonly generatedAt: "2026-09-
|
|
2
|
+
readonly commit: "316af61c453e611840fea61e5ff3450c9fd58f3c";
|
|
3
|
+
readonly generatedAt: "2026-09-29T12:20:25.060Z";
|
|
4
4
|
readonly schemaVersion: 1;
|
|
5
5
|
};
|
package/dist/gen/meta.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Generated by `registry sdk` from dist-public/ — do not edit.
|
|
2
2
|
export const registryVersion = {
|
|
3
|
-
commit: "
|
|
4
|
-
generatedAt: "2026-09-
|
|
3
|
+
commit: "316af61c453e611840fea61e5ff3450c9fd58f3c",
|
|
4
|
+
generatedAt: "2026-09-29T12:20:25.060Z",
|
|
5
5
|
schemaVersion: 1,
|
|
6
6
|
};
|
package/dist/gen/registry.d.ts
CHANGED
|
@@ -1057,6 +1057,15 @@ export declare const hideki2Testnet: {
|
|
|
1057
1057
|
readonly status: "active";
|
|
1058
1058
|
readonly version: "addr:0x1a483b48";
|
|
1059
1059
|
};
|
|
1060
|
+
readonly "prophecy-oracle": {
|
|
1061
|
+
readonly abi: "sha256:ecc4ba1d4404f9487b4d5d3e2b34ef1b7a1d9d188dbc94925ee07cd57d02943e";
|
|
1062
|
+
readonly address: "0xc09b648aDf093808A0478eb12Bc4eBa709413463";
|
|
1063
|
+
readonly contract: "ERC1967Proxy";
|
|
1064
|
+
readonly kind: "singleton";
|
|
1065
|
+
readonly startBlock: 3567925;
|
|
1066
|
+
readonly status: "active";
|
|
1067
|
+
readonly version: "addr:0xc09b648a";
|
|
1068
|
+
};
|
|
1060
1069
|
readonly "settlement-scheduler": {
|
|
1061
1070
|
readonly abi: "sha256:ecc4ba1d4404f9487b4d5d3e2b34ef1b7a1d9d188dbc94925ee07cd57d02943e";
|
|
1062
1071
|
readonly address: "0x9345df09F70EFe1F7d5608cD4e9f4a9871647E52";
|
package/dist/gen/registry.js
CHANGED
|
@@ -1063,6 +1063,15 @@ export const hideki2Testnet = {
|
|
|
1063
1063
|
"status": "active",
|
|
1064
1064
|
"version": "addr:0x1a483b48"
|
|
1065
1065
|
},
|
|
1066
|
+
"prophecy-oracle": {
|
|
1067
|
+
"abi": "sha256:ecc4ba1d4404f9487b4d5d3e2b34ef1b7a1d9d188dbc94925ee07cd57d02943e",
|
|
1068
|
+
"address": "0xc09b648aDf093808A0478eb12Bc4eBa709413463",
|
|
1069
|
+
"contract": "ERC1967Proxy",
|
|
1070
|
+
"kind": "singleton",
|
|
1071
|
+
"startBlock": 3567925,
|
|
1072
|
+
"status": "active",
|
|
1073
|
+
"version": "addr:0xc09b648a"
|
|
1074
|
+
},
|
|
1066
1075
|
"settlement-scheduler": {
|
|
1067
1076
|
"abi": "sha256:ecc4ba1d4404f9487b4d5d3e2b34ef1b7a1d9d188dbc94925ee07cd57d02943e",
|
|
1068
1077
|
"address": "0x9345df09F70EFe1F7d5608cD4e9f4a9871647E52",
|
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,19 @@ export type ProjectSlug<N extends NetworkSlug> = keyof Registry[N]["contracts"]
|
|
|
7
7
|
export type ContractName<N extends NetworkSlug, P extends ProjectSlug<N>> = keyof Registry[N]["contracts"][P] & string;
|
|
8
8
|
export type Address = `0x${string}`;
|
|
9
9
|
export type AbiDigest = `sha256:${string}`;
|
|
10
|
+
/**
|
|
11
|
+
* What a deployment is, structurally. `proxy` and `beacon-proxy` carry an
|
|
12
|
+
* `implementation`; `implementation` and `beacon` are the targets behind one
|
|
13
|
+
* and are recorded in their own right so an upgrade has something to point at;
|
|
14
|
+
* `external` is a contract Somnia depends on but did not deploy.
|
|
15
|
+
*/
|
|
16
|
+
export type DeploymentKind = "singleton" | "proxy" | "beacon" | "beacon-proxy" | "implementation" | "external";
|
|
17
|
+
/**
|
|
18
|
+
* Whether a deployment is the one to use. `superseded` and `retired` records
|
|
19
|
+
* are kept rather than deleted — decoding an old transaction needs the address
|
|
20
|
+
* that was current when it was sent.
|
|
21
|
+
*/
|
|
22
|
+
export type ContractStatus = "active" | "superseded" | "retired";
|
|
10
23
|
/** One deployment's record; narrow it by passing slugs and a name. The `abi` field is a digest — resolve it via the `./abis` entry point or a per-contract `./abi/*` module. */
|
|
11
24
|
export type ContractEntry<N extends NetworkSlug = NetworkSlug, P extends ProjectSlug<N> = ProjectSlug<N>, C extends ContractName<N, P> = ContractName<N, P>> = Registry[N]["contracts"][P][C];
|
|
12
25
|
type DistributedOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;
|
|
@@ -46,24 +59,61 @@ export declare function tryAddress(net: NetworkSlug, project: string, name: stri
|
|
|
46
59
|
export interface ListedContract {
|
|
47
60
|
network: NetworkSlug;
|
|
48
61
|
project: string;
|
|
62
|
+
/** The registry's name for this deployment — a role, like `BTC_reader`. */
|
|
49
63
|
name: string;
|
|
50
64
|
address: Address;
|
|
51
|
-
kind:
|
|
52
|
-
status:
|
|
65
|
+
kind: DeploymentKind;
|
|
66
|
+
status: ContractStatus;
|
|
53
67
|
version: string;
|
|
68
|
+
/**
|
|
69
|
+
* The Solidity contract name, where a source states it. Absent where no
|
|
70
|
+
* source did: the registry records a name only from a broadcast log or a
|
|
71
|
+
* repo declaration, never a guess. This is also the key the per-contract
|
|
72
|
+
* `./abi/<project>/<contract>` modules are published under, so an
|
|
73
|
+
* enumerated deployment can reach its typed ABI only when this is set —
|
|
74
|
+
* and it is set on exactly the deployments that have an `abi` digest.
|
|
75
|
+
*/
|
|
76
|
+
contract?: string;
|
|
54
77
|
implementation?: Address;
|
|
55
78
|
startBlock?: number;
|
|
56
79
|
abi?: AbiDigest;
|
|
57
80
|
}
|
|
58
81
|
/** Enumerate a network's deployments, optionally one project's. */
|
|
59
82
|
export declare function contracts(net: NetworkSlug, project?: string): ListedContract[];
|
|
83
|
+
export interface AllContractsOptions {
|
|
84
|
+
/**
|
|
85
|
+
* Include networks the registry has retired. Off by default: a retired
|
|
86
|
+
* network's addresses still exist but answer on a chain that was wiped, so
|
|
87
|
+
* showing them beside live ones is how a dashboard displays a balance that
|
|
88
|
+
* is not there.
|
|
89
|
+
*/
|
|
90
|
+
includeRetiredNetworks?: boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Include deployments superseded by a later one. Off by default — the
|
|
93
|
+
* registry publishes only each deployment's current release, so this
|
|
94
|
+
* changes nothing today and keeps meaning the same thing if that changes.
|
|
95
|
+
*/
|
|
96
|
+
includeSuperseded?: boolean;
|
|
97
|
+
project?: string;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Every current deployment, across every live network.
|
|
101
|
+
*
|
|
102
|
+
* The one call a dashboard wants: enumerating per network means knowing the
|
|
103
|
+
* slugs, remembering that retired ones exist, and filtering status by hand at
|
|
104
|
+
* every call site — three chances to show a wiped testnet's addresses as
|
|
105
|
+
* current. Ordered by network slug, then project, then name, so a rendered
|
|
106
|
+
* list is stable between releases.
|
|
107
|
+
*/
|
|
108
|
+
export declare function allContracts(opts?: AllContractsOptions): ListedContract[];
|
|
60
109
|
export interface ContractIdentity {
|
|
61
110
|
network: NetworkSlug;
|
|
62
111
|
project: string;
|
|
63
112
|
name: string;
|
|
64
|
-
kind:
|
|
65
|
-
status:
|
|
113
|
+
kind: DeploymentKind;
|
|
114
|
+
status: ContractStatus;
|
|
66
115
|
address: Address;
|
|
116
|
+
contract?: string;
|
|
67
117
|
implementation?: Address;
|
|
68
118
|
abi?: AbiDigest;
|
|
69
119
|
/** "address" — the queried address is the deployment; "implementation" — it is the implementation behind one. */
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { registry } from "./gen/registry.js";
|
|
2
|
+
import { buildIdentityIndex, listAll, listContracts } from "./enumerate.js";
|
|
2
3
|
export * from "./gen/registry.js";
|
|
3
4
|
export { registryVersion } from "./gen/meta.js";
|
|
4
5
|
function info(slug) {
|
|
@@ -56,20 +57,22 @@ export function tryAddress(net, project, name) {
|
|
|
56
57
|
const book = registry[net]?.contracts;
|
|
57
58
|
return book?.[project]?.[name]?.address ?? null;
|
|
58
59
|
}
|
|
60
|
+
const books = registry;
|
|
59
61
|
/** Enumerate a network's deployments, optionally one project's. */
|
|
60
62
|
export function contracts(net, project) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
63
|
+
return listContracts(books, net, project);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Every current deployment, across every live network.
|
|
67
|
+
*
|
|
68
|
+
* The one call a dashboard wants: enumerating per network means knowing the
|
|
69
|
+
* slugs, remembering that retired ones exist, and filtering status by hand at
|
|
70
|
+
* every call site — three chances to show a wiped testnet's addresses as
|
|
71
|
+
* current. Ordered by network slug, then project, then name, so a rendered
|
|
72
|
+
* list is stable between releases.
|
|
73
|
+
*/
|
|
74
|
+
export function allContracts(opts = {}) {
|
|
75
|
+
return listAll(books, opts);
|
|
73
76
|
}
|
|
74
77
|
const identityIndex = new Map();
|
|
75
78
|
/**
|
|
@@ -81,16 +84,7 @@ const identityIndex = new Map();
|
|
|
81
84
|
export function identify(net, addr) {
|
|
82
85
|
let index = identityIndex.get(net);
|
|
83
86
|
if (!index) {
|
|
84
|
-
index =
|
|
85
|
-
for (const entry of contracts(net)) {
|
|
86
|
-
const identity = { ...entry, matchedBy: "address" };
|
|
87
|
-
index.set(entry.address.toLowerCase(), identity);
|
|
88
|
-
if (entry.implementation) {
|
|
89
|
-
const viaImpl = entry.implementation.toLowerCase();
|
|
90
|
-
if (!index.has(viaImpl))
|
|
91
|
-
index.set(viaImpl, { ...identity, matchedBy: "implementation" });
|
|
92
|
-
}
|
|
93
|
-
}
|
|
87
|
+
index = buildIdentityIndex(books, net);
|
|
94
88
|
identityIndex.set(net, index);
|
|
95
89
|
}
|
|
96
90
|
return index.get(addr.toLowerCase()) ?? null;
|
package/package.json
CHANGED