@ixo/decision-oracle 0.2.4 → 0.2.6
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 +6 -3
- package/dist/cli/commands/init.d.ts +3 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +42 -2
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/oracle-init.d.ts.map +1 -1
- package/dist/cli/commands/oracle-init.js +13 -5
- package/dist/cli/commands/oracle-init.js.map +1 -1
- package/dist/cli/index.js +6 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/cron/openhands.d.ts +9 -0
- package/dist/cron/openhands.d.ts.map +1 -0
- package/dist/cron/openhands.js +30 -0
- package/dist/cron/openhands.js.map +1 -0
- package/dist/cron/scan.d.ts.map +1 -1
- package/dist/cron/scan.js +3 -0
- package/dist/cron/scan.js.map +1 -1
- package/dist/db/schema.d.ts +158 -0
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +26 -0
- package/dist/db/schema.js.map +1 -1
- package/dist/define-oracle.d.ts +3 -0
- package/dist/define-oracle.d.ts.map +1 -1
- package/dist/define-oracle.js +13 -1
- package/dist/define-oracle.js.map +1 -1
- package/dist/env.d.ts +12 -0
- package/dist/env.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/lib/ixo/blocksync/index.d.ts +4 -0
- package/dist/lib/ixo/blocksync/index.d.ts.map +1 -1
- package/dist/lib/ixo/blocksync/index.js +47 -1
- package/dist/lib/ixo/blocksync/index.js.map +1 -1
- package/dist/lib/ixo/blocksync/queries.d.ts +2 -0
- package/dist/lib/ixo/blocksync/queries.d.ts.map +1 -1
- package/dist/lib/ixo/blocksync/queries.js +17 -0
- package/dist/lib/ixo/blocksync/queries.js.map +1 -1
- package/dist/lib/ixo/chain.d.ts +1 -1
- package/dist/lib/ixo/chain.d.ts.map +1 -1
- package/dist/lib/openhands/backstop.d.ts +131 -0
- package/dist/lib/openhands/backstop.d.ts.map +1 -0
- package/dist/lib/openhands/backstop.js +513 -0
- package/dist/lib/openhands/backstop.js.map +1 -0
- package/dist/lib/openhands/chain.d.ts +218 -0
- package/dist/lib/openhands/chain.d.ts.map +1 -0
- package/dist/lib/openhands/chain.js +392 -0
- package/dist/lib/openhands/chain.js.map +1 -0
- package/dist/lib/openhands/options.d.ts +13 -0
- package/dist/lib/openhands/options.d.ts.map +1 -0
- package/dist/lib/openhands/options.js +28 -0
- package/dist/lib/openhands/options.js.map +1 -0
- package/dist/lib/openhands/routes.d.ts +73 -0
- package/dist/lib/openhands/routes.d.ts.map +1 -0
- package/dist/lib/openhands/routes.js +355 -0
- package/dist/lib/openhands/routes.js.map +1 -0
- package/dist/lib/openhands/store.d.ts +74 -0
- package/dist/lib/openhands/store.d.ts.map +1 -0
- package/dist/lib/openhands/store.js +148 -0
- package/dist/lib/openhands/store.js.map +1 -0
- package/dist/oracle.d.ts +52 -1
- package/dist/oracle.d.ts.map +1 -1
- package/dist/oracle.js +6 -0
- package/dist/oracle.js.map +1 -1
- package/dist/routes/v1/info.d.ts.map +1 -1
- package/dist/routes/v1/info.js +6 -0
- package/dist/routes/v1/info.js.map +1 -1
- package/dist/runtime.d.ts +6 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +10 -0
- package/dist/runtime.js.map +1 -1
- package/dist/workflows/openhands-hire.d.ts +65 -0
- package/dist/workflows/openhands-hire.d.ts.map +1 -0
- package/dist/workflows/openhands-hire.js +203 -0
- package/dist/workflows/openhands-hire.js.map +1 -0
- package/docs/api.md +70 -7
- package/docs/guide.md +33 -0
- package/migrations/0025_openhands.sql +12 -0
- package/migrations/meta/0025_snapshot.json +2976 -0
- package/migrations/meta/_journal.json +7 -0
- package/package.json +1 -1
- package/skills/README.md +1 -1
- package/skills/add-openhands-support/SKILL.md +96 -86
- package/skills/create-oracle/SKILL.md +10 -4
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The chain reads and the one chain WRITE the OpenHands hire needs (the `openhands` add-on), kept
|
|
3
|
+
* apart from the workflow that sequences them so every decision here is testable on its own.
|
|
4
|
+
*
|
|
5
|
+
* Why an oracle mints its own authorization at all: an OpenHands ask is one entity + one claim
|
|
6
|
+
* collection, and the collection id does not exist at the moment the poster grants. So the poster
|
|
7
|
+
* grants the oracle a META-authorization instead — `CreateClaimAuthorizationAuthorization` with
|
|
8
|
+
* `allowedAuthTypes = EVALUATE` — the right to hand itself the concrete `EvaluateClaimAuthorization`
|
|
9
|
+
* the register gate and the act lane require, once the collection exists. The oracle execs
|
|
10
|
+
* `MsgCreateClaimAuthorization` (creator = grantee = itself, admin = the ask's admin) inside a
|
|
11
|
+
* `MsgExec`, and the chain accepts it because of that meta-grant.
|
|
12
|
+
*
|
|
13
|
+
* Ported from the IXO-run OpenHands oracles (openhands-oracles `packages/core/src/openhands/
|
|
14
|
+
* chain.ts`), which ran it on mainnet first; the pool-payout ceilings stayed there.
|
|
15
|
+
*/
|
|
16
|
+
import type { Config } from "../../config.js";
|
|
17
|
+
import { type IxoSdk } from "../ixo/chain.js";
|
|
18
|
+
/** The meta-grant: the right to create claim authorizations on an admin's collections. */
|
|
19
|
+
export declare const META_AUTHZ = "/ixo.claims.v1beta1.CreateClaimAuthorizationAuthorization";
|
|
20
|
+
/** The concrete grant the register gate and the act lane read. */
|
|
21
|
+
export declare const EVALUATE_AUTHZ = "/ixo.claims.v1beta1.EvaluateClaimAuthorization";
|
|
22
|
+
/**
|
|
23
|
+
* The `msgTypeUrl` authz keys each grant under — the authorization's `MsgTypeURL()`, NOT its own
|
|
24
|
+
* type URL (ixo-blockchain `x/claims/types/authz.go`). A keyed `grants` read with the wrong one
|
|
25
|
+
* answers not-found, which would read as "no grant".
|
|
26
|
+
*/
|
|
27
|
+
export declare const META_MSG_TYPE = "/ixo.claims.v1beta1.MsgCreateClaimAuthorization";
|
|
28
|
+
export declare const EVALUATE_MSG_TYPE = "/ixo.claims.v1beta1.MsgEvaluateClaim";
|
|
29
|
+
/** CreateClaimAuthorizationType: ALL=0 (the chain refuses it), SUBMIT=1, EVALUATE=2. */
|
|
30
|
+
export declare const AUTH_EVALUATE = 2;
|
|
31
|
+
/**
|
|
32
|
+
* How long past an ask's end the oracle may still rule. The chain's end date stops SUBMISSIONS,
|
|
33
|
+
* not judgements: a claim filed on the last day is judged after it, and an authorization that died
|
|
34
|
+
* with the ask made those verdicts fail, quietly, for ever.
|
|
35
|
+
*/
|
|
36
|
+
export declare const JUDGE_GRACE_DAYS = 90;
|
|
37
|
+
export declare const JUDGE_GRACE_MS: number;
|
|
38
|
+
/**
|
|
39
|
+
* `maxAgentQuota = 0` is the CHAIN's "no cap", not "no evaluations" (the proto: "0 means no quota
|
|
40
|
+
* maximum quota per authorization").
|
|
41
|
+
*/
|
|
42
|
+
export declare const UNBOUNDED_QUOTA = 0;
|
|
43
|
+
/**
|
|
44
|
+
* What an unbounded meta-grant actually mints. `agentQuota` on the concrete authorization is a
|
|
45
|
+
* count the chain decrements once per verdict and DROPS the constraint at 0, so every mint is a
|
|
46
|
+
* batch of verdicts. A batch of 100 was spent in a busy day and the ask stalled behind the refill
|
|
47
|
+
* (mainnet ask 8253, 2026-10-06); the poster set no cap, so a large batch takes nothing they did
|
|
48
|
+
* not already give. A CAPPED meta-grant mints exactly its cap (`agentQuotaFor`).
|
|
49
|
+
*/
|
|
50
|
+
export declare const UNCAPPED_AGENT_QUOTA = 10000;
|
|
51
|
+
/**
|
|
52
|
+
* Remaining evaluate quota below which a hired collection is topped up — before 0, because 0 is an
|
|
53
|
+
* engine 403 and a paused collection. Margin, not arithmetic: a top-up is a hire rerun (a few chain
|
|
54
|
+
* round trips plus a block), so the batch has to outlast that and any verdicts already in flight.
|
|
55
|
+
*/
|
|
56
|
+
export declare const TOPUP_BELOW = 50;
|
|
57
|
+
type ClaimsSdk = IxoSdk["ixo"]["claims"]["v1beta1"];
|
|
58
|
+
/** The proto `Timestamp` shape the SDK's own `fromTimestamp` accepts. */
|
|
59
|
+
type ProtoTimestamp = Parameters<IxoSdk["utils"]["proto"]["fromTimestamp"]>[0];
|
|
60
|
+
type MetaAuthorization = ReturnType<ClaimsSdk["CreateClaimAuthorizationAuthorization"]["decode"]>;
|
|
61
|
+
/** `{ denom, amount }` as the SDK decodes it. */
|
|
62
|
+
export type ProtoCoin = MetaAuthorization["constraints"][number]["maxAmount"][number];
|
|
63
|
+
/** One `cosmos.authz` grant, narrowed to what a decoder needs. */
|
|
64
|
+
export interface AuthzGrant {
|
|
65
|
+
granter: string;
|
|
66
|
+
authorization?: {
|
|
67
|
+
typeUrl: string;
|
|
68
|
+
value: Uint8Array;
|
|
69
|
+
} | null | undefined;
|
|
70
|
+
expiration?: ProtoTimestamp | null | undefined;
|
|
71
|
+
}
|
|
72
|
+
/** A live meta-grant to this oracle: who it is for, who signed it, and what it caps. */
|
|
73
|
+
export interface MetaGrant {
|
|
74
|
+
/** The ask's admin account — the `adminAddress` the minted authorization must name. */
|
|
75
|
+
admin: string;
|
|
76
|
+
/** The account that signed the grant. Only one the admin signed is minted under (`pickMetaGrant`). */
|
|
77
|
+
granter: string;
|
|
78
|
+
/** The evaluation ceiling the poster set. `UNBOUNDED_QUOTA` (0) = the chain's "no cap". */
|
|
79
|
+
maxAgentQuota: number;
|
|
80
|
+
/** The member the authorization is scoped to, when the poster scoped it; "" = anyone. */
|
|
81
|
+
memberAddress: string;
|
|
82
|
+
/**
|
|
83
|
+
* The payout ceiling the poster set, verbatim — `[]` when they set none. The two proto comments
|
|
84
|
+
* are INVERTED: on the meta constraint empty means "any custom amount is allowed"; on the minted
|
|
85
|
+
* `EvaluateClaimConstraints.maxCustomAmount` it means "no custom amount — the collection's own
|
|
86
|
+
* approval payment is used". `mintCap` (`OpenhandsOptions.maxCustomAmount`) decides what an empty
|
|
87
|
+
* one becomes.
|
|
88
|
+
*/
|
|
89
|
+
maxAmount: ProtoCoin[];
|
|
90
|
+
/** The collections the constraint names. EMPTY means every collection of that admin. */
|
|
91
|
+
collectionIds: string[];
|
|
92
|
+
/** When the right to mint dies — the EARLIER of the grant's and the constraint's; null = never. */
|
|
93
|
+
expiration: Date | null;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* What to write as `maxCustomAmount` when the poster's meta-grant names no ceiling, given the
|
|
97
|
+
* collection's approval denom. Unset ⇒ `[]`: the collection's own approval payment pays, which is
|
|
98
|
+
* what every priced ask wants. An oracle that NAMES payouts (`policies.act`) supplies its ceiling.
|
|
99
|
+
*/
|
|
100
|
+
export type MintCap = (approvalDenom: string | null) => ProtoCoin[];
|
|
101
|
+
/**
|
|
102
|
+
* Every live EVALUATE meta-grant in `grants`, one per eligible CONSTRAINT. A grant that will not
|
|
103
|
+
* decode is a grant this oracle does not hold — skipped, never guessed at. Both expiries are
|
|
104
|
+
* honoured and the earlier wins. `collectionId`, when given, drops constraints that do not cover it.
|
|
105
|
+
*/
|
|
106
|
+
export declare function decodeMetaGrants(grants: readonly AuthzGrant[], sdk: IxoSdk, now: Date, collectionId?: string): MetaGrant[];
|
|
107
|
+
/** The meta-grants among `metas` that cover `collectionId` — decode once, re-scope many times. */
|
|
108
|
+
export declare function metasForCollection(metas: readonly MetaGrant[], collectionId: string): MetaGrant[];
|
|
109
|
+
/** What to put on the minted authorization: the poster's cap, or `UNCAPPED_AGENT_QUOTA` for none. */
|
|
110
|
+
export declare function agentQuotaFor(meta: MetaGrant): number;
|
|
111
|
+
/**
|
|
112
|
+
* The grant among `metas` to mint under for `admin`, or null. Only one the ADMIN signed, naming
|
|
113
|
+
* the admin — the chain's rule twice over: `MsgCreateClaimAuthorization` is signed by
|
|
114
|
+
* `admin_address`, so the `MsgExec` is authorized by the grant FROM the admin and no other key; and
|
|
115
|
+
* the meta-grant's `Accept` refuses a message naming another admin. Accepting anyone else's grant
|
|
116
|
+
* let a stranger aim this oracle's work at a victim's collections.
|
|
117
|
+
*/
|
|
118
|
+
export declare function pickMetaGrant(metas: readonly MetaGrant[], admin: string): MetaGrant | null;
|
|
119
|
+
/** Grants per `granteeGrants` page — above the node's default of 100. */
|
|
120
|
+
export declare const GRANTS_PAGE_LIMIT = 200;
|
|
121
|
+
/** One `granteeGrants` page and the key of the next ("" when it was the last). */
|
|
122
|
+
export interface GrantsPage {
|
|
123
|
+
grants: AuthzGrant[];
|
|
124
|
+
nextKey: Uint8Array;
|
|
125
|
+
sdk: IxoSdk;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* ONE page of the grants to this oracle's wallet, starting at `key` (empty = the first page) — the
|
|
129
|
+
* unit the backstop's discovery lane walks, a few pages a tick. Not-found means "none" only on the
|
|
130
|
+
* FIRST page; part-way through a walk it is a key the node no longer recognises, and throws.
|
|
131
|
+
*/
|
|
132
|
+
export declare function grantsPage(config: Config, key?: Uint8Array): Promise<GrantsPage>;
|
|
133
|
+
/**
|
|
134
|
+
* A collection's admin read off the CHAIN, or null when the chain has no such collection — for the
|
|
135
|
+
* hire webhook, called seconds after an ask is posted, before Blocksync has necessarily indexed
|
|
136
|
+
* it. Every failure but the chain's `collection not found` throws: an RPC outage is never "none".
|
|
137
|
+
*/
|
|
138
|
+
export declare function collectionAdminOnChain(config: Config, collectionId: string): Promise<string | null>;
|
|
139
|
+
/** A keyed read of one granter plus what is needed to read it, judged against one clock. */
|
|
140
|
+
export interface OracleGrants {
|
|
141
|
+
grants: AuthzGrant[];
|
|
142
|
+
/** The live EVALUATE meta-grants among `grants`, unscoped to any collection. */
|
|
143
|
+
metas: MetaGrant[];
|
|
144
|
+
sdk: IxoSdk;
|
|
145
|
+
now: Date;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Everything `granter` granted this oracle — its meta-grant and every authorization minted under it
|
|
149
|
+
* — in ONE keyed read. Complete for that admin: both halves are granted from the admin's account.
|
|
150
|
+
*/
|
|
151
|
+
export declare function readGrantsFrom(config: Config, granter: string): Promise<OracleGrants>;
|
|
152
|
+
/** The `EvaluateClaimAuthorization`s `admin` granted this oracle (the hire's mint step). */
|
|
153
|
+
export declare function readEvaluateGrantsFrom(config: Config, admin: string): Promise<OracleGrants>;
|
|
154
|
+
/** The live meta-grant that lets this oracle mint for `admin`'s `collectionId`, or null. */
|
|
155
|
+
export declare function metaGrantFor(config: Config, admin: string, collectionId: string): Promise<MetaGrant | null>;
|
|
156
|
+
/** The ceiling to write on the minted authorization: the poster's verbatim, else `mintCap`'s. */
|
|
157
|
+
export declare function capForMint(metaCap: readonly ProtoCoin[], approvalDenom: string | null, mintCap?: MintCap): ProtoCoin[];
|
|
158
|
+
/** Two payout ceilings as the chain sees them: same denoms and amounts, order irrelevant. */
|
|
159
|
+
export declare function sameCap(a: readonly ProtoCoin[], b: readonly ProtoCoin[]): boolean;
|
|
160
|
+
/**
|
|
161
|
+
* Does this oracle already hold a live authorization for `collectionId` on the poster's CURRENT
|
|
162
|
+
* terms (the ceiling `capForMint` would write today)? A poster who raises their ceiling later
|
|
163
|
+
* leaves an authorization that cannot pay what is named; answering false re-mints beside it — the
|
|
164
|
+
* chain APPENDS constraints and `Accept` passes over one whose cap cannot cover the amount.
|
|
165
|
+
*/
|
|
166
|
+
export declare function holdsMatchingEvaluateGrant(chain: Pick<OracleGrants, "grants" | "sdk" | "now">, args: {
|
|
167
|
+
admin: string;
|
|
168
|
+
collectionId: string;
|
|
169
|
+
metaCap: readonly ProtoCoin[];
|
|
170
|
+
approvalDenom: string | null;
|
|
171
|
+
mintCap?: MintCap;
|
|
172
|
+
}): boolean;
|
|
173
|
+
/**
|
|
174
|
+
* How many more verdicts this oracle can sign on `collectionId`: the `agentQuota` of every live
|
|
175
|
+
* constraint naming it, summed — how the chain spends it (`Accept` decrements the first covering
|
|
176
|
+
* constraint). A quota that will not read counts as nothing: under-counting costs one early top-up.
|
|
177
|
+
*/
|
|
178
|
+
export declare function remainingEvaluateQuota(chain: Pick<OracleGrants, "grants" | "sdk" | "now">, args: {
|
|
179
|
+
admin: string;
|
|
180
|
+
collectionId: string;
|
|
181
|
+
}): number;
|
|
182
|
+
/**
|
|
183
|
+
* Should a collection holding `remaining` verdicts get another mint of `mintQuota`? Below
|
|
184
|
+
* `TOPUP_BELOW`, or below one mint when the poster's cap is smaller — which keeps it idempotent:
|
|
185
|
+
* after a mint `remaining >= mintQuota`, so a retried step re-reads the chain and stops.
|
|
186
|
+
*/
|
|
187
|
+
export declare function needsTopUp(remaining: number, mintQuota: number): boolean;
|
|
188
|
+
/**
|
|
189
|
+
* The `MsgExec`-wrapped `MsgCreateClaimAuthorization` this oracle signs to hand ITSELF the
|
|
190
|
+
* collection's evaluate right, under the poster's meta-grant. `maxAmount` is `capForMint`'s.
|
|
191
|
+
*/
|
|
192
|
+
export declare function mintEvaluateAuthzMsg(sdk: IxoSdk, args: {
|
|
193
|
+
oracleAddress: string;
|
|
194
|
+
oracleDid: string;
|
|
195
|
+
admin: string;
|
|
196
|
+
collectionId: string;
|
|
197
|
+
agentQuota: number;
|
|
198
|
+
beforeDate: Date;
|
|
199
|
+
maxAmount: ProtoCoin[];
|
|
200
|
+
/** Carried from the meta-grant when the poster scoped it — the chain checks the two agree. */
|
|
201
|
+
memberAddress?: string;
|
|
202
|
+
}): {
|
|
203
|
+
typeUrl: string;
|
|
204
|
+
value: unknown;
|
|
205
|
+
};
|
|
206
|
+
/**
|
|
207
|
+
* How long the minted authorization may live: never past the poster's meta-grant, never past the
|
|
208
|
+
* ask's end plus the judging grace (a year for an ask with no end). Must be in the future.
|
|
209
|
+
*/
|
|
210
|
+
export declare function beforeDateFor(meta: MetaGrant, endDate: string | null, now: Date): Date;
|
|
211
|
+
/** The denom of a collection's first approval coin (its on-chain `payments`), or null. */
|
|
212
|
+
export declare function approvalDenomOf(payments: unknown): string | null;
|
|
213
|
+
/** An ask that ended may still be judged for `JUDGE_GRACE_DAYS`; an unreadable end is no end. */
|
|
214
|
+
export declare function isJudgeable(endDate: string | null, now: Date): boolean;
|
|
215
|
+
/** End plus grace as an ISO stamp (`openhands_hires.ends_at`), or null for no readable end. */
|
|
216
|
+
export declare function endsAtOf(endDate: string | null): string | null;
|
|
217
|
+
export {};
|
|
218
|
+
//# sourceMappingURL=chain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chain.d.ts","sourceRoot":"","sources":["../../../src/lib/openhands/chain.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The chain reads and the one chain WRITE the OpenHands hire needs (the `openhands` add-on), kept
|
|
3
|
+
* apart from the workflow that sequences them so every decision here is testable on its own.
|
|
4
|
+
*
|
|
5
|
+
* Why an oracle mints its own authorization at all: an OpenHands ask is one entity + one claim
|
|
6
|
+
* collection, and the collection id does not exist at the moment the poster grants. So the poster
|
|
7
|
+
* grants the oracle a META-authorization instead — `CreateClaimAuthorizationAuthorization` with
|
|
8
|
+
* `allowedAuthTypes = EVALUATE` — the right to hand itself the concrete `EvaluateClaimAuthorization`
|
|
9
|
+
* the register gate and the act lane require, once the collection exists. The oracle execs
|
|
10
|
+
* `MsgCreateClaimAuthorization` (creator = grantee = itself, admin = the ask's admin) inside a
|
|
11
|
+
* `MsgExec`, and the chain accepts it because of that meta-grant.
|
|
12
|
+
*
|
|
13
|
+
* Ported from the IXO-run OpenHands oracles (openhands-oracles `packages/core/src/openhands/
|
|
14
|
+
* chain.ts`), which ran it on mainnet first; the pool-payout ceilings stayed there.
|
|
15
|
+
*/
|
|
16
|
+
import { getIxoSdk, getQueryClient, timedRpc } from "../ixo/chain.js";
|
|
17
|
+
/** The meta-grant: the right to create claim authorizations on an admin's collections. */
|
|
18
|
+
export const META_AUTHZ = "/ixo.claims.v1beta1.CreateClaimAuthorizationAuthorization";
|
|
19
|
+
/** The concrete grant the register gate and the act lane read. */
|
|
20
|
+
export const EVALUATE_AUTHZ = "/ixo.claims.v1beta1.EvaluateClaimAuthorization";
|
|
21
|
+
/**
|
|
22
|
+
* The `msgTypeUrl` authz keys each grant under — the authorization's `MsgTypeURL()`, NOT its own
|
|
23
|
+
* type URL (ixo-blockchain `x/claims/types/authz.go`). A keyed `grants` read with the wrong one
|
|
24
|
+
* answers not-found, which would read as "no grant".
|
|
25
|
+
*/
|
|
26
|
+
export const META_MSG_TYPE = "/ixo.claims.v1beta1.MsgCreateClaimAuthorization";
|
|
27
|
+
export const EVALUATE_MSG_TYPE = "/ixo.claims.v1beta1.MsgEvaluateClaim";
|
|
28
|
+
/** CreateClaimAuthorizationType: ALL=0 (the chain refuses it), SUBMIT=1, EVALUATE=2. */
|
|
29
|
+
export const AUTH_EVALUATE = 2;
|
|
30
|
+
const DAY_MS = 86_400_000;
|
|
31
|
+
/**
|
|
32
|
+
* How long past an ask's end the oracle may still rule. The chain's end date stops SUBMISSIONS,
|
|
33
|
+
* not judgements: a claim filed on the last day is judged after it, and an authorization that died
|
|
34
|
+
* with the ask made those verdicts fail, quietly, for ever.
|
|
35
|
+
*/
|
|
36
|
+
export const JUDGE_GRACE_DAYS = 90;
|
|
37
|
+
export const JUDGE_GRACE_MS = JUDGE_GRACE_DAYS * DAY_MS;
|
|
38
|
+
/**
|
|
39
|
+
* `maxAgentQuota = 0` is the CHAIN's "no cap", not "no evaluations" (the proto: "0 means no quota
|
|
40
|
+
* maximum quota per authorization").
|
|
41
|
+
*/
|
|
42
|
+
export const UNBOUNDED_QUOTA = 0;
|
|
43
|
+
/**
|
|
44
|
+
* What an unbounded meta-grant actually mints. `agentQuota` on the concrete authorization is a
|
|
45
|
+
* count the chain decrements once per verdict and DROPS the constraint at 0, so every mint is a
|
|
46
|
+
* batch of verdicts. A batch of 100 was spent in a busy day and the ask stalled behind the refill
|
|
47
|
+
* (mainnet ask 8253, 2026-10-06); the poster set no cap, so a large batch takes nothing they did
|
|
48
|
+
* not already give. A CAPPED meta-grant mints exactly its cap (`agentQuotaFor`).
|
|
49
|
+
*/
|
|
50
|
+
export const UNCAPPED_AGENT_QUOTA = 10_000;
|
|
51
|
+
/**
|
|
52
|
+
* Remaining evaluate quota below which a hired collection is topped up — before 0, because 0 is an
|
|
53
|
+
* engine 403 and a paused collection. Margin, not arithmetic: a top-up is a hire rerun (a few chain
|
|
54
|
+
* round trips plus a block), so the batch has to outlast that and any verdicts already in flight.
|
|
55
|
+
*/
|
|
56
|
+
export const TOPUP_BELOW = 50;
|
|
57
|
+
/** A proto amount (`Long`, bigint, string or number) as a JS number; unreadable stays NaN. */
|
|
58
|
+
function toNumber(value) {
|
|
59
|
+
if (typeof value === "number")
|
|
60
|
+
return value;
|
|
61
|
+
if (value === null || value === undefined)
|
|
62
|
+
return Number.NaN;
|
|
63
|
+
return Number(String(value));
|
|
64
|
+
}
|
|
65
|
+
function timestampToDate(sdk, value) {
|
|
66
|
+
if (value === null || value === undefined)
|
|
67
|
+
return null;
|
|
68
|
+
const date = sdk.utils.proto.fromTimestamp(value);
|
|
69
|
+
return Number.isFinite(date.getTime()) ? date : null;
|
|
70
|
+
}
|
|
71
|
+
const isLive = (expiry, now) => expiry === null || expiry.getTime() > now.getTime();
|
|
72
|
+
/** The chain's scoping rule: an empty list is every collection, not none. */
|
|
73
|
+
const coversCollection = (ids, collectionId) => ids.length === 0 || ids.includes(collectionId);
|
|
74
|
+
function earliest(a, b) {
|
|
75
|
+
if (a === null)
|
|
76
|
+
return b;
|
|
77
|
+
if (b === null)
|
|
78
|
+
return a;
|
|
79
|
+
return a.getTime() <= b.getTime() ? a : b;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Every live EVALUATE meta-grant in `grants`, one per eligible CONSTRAINT. A grant that will not
|
|
83
|
+
* decode is a grant this oracle does not hold — skipped, never guessed at. Both expiries are
|
|
84
|
+
* honoured and the earlier wins. `collectionId`, when given, drops constraints that do not cover it.
|
|
85
|
+
*/
|
|
86
|
+
export function decodeMetaGrants(grants, sdk, now, collectionId) {
|
|
87
|
+
const out = [];
|
|
88
|
+
for (const grant of grants) {
|
|
89
|
+
const authorization = grant.authorization;
|
|
90
|
+
if (!authorization || authorization.typeUrl !== META_AUTHZ)
|
|
91
|
+
continue;
|
|
92
|
+
let decoded;
|
|
93
|
+
try {
|
|
94
|
+
decoded = sdk.ixo.claims.v1beta1.CreateClaimAuthorizationAuthorization.decode(authorization.value);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
const grantExpiry = timestampToDate(sdk, grant.expiration);
|
|
100
|
+
if (!isLive(grantExpiry, now))
|
|
101
|
+
continue;
|
|
102
|
+
for (const constraint of decoded.constraints) {
|
|
103
|
+
if (Number(constraint.allowedAuthTypes) !== AUTH_EVALUATE)
|
|
104
|
+
continue;
|
|
105
|
+
// Zero IS readable: it is the chain's "no cap". Unreadable or negative is not mintable.
|
|
106
|
+
const maxAgentQuota = toNumber(constraint.maxAgentQuota);
|
|
107
|
+
if (!Number.isFinite(maxAgentQuota) || maxAgentQuota < 0)
|
|
108
|
+
continue;
|
|
109
|
+
const scoped = constraint.collectionIds ?? [];
|
|
110
|
+
if (collectionId !== undefined && !coversCollection(scoped, collectionId))
|
|
111
|
+
continue;
|
|
112
|
+
const expiration = earliest(grantExpiry, timestampToDate(sdk, constraint.expiration));
|
|
113
|
+
if (!isLive(expiration, now))
|
|
114
|
+
continue;
|
|
115
|
+
out.push({
|
|
116
|
+
admin: decoded.admin,
|
|
117
|
+
granter: grant.granter,
|
|
118
|
+
maxAgentQuota,
|
|
119
|
+
memberAddress: constraint.memberAddress ?? "",
|
|
120
|
+
maxAmount: constraint.maxAmount ?? [],
|
|
121
|
+
collectionIds: scoped,
|
|
122
|
+
expiration,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return out;
|
|
127
|
+
}
|
|
128
|
+
/** The meta-grants among `metas` that cover `collectionId` — decode once, re-scope many times. */
|
|
129
|
+
export function metasForCollection(metas, collectionId) {
|
|
130
|
+
return metas.filter((meta) => coversCollection(meta.collectionIds, collectionId));
|
|
131
|
+
}
|
|
132
|
+
/** What to put on the minted authorization: the poster's cap, or `UNCAPPED_AGENT_QUOTA` for none. */
|
|
133
|
+
export function agentQuotaFor(meta) {
|
|
134
|
+
return meta.maxAgentQuota === UNBOUNDED_QUOTA ? UNCAPPED_AGENT_QUOTA : meta.maxAgentQuota;
|
|
135
|
+
}
|
|
136
|
+
/** Unbounded first (it buys the most verdicts), then the longest-lived, then the largest cap. */
|
|
137
|
+
function byReach(a, b) {
|
|
138
|
+
const unbounded = (g) => (g.maxAgentQuota === UNBOUNDED_QUOTA ? 1 : 0);
|
|
139
|
+
if (unbounded(a) !== unbounded(b))
|
|
140
|
+
return unbounded(b) - unbounded(a);
|
|
141
|
+
const reach = (g) => g.expiration?.getTime() ?? Number.POSITIVE_INFINITY;
|
|
142
|
+
if (reach(a) !== reach(b))
|
|
143
|
+
return reach(b) - reach(a);
|
|
144
|
+
return b.maxAgentQuota - a.maxAgentQuota;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* The grant among `metas` to mint under for `admin`, or null. Only one the ADMIN signed, naming
|
|
148
|
+
* the admin — the chain's rule twice over: `MsgCreateClaimAuthorization` is signed by
|
|
149
|
+
* `admin_address`, so the `MsgExec` is authorized by the grant FROM the admin and no other key; and
|
|
150
|
+
* the meta-grant's `Accept` refuses a message naming another admin. Accepting anyone else's grant
|
|
151
|
+
* let a stranger aim this oracle's work at a victim's collections.
|
|
152
|
+
*/
|
|
153
|
+
export function pickMetaGrant(metas, admin) {
|
|
154
|
+
return metas.filter((g) => g.granter === admin && g.admin === admin).sort(byReach)[0] ?? null;
|
|
155
|
+
}
|
|
156
|
+
/** Grants per `granteeGrants` page — above the node's default of 100. */
|
|
157
|
+
export const GRANTS_PAGE_LIMIT = 200;
|
|
158
|
+
const notFound = (err) => String(err).toLowerCase().includes("not found");
|
|
159
|
+
/**
|
|
160
|
+
* ONE page of the grants to this oracle's wallet, starting at `key` (empty = the first page) — the
|
|
161
|
+
* unit the backstop's discovery lane walks, a few pages a tick. Not-found means "none" only on the
|
|
162
|
+
* FIRST page; part-way through a walk it is a key the node no longer recognises, and throws.
|
|
163
|
+
*/
|
|
164
|
+
export async function grantsPage(config, key = new Uint8Array()) {
|
|
165
|
+
const [sdk, queryClient] = await Promise.all([getIxoSdk(), getQueryClient(config)]);
|
|
166
|
+
const { numberToLong } = sdk.utils.proto;
|
|
167
|
+
try {
|
|
168
|
+
const response = await timedRpc("authz-grantee-grants", () => queryClient.cosmos.authz.v1beta1.granteeGrants({
|
|
169
|
+
grantee: config.ORACLE_ADDRESS,
|
|
170
|
+
pagination: {
|
|
171
|
+
key,
|
|
172
|
+
offset: numberToLong(0),
|
|
173
|
+
limit: numberToLong(GRANTS_PAGE_LIMIT),
|
|
174
|
+
countTotal: false,
|
|
175
|
+
reverse: false,
|
|
176
|
+
},
|
|
177
|
+
}), (err) => key.length === 0 && notFound(err));
|
|
178
|
+
return {
|
|
179
|
+
grants: response.grants,
|
|
180
|
+
nextKey: response.pagination?.nextKey ?? new Uint8Array(),
|
|
181
|
+
sdk,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
catch (err) {
|
|
185
|
+
if (key.length === 0 && notFound(err))
|
|
186
|
+
return { grants: [], nextKey: new Uint8Array(), sdk };
|
|
187
|
+
throw err;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* A collection's admin read off the CHAIN, or null when the chain has no such collection — for the
|
|
192
|
+
* hire webhook, called seconds after an ask is posted, before Blocksync has necessarily indexed
|
|
193
|
+
* it. Every failure but the chain's `collection not found` throws: an RPC outage is never "none".
|
|
194
|
+
*/
|
|
195
|
+
export async function collectionAdminOnChain(config, collectionId) {
|
|
196
|
+
const queryClient = await getQueryClient(config);
|
|
197
|
+
try {
|
|
198
|
+
const { collection } = await timedRpc("claims-collection", () => queryClient.ixo.claims.v1beta1.collection({ id: collectionId }), (err) => /collection not found/i.test(String(err)));
|
|
199
|
+
return collection?.admin || null;
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
if (/collection not found/i.test(String(err)))
|
|
203
|
+
return null;
|
|
204
|
+
throw err;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* What `granter` granted this oracle for `msgTypeUrl`, by the keyed `grants` query — one store
|
|
209
|
+
* lookup. `msgTypeUrl = ""` asks for every grant of the pair in that one read (the meta-grant and
|
|
210
|
+
* what was minted under it together). Not-found is how the chain answers "never granted".
|
|
211
|
+
*/
|
|
212
|
+
async function grantsFrom(config, granter, msgTypeUrl) {
|
|
213
|
+
const queryClient = await getQueryClient(config);
|
|
214
|
+
try {
|
|
215
|
+
const { grants } = await timedRpc("authz-grants", () => queryClient.cosmos.authz.v1beta1.grants({
|
|
216
|
+
granter,
|
|
217
|
+
grantee: config.ORACLE_ADDRESS,
|
|
218
|
+
msgTypeUrl,
|
|
219
|
+
}), notFound);
|
|
220
|
+
return grants.map((g) => ({
|
|
221
|
+
granter,
|
|
222
|
+
authorization: g.authorization,
|
|
223
|
+
expiration: g.expiration,
|
|
224
|
+
}));
|
|
225
|
+
}
|
|
226
|
+
catch (err) {
|
|
227
|
+
if (notFound(err))
|
|
228
|
+
return [];
|
|
229
|
+
throw err;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Everything `granter` granted this oracle — its meta-grant and every authorization minted under it
|
|
234
|
+
* — in ONE keyed read. Complete for that admin: both halves are granted from the admin's account.
|
|
235
|
+
*/
|
|
236
|
+
export async function readGrantsFrom(config, granter) {
|
|
237
|
+
const [sdk, grants] = await Promise.all([getIxoSdk(), grantsFrom(config, granter, "")]);
|
|
238
|
+
const now = new Date();
|
|
239
|
+
return { grants, metas: decodeMetaGrants(grants, sdk, now), sdk, now };
|
|
240
|
+
}
|
|
241
|
+
/** The `EvaluateClaimAuthorization`s `admin` granted this oracle (the hire's mint step). */
|
|
242
|
+
export async function readEvaluateGrantsFrom(config, admin) {
|
|
243
|
+
const [sdk, grants] = await Promise.all([
|
|
244
|
+
getIxoSdk(),
|
|
245
|
+
grantsFrom(config, admin, EVALUATE_MSG_TYPE),
|
|
246
|
+
]);
|
|
247
|
+
return { grants, metas: [], sdk, now: new Date() };
|
|
248
|
+
}
|
|
249
|
+
/** The live meta-grant that lets this oracle mint for `admin`'s `collectionId`, or null. */
|
|
250
|
+
export async function metaGrantFor(config, admin, collectionId) {
|
|
251
|
+
const [sdk, own] = await Promise.all([getIxoSdk(), grantsFrom(config, admin, META_MSG_TYPE)]);
|
|
252
|
+
return pickMetaGrant(decodeMetaGrants(own, sdk, new Date(), collectionId), admin);
|
|
253
|
+
}
|
|
254
|
+
/** The ceiling to write on the minted authorization: the poster's verbatim, else `mintCap`'s. */
|
|
255
|
+
export function capForMint(metaCap, approvalDenom, mintCap) {
|
|
256
|
+
if (metaCap.length > 0)
|
|
257
|
+
return [...metaCap];
|
|
258
|
+
return mintCap ? mintCap(approvalDenom) : [];
|
|
259
|
+
}
|
|
260
|
+
/** Two payout ceilings as the chain sees them: same denoms and amounts, order irrelevant. */
|
|
261
|
+
export function sameCap(a, b) {
|
|
262
|
+
if (a.length !== b.length)
|
|
263
|
+
return false;
|
|
264
|
+
const key = (coins) => coins
|
|
265
|
+
.map((c) => `${c.denom}:${c.amount}`)
|
|
266
|
+
.sort()
|
|
267
|
+
.join("|");
|
|
268
|
+
return key(a) === key(b);
|
|
269
|
+
}
|
|
270
|
+
/** The live constraints naming `collectionId` on the grants `admin` gave this oracle. */
|
|
271
|
+
function liveConstraints(chain, admin, collectionId) {
|
|
272
|
+
const { grants, sdk, now } = chain;
|
|
273
|
+
const out = [];
|
|
274
|
+
for (const grant of grants) {
|
|
275
|
+
if (grant.granter !== admin)
|
|
276
|
+
continue;
|
|
277
|
+
const authorization = grant.authorization;
|
|
278
|
+
if (!authorization || authorization.typeUrl !== EVALUATE_AUTHZ)
|
|
279
|
+
continue;
|
|
280
|
+
let decoded;
|
|
281
|
+
try {
|
|
282
|
+
decoded = sdk.ixo.claims.v1beta1.EvaluateClaimAuthorization.decode(authorization.value);
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
if (!isLive(timestampToDate(sdk, grant.expiration), now))
|
|
288
|
+
continue;
|
|
289
|
+
for (const c of decoded.constraints) {
|
|
290
|
+
if (c.collectionId !== collectionId)
|
|
291
|
+
continue;
|
|
292
|
+
if (!isLive(timestampToDate(sdk, c.beforeDate), now))
|
|
293
|
+
continue;
|
|
294
|
+
out.push(c);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return out;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Does this oracle already hold a live authorization for `collectionId` on the poster's CURRENT
|
|
301
|
+
* terms (the ceiling `capForMint` would write today)? A poster who raises their ceiling later
|
|
302
|
+
* leaves an authorization that cannot pay what is named; answering false re-mints beside it — the
|
|
303
|
+
* chain APPENDS constraints and `Accept` passes over one whose cap cannot cover the amount.
|
|
304
|
+
*/
|
|
305
|
+
export function holdsMatchingEvaluateGrant(chain, args) {
|
|
306
|
+
const expected = capForMint(args.metaCap, args.approvalDenom, args.mintCap);
|
|
307
|
+
return liveConstraints(chain, args.admin, args.collectionId).some((c) => sameCap(c.maxCustomAmount, expected));
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* How many more verdicts this oracle can sign on `collectionId`: the `agentQuota` of every live
|
|
311
|
+
* constraint naming it, summed — how the chain spends it (`Accept` decrements the first covering
|
|
312
|
+
* constraint). A quota that will not read counts as nothing: under-counting costs one early top-up.
|
|
313
|
+
*/
|
|
314
|
+
export function remainingEvaluateQuota(chain, args) {
|
|
315
|
+
let remaining = 0;
|
|
316
|
+
for (const c of liveConstraints(chain, args.admin, args.collectionId)) {
|
|
317
|
+
const quota = toNumber(c.agentQuota);
|
|
318
|
+
if (Number.isFinite(quota) && quota > 0)
|
|
319
|
+
remaining += quota;
|
|
320
|
+
}
|
|
321
|
+
return remaining;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Should a collection holding `remaining` verdicts get another mint of `mintQuota`? Below
|
|
325
|
+
* `TOPUP_BELOW`, or below one mint when the poster's cap is smaller — which keeps it idempotent:
|
|
326
|
+
* after a mint `remaining >= mintQuota`, so a retried step re-reads the chain and stops.
|
|
327
|
+
*/
|
|
328
|
+
export function needsTopUp(remaining, mintQuota) {
|
|
329
|
+
if (!Number.isFinite(mintQuota) || mintQuota < 1)
|
|
330
|
+
return false;
|
|
331
|
+
return remaining < Math.min(TOPUP_BELOW, mintQuota);
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* The `MsgExec`-wrapped `MsgCreateClaimAuthorization` this oracle signs to hand ITSELF the
|
|
335
|
+
* collection's evaluate right, under the poster's meta-grant. `maxAmount` is `capForMint`'s.
|
|
336
|
+
*/
|
|
337
|
+
export function mintEvaluateAuthzMsg(sdk, args) {
|
|
338
|
+
const { ixo, cosmos, utils } = sdk;
|
|
339
|
+
const authorize = ixo.claims.v1beta1.MsgCreateClaimAuthorization.encode(ixo.claims.v1beta1.MsgCreateClaimAuthorization.fromPartial({
|
|
340
|
+
creatorAddress: args.oracleAddress,
|
|
341
|
+
creatorDid: args.oracleDid,
|
|
342
|
+
granteeAddress: args.oracleAddress,
|
|
343
|
+
adminAddress: args.admin,
|
|
344
|
+
collectionId: args.collectionId,
|
|
345
|
+
authType: AUTH_EVALUATE,
|
|
346
|
+
agentQuota: utils.proto.numberToLong(args.agentQuota),
|
|
347
|
+
beforeDate: utils.proto.toTimestamp(args.beforeDate),
|
|
348
|
+
maxAmount: args.maxAmount,
|
|
349
|
+
...(args.memberAddress ? { memberAddress: args.memberAddress } : {}),
|
|
350
|
+
})).finish();
|
|
351
|
+
return {
|
|
352
|
+
typeUrl: "/cosmos.authz.v1beta1.MsgExec",
|
|
353
|
+
value: cosmos.authz.v1beta1.MsgExec.fromPartial({
|
|
354
|
+
grantee: args.oracleAddress,
|
|
355
|
+
msgs: [{ typeUrl: META_MSG_TYPE, value: authorize }],
|
|
356
|
+
}),
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* How long the minted authorization may live: never past the poster's meta-grant, never past the
|
|
361
|
+
* ask's end plus the judging grace (a year for an ask with no end). Must be in the future.
|
|
362
|
+
*/
|
|
363
|
+
export function beforeDateFor(meta, endDate, now) {
|
|
364
|
+
const ends = endDate ? Date.parse(endDate) : Number.NaN;
|
|
365
|
+
const horizon = Number.isFinite(ends) ? ends + JUDGE_GRACE_MS : now.getTime() + 365 * DAY_MS;
|
|
366
|
+
const capped = Math.min(meta.expiration?.getTime() ?? Number.POSITIVE_INFINITY, horizon);
|
|
367
|
+
if (!(capped > now.getTime())) {
|
|
368
|
+
throw new Error(`nothing left to authorize: meta-grant expires ${meta.expiration?.toISOString() ?? "never"}, ask ends ${endDate ?? "never"}`);
|
|
369
|
+
}
|
|
370
|
+
return new Date(capped);
|
|
371
|
+
}
|
|
372
|
+
/** The denom of a collection's first approval coin (its on-chain `payments`), or null. */
|
|
373
|
+
export function approvalDenomOf(payments) {
|
|
374
|
+
const approval = payments?.approval;
|
|
375
|
+
const first = Array.isArray(approval?.amount)
|
|
376
|
+
? approval.amount[0]
|
|
377
|
+
: null;
|
|
378
|
+
return typeof first?.denom === "string" && first.denom ? first.denom : null;
|
|
379
|
+
}
|
|
380
|
+
/** An ask that ended may still be judged for `JUDGE_GRACE_DAYS`; an unreadable end is no end. */
|
|
381
|
+
export function isJudgeable(endDate, now) {
|
|
382
|
+
if (!endDate)
|
|
383
|
+
return true;
|
|
384
|
+
const ends = Date.parse(endDate);
|
|
385
|
+
return !Number.isFinite(ends) || ends + JUDGE_GRACE_MS > now.getTime();
|
|
386
|
+
}
|
|
387
|
+
/** End plus grace as an ISO stamp (`openhands_hires.ends_at`), or null for no readable end. */
|
|
388
|
+
export function endsAtOf(endDate) {
|
|
389
|
+
const ends = endDate ? Date.parse(endDate) : Number.NaN;
|
|
390
|
+
return Number.isFinite(ends) ? new Date(ends + JUDGE_GRACE_MS).toISOString() : null;
|
|
391
|
+
}
|
|
392
|
+
//# sourceMappingURL=chain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chain.js","sourceRoot":"","sources":["../../../src/lib/openhands/chain.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The provider's `openhands` options (oracle.ts `OpenhandsOptions`), read through the registry like
|
|
3
|
+
* every other part of the config — and the one fail-soft way their `onQuota` hook is called.
|
|
4
|
+
*/
|
|
5
|
+
import type { OracleEnv } from "../../env.js";
|
|
6
|
+
import { type OpenhandsOptions, type OpenhandsQuota } from "../../oracle.js";
|
|
7
|
+
import type { Logger } from "../logger.js";
|
|
8
|
+
/** Is this oracle an OpenHands checker (`openhands` present in `defineOracle`)? */
|
|
9
|
+
export declare function openhandsEnabled(): boolean;
|
|
10
|
+
export declare function openhandsOptions(): OpenhandsOptions;
|
|
11
|
+
/** Tell the provider's `onQuota` what was just read. A throw there never fails the hire or the pass. */
|
|
12
|
+
export declare function reportQuota(env: OracleEnv, logger: Logger, quota: OpenhandsQuota): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=options.d.ts.map
|