@dopamint-fun/open-sdk 0.2.0-dev.1 → 0.2.0-dev.11
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 +3 -3
- package/dist/agentHttp.js +12 -15
- package/dist/bytes.d.ts +9 -0
- package/dist/bytes.js +18 -1
- package/dist/claim.js +38 -22
- package/dist/cli.js +53 -54
- package/dist/identity.d.ts +1 -1
- package/dist/identity.js +20 -40
- package/dist/index.d.ts +4 -4
- package/dist/index.js +5 -5
- package/dist/offer.js +3 -3
- package/dist/openTournament.d.ts +22 -0
- package/dist/openTournament.js +34 -3
- package/dist/refusal.d.ts +5 -0
- package/dist/refusal.js +21 -0
- package/dist/room.js +2 -2
- package/dist/seatState.d.ts +1 -0
- package/dist/seatState.js +6 -0
- package/dist/seatTurn.js +1 -1
- package/dist/session.d.ts +12 -0
- package/dist/session.js +63 -9
- package/dist/sessionCodec.d.ts +4 -0
- package/dist/sessionCodec.js +18 -3
- package/dist/sessionWire.js +1 -1
- package/dist/settlement.d.ts +5 -1
- package/dist/settlement.js +6 -7
- package/dist/tour.js +4 -4
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -3,9 +3,9 @@ export { deriveAgentId, registerCanonicalPayload, registerPayloadDigest, type Re
|
|
|
3
3
|
export { canonicalIdentityPayload, nameAgent, parseIdentityFields, type AgentIdentityFields, type NameAgentArgs, } from "./identity.js";
|
|
4
4
|
export { actionSigningBytes, encodeActionFrame, encodeJoinFrame, encodeResumeFrame, joinSigningBytes, resumeSigningBytes, SESSION_VERSION, UnsupportedSessionVersionError, type ActionProposal, type ArtifactReference, type JoinRequest, type ResumeRequest, type SessionContext, } from "./sessionWire.js";
|
|
5
5
|
export { encodeAckFrame, SESSION_ERROR_NAMES, MAX_PREDICTION_PACING_MS, admitAuthorityEvent, applyPredictionGateStatus, decodeAuthorityMessage, freshSessionBoundary, predictionGateMessage, predictionGatePreparationOf, predictionGateTargetReceipt, sessionErrorHint, sessionErrorName, PredictionGateConflictError, SessionBoundaryError, type AcceptedSessionBoundary, type AuthorityMessage, type PredictionGateMessage, type PredictionGateOpening, type PredictionGatePreparation, type PredictionGateRelease, type PredictionGateStatus, type PredictionWindowRef, type ReceiptRef, type ResumeCursor, type StateRef, type ViewSnapshot, } from "./sessionCodec.js";
|
|
6
|
-
export { type OpenTableView, type PlayReport, type SeatDecision, type SeatDecisionResult, type SeatPosition, SessionClient, SessionRefusal, chooseSeatAction, playSeat, } from "./session.js";
|
|
6
|
+
export { type OpenTableView, type PlayReport, type SeatDecision, type SeatDecisionResult, type SeatPosition, SessionClient, SessionRefusal, chooseSeatAction, playSeat, waitForReadyOwner, } from "./session.js";
|
|
7
7
|
export { cardFromByte, decodeLegalActions, decodeParticipantView, encodeAction, pickAction, type Card, type Rank, type Suit, type TexasAction, type TexasLegalActions, type TexasSeatView, } from "./texas.js";
|
|
8
|
-
export {
|
|
8
|
+
export { buildConsentRequest, DEFAULT_OPEN_API_BASE_URL, digestForPrompt, recomputeSettlementDigest, settlementConsentPath, verifyConsentDisclosure, } from "./settlement.js";
|
|
9
9
|
export { PACKAGE_NAME, RELEASE_CHANNELS, channelDistTag, installCommand, installSpec, resolveChannel, versionMatchesChannel, type ReleaseChannel, } from "./channel.js";
|
|
10
10
|
export { fromHex, toHex } from "./bytes.js";
|
|
11
11
|
export { AGENT_HTTP_CAPABILITY_HEADER, AGENT_HTTP_CAPABILITY_NONCE_BYTES, MAX_AGENT_HTTP_CAPABILITY_WINDOW_MS, agentHttpCanonicalPayload, agentHttpSigningBytes, decodeAgentHttpHeader, encodeAgentHttpHeader, mintAgentHttpCapability, type AgentHttpBinding, type AgentHttpCapability, } from "./agentHttp.js";
|
|
@@ -17,5 +17,5 @@ export { handEquity, requiredEquity, cardCode, type HandEquity, type HandEquityO
|
|
|
17
17
|
export { cardIndex, handCategory, scoreHand, HAND_CATEGORIES, RANK_ORDER, SUIT_ORDER, type BestFive, type HandCategory, } from "./handRank.js";
|
|
18
18
|
export { DEFAULT_SEAT_STATE_FILE, loadSeatState, saveSeatState, type SeatSessionState, } from "./seatState.js";
|
|
19
19
|
export { newSeatState, openTurn, submitTurn, type SeatStateCheckpoint, type SeatTurnOutcome, type SeatTurnPosition, } from "./seatTurn.js";
|
|
20
|
-
export { chipAddressOf, joinTransaction, leaveTransaction, listTournaments, planJoin, presentToTournament, readAgentEntry, readPass, readOwner, playsHeldBy, giveBackTransaction, readTournament, sponsorAndExecute, tournamentIdArg, tournamentPossessionSignature, JoinRefused, TournamentRefusal, TOURNAMENT_POSSESSION_SEAT, type JoinPlan, type SponsoredExecution, type TournamentAgentEntry, type TournamentPass, type TournamentPlay, type TournamentOwnerView, type TournamentOwnerAgent, type TournamentChainObjects, type TournamentClient, type TournamentOverview, type TournamentQueueEntry, } from "./openTournament.js";
|
|
21
|
-
export { ClientRefusal, describeNext, refusalLines, refusalMessage, refusalMessageFromText, type RefusalBody, type RefusalNext, } from "./refusal.js";
|
|
20
|
+
export { chipAddressOf, joinTransaction, leaveTransaction, listTournaments, planJoin, presentToTournament, readAgentEntry, readAgentEntrySettled, BOOK_CATCHES_UP_MS, readPass, readOwner, playsHeldBy, giveBackTransaction, readTournament, sponsorAndExecute, tournamentIdArg, tournamentPossessionSignature, JoinRefused, TournamentRefusal, TOURNAMENT_POSSESSION_SEAT, type JoinPlan, type SponsoredExecution, type TournamentAgentEntry, type TournamentPass, type TournamentPlay, type TournamentOwnerView, type TournamentOwnerAgent, type TournamentChainObjects, type TournamentClient, type TournamentOverview, type TournamentQueueEntry, } from "./openTournament.js";
|
|
21
|
+
export { ClientRefusal, describeNext, ownershipFencePoll, ownershipFenced, refusalLines, refusalMessage, refusalMessageFromText, type RefusalBody, type RefusalNext, } from "./refusal.js";
|
package/dist/index.js
CHANGED
|
@@ -3,16 +3,16 @@
|
|
|
3
3
|
* Generate and hold an ed25519 keypair (Sui format, `.dopa-keypair`), produce
|
|
4
4
|
* the canonical signatures, and drive the Participant Session against
|
|
5
5
|
* `session_base_url`. Byte parity with the Rust client is pinned by
|
|
6
|
-
* `libs/dopa-open
|
|
6
|
+
* `libs/dopa-open/client-rs/vectors/ts-signer-parity.json`.
|
|
7
7
|
*/
|
|
8
8
|
export { DEFAULT_KEY_FILE, generateKeypair, keypairFromSeed, loadKeypair, saveKeypair, signOwnerAuthenticator, signRaw, } from "./keypair.js";
|
|
9
9
|
export { deriveAgentId, registerCanonicalPayload, registerPayloadDigest, } from "./registration.js";
|
|
10
10
|
export { canonicalIdentityPayload, nameAgent, parseIdentityFields, } from "./identity.js";
|
|
11
11
|
export { actionSigningBytes, encodeActionFrame, encodeJoinFrame, encodeResumeFrame, joinSigningBytes, resumeSigningBytes, SESSION_VERSION, UnsupportedSessionVersionError, } from "./sessionWire.js";
|
|
12
12
|
export { encodeAckFrame, SESSION_ERROR_NAMES, MAX_PREDICTION_PACING_MS, admitAuthorityEvent, applyPredictionGateStatus, decodeAuthorityMessage, freshSessionBoundary, predictionGateMessage, predictionGatePreparationOf, predictionGateTargetReceipt, sessionErrorHint, sessionErrorName, PredictionGateConflictError, SessionBoundaryError, } from "./sessionCodec.js";
|
|
13
|
-
export { SessionClient, SessionRefusal, chooseSeatAction, playSeat, } from "./session.js";
|
|
13
|
+
export { SessionClient, SessionRefusal, chooseSeatAction, playSeat, waitForReadyOwner, } from "./session.js";
|
|
14
14
|
export { cardFromByte, decodeLegalActions, decodeParticipantView, encodeAction, pickAction, } from "./texas.js";
|
|
15
|
-
export {
|
|
15
|
+
export { buildConsentRequest, DEFAULT_OPEN_API_BASE_URL, digestForPrompt, recomputeSettlementDigest, settlementConsentPath, verifyConsentDisclosure, } from "./settlement.js";
|
|
16
16
|
export { PACKAGE_NAME, RELEASE_CHANNELS, channelDistTag, installCommand, installSpec, resolveChannel, versionMatchesChannel, } from "./channel.js";
|
|
17
17
|
export { fromHex, toHex } from "./bytes.js";
|
|
18
18
|
export { AGENT_HTTP_CAPABILITY_HEADER, AGENT_HTTP_CAPABILITY_NONCE_BYTES, MAX_AGENT_HTTP_CAPABILITY_WINDOW_MS, agentHttpCanonicalPayload, agentHttpSigningBytes, decodeAgentHttpHeader, encodeAgentHttpHeader, mintAgentHttpCapability, } from "./agentHttp.js";
|
|
@@ -29,5 +29,5 @@ export { handEquity, requiredEquity, cardCode, } from "./equity.js";
|
|
|
29
29
|
export { cardIndex, handCategory, scoreHand, HAND_CATEGORIES, RANK_ORDER, SUIT_ORDER, } from "./handRank.js";
|
|
30
30
|
export { DEFAULT_SEAT_STATE_FILE, loadSeatState, saveSeatState, } from "./seatState.js";
|
|
31
31
|
export { newSeatState, openTurn, submitTurn, } from "./seatTurn.js";
|
|
32
|
-
export { chipAddressOf, joinTransaction, leaveTransaction, listTournaments, planJoin, presentToTournament, readAgentEntry, readPass, readOwner, playsHeldBy, giveBackTransaction, readTournament, sponsorAndExecute, tournamentIdArg, tournamentPossessionSignature, JoinRefused, TournamentRefusal, TOURNAMENT_POSSESSION_SEAT, } from "./openTournament.js";
|
|
33
|
-
export { ClientRefusal, describeNext, refusalLines, refusalMessage, refusalMessageFromText, } from "./refusal.js";
|
|
32
|
+
export { chipAddressOf, joinTransaction, leaveTransaction, listTournaments, planJoin, presentToTournament, readAgentEntry, readAgentEntrySettled, BOOK_CATCHES_UP_MS, readPass, readOwner, playsHeldBy, giveBackTransaction, readTournament, sponsorAndExecute, tournamentIdArg, tournamentPossessionSignature, JoinRefused, TournamentRefusal, TOURNAMENT_POSSESSION_SEAT, } from "./openTournament.js";
|
|
33
|
+
export { ClientRefusal, describeNext, ownershipFencePoll, ownershipFenced, refusalLines, refusalMessage, refusalMessageFromText, } from "./refusal.js";
|
package/dist/offer.js
CHANGED
|
@@ -52,7 +52,7 @@ function record(raw) {
|
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
54
|
export async function readOffer(productUrl, offerId) {
|
|
55
|
-
const { status, json } = await readJson(`${productUrl.replace(/\/$/, "")}/
|
|
55
|
+
const { status, json } = await readJson(`${productUrl.replace(/\/$/, "")}/v1/playground/matches/${offerId}`);
|
|
56
56
|
if (status !== 200)
|
|
57
57
|
throw new Error(refusalMessage("offer read", status, json));
|
|
58
58
|
return record(json);
|
|
@@ -81,7 +81,7 @@ export async function acceptOffer(productUrl, offerId, seat, agent) {
|
|
|
81
81
|
signature: Array.from(signed.signature),
|
|
82
82
|
seat_possession_signature: Array.from(signed.seatPossessionSignature),
|
|
83
83
|
});
|
|
84
|
-
const { status, json } = await readJson(`${productUrl.replace(/\/$/, "")}/
|
|
84
|
+
const { status, json } = await readJson(`${productUrl.replace(/\/$/, "")}/v1/playground/matches/${offerId}/acceptances`, { method: "POST", headers: { "content-type": "application/json" }, body });
|
|
85
85
|
if (status === 200 || status === 201)
|
|
86
86
|
return;
|
|
87
87
|
if (status === 409)
|
|
@@ -89,7 +89,7 @@ export async function acceptOffer(productUrl, offerId, seat, agent) {
|
|
|
89
89
|
throw new Error(refusalMessage("acceptance", status, json));
|
|
90
90
|
}
|
|
91
91
|
async function admit(productUrl, offerId, agentId, agent) {
|
|
92
|
-
const target = `/
|
|
92
|
+
const target = `/v1/playground/matches/${offerId}/admit`;
|
|
93
93
|
const { header } = await mintAgentHttpCapability(agent, agentId, {
|
|
94
94
|
method: "POST",
|
|
95
95
|
requestTarget: target,
|
package/dist/openTournament.d.ts
CHANGED
|
@@ -143,6 +143,28 @@ export declare function readTournamentMatches(productUrl: string, tournamentId:
|
|
|
143
143
|
export declare function disputeHolding(productUrl: string, tournamentId: string, chipAddress: string, fetchImpl?: typeof fetch): Promise<number | undefined>;
|
|
144
144
|
/** The agent's entry in the chip book, or `null` before its first redeem. */
|
|
145
145
|
export declare function readAgentEntry(productUrl: string, tournamentId: string, chipAddress: string, fetchImpl?: typeof fetch): Promise<TournamentAgentEntry | null>;
|
|
146
|
+
/** How long a book read waits for a join that has just landed.
|
|
147
|
+
*
|
|
148
|
+
* The book is the chain's, read a checkpoint behind it: an agent whose
|
|
149
|
+
* `queue_join` succeeded a moment ago is on chain and not yet in the book.
|
|
150
|
+
* Measured at about a second on a local stack; this is generous enough to
|
|
151
|
+
* cover a slower one and short enough that an agent that really is absent is
|
|
152
|
+
* told so rather than left waiting. */
|
|
153
|
+
export declare const BOOK_CATCHES_UP_MS = 8000;
|
|
154
|
+
/** The agent's entry, waited for while the book catches up with the chain.
|
|
155
|
+
*
|
|
156
|
+
* For a caller that has just been told its join landed. A plain
|
|
157
|
+
* `readAgentEntry` answering `null` in that window is not "this agent never
|
|
158
|
+
* queued" — it is "the book has not seen the queue join yet", and the two are
|
|
159
|
+
* worth telling apart before refusing somebody. Absent for the whole bound is
|
|
160
|
+
* the first answer, and this returns `null` for it. */
|
|
161
|
+
export declare function readAgentEntrySettled(productUrl: string, tournamentId: string, chipAddress: string, options?: {
|
|
162
|
+
boundMs?: number;
|
|
163
|
+
pollMs?: number;
|
|
164
|
+
fetchImpl?: typeof fetch;
|
|
165
|
+
sleep?: (ms: number) => Promise<void>;
|
|
166
|
+
now?: () => number;
|
|
167
|
+
}): Promise<TournamentAgentEntry | null>;
|
|
146
168
|
/** An owner's pass, or `null` when the owner has claimed none. */
|
|
147
169
|
export declare function readPass(productUrl: string, tournamentId: string, owner: string, fetchImpl?: typeof fetch): Promise<TournamentPass | null>;
|
|
148
170
|
/** An owner's side: its pass and every agent it has claimed, each with the
|
package/dist/openTournament.js
CHANGED
|
@@ -26,7 +26,7 @@ function base(productUrl) {
|
|
|
26
26
|
return productUrl.replace(/\/$/, "");
|
|
27
27
|
}
|
|
28
28
|
function tournamentPath(tournamentId, rest = "") {
|
|
29
|
-
return `/
|
|
29
|
+
return `/v1/tournaments/${tournamentId}${rest}`;
|
|
30
30
|
}
|
|
31
31
|
async function readJson(fetchImpl, url) {
|
|
32
32
|
const response = await fetchImpl(url);
|
|
@@ -57,7 +57,7 @@ export async function readTournament(productUrl, tournamentId, fetchImpl = fetch
|
|
|
57
57
|
}
|
|
58
58
|
/** The open-entry tournaments the product runs. */
|
|
59
59
|
export async function listTournaments(productUrl, fetchImpl = fetch) {
|
|
60
|
-
const { status, json } = await readJson(fetchImpl, `${base(productUrl)}/
|
|
60
|
+
const { status, json } = await readJson(fetchImpl, `${base(productUrl)}/v1/tournaments`);
|
|
61
61
|
if (status === 404)
|
|
62
62
|
return [];
|
|
63
63
|
if (status !== 200)
|
|
@@ -100,6 +100,37 @@ export async function readAgentEntry(productUrl, tournamentId, chipAddress, fetc
|
|
|
100
100
|
throw new TournamentRefusal(status, json, "chip book read");
|
|
101
101
|
return json;
|
|
102
102
|
}
|
|
103
|
+
/** How long a book read waits for a join that has just landed.
|
|
104
|
+
*
|
|
105
|
+
* The book is the chain's, read a checkpoint behind it: an agent whose
|
|
106
|
+
* `queue_join` succeeded a moment ago is on chain and not yet in the book.
|
|
107
|
+
* Measured at about a second on a local stack; this is generous enough to
|
|
108
|
+
* cover a slower one and short enough that an agent that really is absent is
|
|
109
|
+
* told so rather than left waiting. */
|
|
110
|
+
export const BOOK_CATCHES_UP_MS = 8_000;
|
|
111
|
+
/** The agent's entry, waited for while the book catches up with the chain.
|
|
112
|
+
*
|
|
113
|
+
* For a caller that has just been told its join landed. A plain
|
|
114
|
+
* `readAgentEntry` answering `null` in that window is not "this agent never
|
|
115
|
+
* queued" — it is "the book has not seen the queue join yet", and the two are
|
|
116
|
+
* worth telling apart before refusing somebody. Absent for the whole bound is
|
|
117
|
+
* the first answer, and this returns `null` for it. */
|
|
118
|
+
export async function readAgentEntrySettled(productUrl, tournamentId, chipAddress, options = {}) {
|
|
119
|
+
const boundMs = options.boundMs ?? BOOK_CATCHES_UP_MS;
|
|
120
|
+
const pollMs = options.pollMs ?? 1_000;
|
|
121
|
+
const now = options.now ?? Date.now;
|
|
122
|
+
const sleep = options.sleep ??
|
|
123
|
+
((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
124
|
+
const deadline = now() + boundMs;
|
|
125
|
+
for (;;) {
|
|
126
|
+
const entry = await readAgentEntry(productUrl, tournamentId, chipAddress, options.fetchImpl ?? fetch);
|
|
127
|
+
if (entry)
|
|
128
|
+
return entry;
|
|
129
|
+
if (now() >= deadline)
|
|
130
|
+
return null;
|
|
131
|
+
await sleep(pollMs);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
103
134
|
/** An owner's pass, or `null` when the owner has claimed none. */
|
|
104
135
|
export async function readPass(productUrl, tournamentId, owner, fetchImpl = fetch) {
|
|
105
136
|
const { status, json } = await readJson(fetchImpl, `${base(productUrl)}${tournamentPath(tournamentId, `/passes/${owner}`)}`);
|
|
@@ -178,7 +209,7 @@ plays, owner) {
|
|
|
178
209
|
if (entry && entry.state !== "idle")
|
|
179
210
|
throw new JoinRefused(`this agent is already ${entry.state}${entry.state === "seated" ? " at a table" : ""}; an agent plays one table at a time`, {
|
|
180
211
|
action: "wait",
|
|
181
|
-
poll: `/
|
|
212
|
+
poll: `/v1/tournaments/${overview.tournamentId}/agents/${entry.chipAddress}`,
|
|
182
213
|
});
|
|
183
214
|
const booked = entry?.balance ?? 0;
|
|
184
215
|
const wallet = entry?.walletBalance ?? booked;
|
package/dist/refusal.d.ts
CHANGED
|
@@ -29,6 +29,11 @@ export interface RefusalBody {
|
|
|
29
29
|
docs?: string;
|
|
30
30
|
}
|
|
31
31
|
/** `next …`, as one line an agent can act on. */
|
|
32
|
+
/** True when a refusal body says the writer is fenced and the caller should
|
|
33
|
+
* poll committed ownership rather than resend to the same origin. */
|
|
34
|
+
export declare function ownershipFenced(body: unknown): boolean;
|
|
35
|
+
/** The product route a fenced seat polls, when the refusal named one. */
|
|
36
|
+
export declare function ownershipFencePoll(body: unknown): string | undefined;
|
|
32
37
|
export declare function describeNext(next: RefusalNext): string;
|
|
33
38
|
/** The lines a refusal prints: its code, what it said, the move, the entry. */
|
|
34
39
|
export declare function refusalLines(body: unknown): string[];
|
package/dist/refusal.js
CHANGED
|
@@ -6,6 +6,27 @@
|
|
|
6
6
|
* reading a refused command's output reads its move off the same lines rather
|
|
7
7
|
* than off a table in a skill document. */
|
|
8
8
|
/** `next …`, as one line an agent can act on. */
|
|
9
|
+
/** True when a refusal body says the writer is fenced and the caller should
|
|
10
|
+
* poll committed ownership rather than resend to the same origin. */
|
|
11
|
+
export function ownershipFenced(body) {
|
|
12
|
+
if (typeof body !== "object" || body === null)
|
|
13
|
+
return false;
|
|
14
|
+
const refusal = body;
|
|
15
|
+
if (refusal.code !== "ownership_fenced")
|
|
16
|
+
return false;
|
|
17
|
+
return (isNext(refusal.next) &&
|
|
18
|
+
refusal.next.action === "wait" &&
|
|
19
|
+
typeof refusal.next.poll === "string");
|
|
20
|
+
}
|
|
21
|
+
/** The product route a fenced seat polls, when the refusal named one. */
|
|
22
|
+
export function ownershipFencePoll(body) {
|
|
23
|
+
if (!ownershipFenced(body))
|
|
24
|
+
return undefined;
|
|
25
|
+
const next = body.next;
|
|
26
|
+
if (next && next.action === "wait")
|
|
27
|
+
return next.poll;
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
9
30
|
export function describeNext(next) {
|
|
10
31
|
switch (next.action) {
|
|
11
32
|
case "retry":
|
package/dist/room.js
CHANGED
|
@@ -57,7 +57,7 @@ export async function openRoom(client, seatCount) {
|
|
|
57
57
|
seatCount < MIN_ROOM_SEATS ||
|
|
58
58
|
seatCount > MAX_ROOM_SEATS)
|
|
59
59
|
throw new Error(`a private room seats ${MIN_ROOM_SEATS} to ${MAX_ROOM_SEATS}, not ${seatCount}`);
|
|
60
|
-
const { status, json } = await signedFetch(client, "POST", "/
|
|
60
|
+
const { status, json } = await signedFetch(client, "POST", "/v1/tables/private-rooms", { seatCount });
|
|
61
61
|
if (status !== 201) {
|
|
62
62
|
if (json?.code === "agent_not_claimed")
|
|
63
63
|
throw notClaimed();
|
|
@@ -95,7 +95,7 @@ export class RoomJoinRefusal extends Error {
|
|
|
95
95
|
}
|
|
96
96
|
/** Join a room by the id its opener handed out. */
|
|
97
97
|
export async function joinRoom(client, tableId) {
|
|
98
|
-
const target = `/
|
|
98
|
+
const target = `/v1/tables/private-rooms/${tableId}/join`;
|
|
99
99
|
const { status, json } = await signedFetch(client, "POST", target);
|
|
100
100
|
if (status !== 201) {
|
|
101
101
|
if (json?.code === "agent_not_claimed")
|
package/dist/seatState.d.ts
CHANGED
package/dist/seatState.js
CHANGED
|
@@ -175,6 +175,9 @@ export function encodeGate(gate) {
|
|
|
175
175
|
arrivalMs: gate.release.arrivalMs.toString(),
|
|
176
176
|
lockedAtMs: gate.release.lockedAtMs.toString(),
|
|
177
177
|
budgetMs: gate.release.budgetMs.toString(),
|
|
178
|
+
terminalDigest: gate.release.terminalDigest
|
|
179
|
+
? toHex0x(gate.release.terminalDigest)
|
|
180
|
+
: null,
|
|
178
181
|
},
|
|
179
182
|
};
|
|
180
183
|
}
|
|
@@ -208,6 +211,9 @@ export function decodeGate(stored) {
|
|
|
208
211
|
arrivalMs: BigInt(stored.release.arrivalMs),
|
|
209
212
|
lockedAtMs: BigInt(stored.release.lockedAtMs),
|
|
210
213
|
budgetMs: BigInt(stored.release.budgetMs),
|
|
214
|
+
terminalDigest: stored.release.terminalDigest
|
|
215
|
+
? fromHex(stored.release.terminalDigest)
|
|
216
|
+
: null,
|
|
211
217
|
}),
|
|
212
218
|
};
|
|
213
219
|
default:
|
package/dist/seatTurn.js
CHANGED
|
@@ -478,7 +478,7 @@ async function sayAtTable(fetchImpl, session, agent, agentId, say) {
|
|
|
478
478
|
if (!trimmed)
|
|
479
479
|
return false;
|
|
480
480
|
const { mintAgentHttpCapability, AGENT_HTTP_CAPABILITY_HEADER } = await import("./agentHttp.js");
|
|
481
|
-
const target = `/
|
|
481
|
+
const target = `/v1/executions/${session.executionHex}/talk`;
|
|
482
482
|
const body = new TextEncoder().encode(JSON.stringify({ say: trimmed }));
|
|
483
483
|
try {
|
|
484
484
|
const { header } = await mintAgentHttpCapability(agent, agentId, {
|
package/dist/session.d.ts
CHANGED
|
@@ -327,6 +327,18 @@ export interface RestartRetry {
|
|
|
327
327
|
* answer, 408, 429 or a 5xx -- until `bound` has passed. Any other answer is
|
|
328
328
|
* returned as it came, so a refusal stays the caller's to read. */
|
|
329
329
|
export declare function fetchWhileRestarting(fetchImpl: typeof fetch, url: string, retry?: RestartRetry): Promise<Response>;
|
|
330
|
+
/** Poll product until the committed owner is ready, then return its origin. */
|
|
331
|
+
export declare function waitForReadyOwner(args: {
|
|
332
|
+
productUrl: string;
|
|
333
|
+
executionId: string;
|
|
334
|
+
fetchImpl?: typeof fetch;
|
|
335
|
+
timeoutMs?: number;
|
|
336
|
+
pauseMs?: number;
|
|
337
|
+
sleep?: (ms: number) => Promise<void>;
|
|
338
|
+
}): Promise<{
|
|
339
|
+
sessionOrigin: string;
|
|
340
|
+
version: number;
|
|
341
|
+
}>;
|
|
330
342
|
export declare function openSeatSession(args: SeatSessionArgs): Promise<SeatSession>;
|
|
331
343
|
export declare function playSeat(args: PlayArgs): Promise<PlayReport>;
|
|
332
344
|
/** What the play loop does about a refusal, by the refusal's tag.
|
package/dist/session.js
CHANGED
|
@@ -7,6 +7,7 @@ import { MAX_TRANSPORT_FRAME_BYTES, PredictionGateConflictError, SessionBoundary
|
|
|
7
7
|
import { actionSigningBytes, encodeActionFrame, encodeJoinFrame, encodeResumeFrame, joinSigningBytes, requireSessionVersion, resumeSigningBytes, SESSION_VERSION, UnsupportedSessionVersionError, } from "./sessionWire.js";
|
|
8
8
|
import { decodeLegalActions, decodeParticipantView, encodeAction, pickAction, } from "./texas.js";
|
|
9
9
|
import { authorizeSeatChallenge } from "./seatAuth.js";
|
|
10
|
+
import { ownershipFenced } from "./refusal.js";
|
|
10
11
|
const ACTION_IDENTITY_DOMAIN = textBytes("dopa_open::client::action_identity_v1");
|
|
11
12
|
/** The lines a play door reports for one seat's sitting.
|
|
12
13
|
*
|
|
@@ -528,13 +529,50 @@ export async function fetchWhileRestarting(fetchImpl, url, retry = {
|
|
|
528
529
|
await sleep(retry.pauseMs);
|
|
529
530
|
}
|
|
530
531
|
}
|
|
532
|
+
/** Poll product until the committed owner is ready, then return its origin. */
|
|
533
|
+
export async function waitForReadyOwner(args) {
|
|
534
|
+
const fetchImpl = args.fetchImpl ?? fetch;
|
|
535
|
+
const sleep = args.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
536
|
+
const product = args.productUrl.replace(/\/$/, "");
|
|
537
|
+
const until = Date.now() + (args.timeoutMs ?? 30_000);
|
|
538
|
+
const pause = args.pauseMs ?? 200;
|
|
539
|
+
const id = args.executionId.replace(/^0x/i, "");
|
|
540
|
+
for (;;) {
|
|
541
|
+
const response = await fetchImpl(`${product}/v1/authority/executions/${id}/route`);
|
|
542
|
+
if (response.ok) {
|
|
543
|
+
const body = (await response.json());
|
|
544
|
+
if (body.ready && body.sessionOrigin)
|
|
545
|
+
return { sessionOrigin: body.sessionOrigin, version: body.version ?? 0 };
|
|
546
|
+
}
|
|
547
|
+
else {
|
|
548
|
+
await response.body?.cancel();
|
|
549
|
+
}
|
|
550
|
+
if (Date.now() + pause > until)
|
|
551
|
+
throw new Error("committed owner did not become ready");
|
|
552
|
+
await sleep(pause);
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
function httpFailure(error) {
|
|
556
|
+
if (!(error instanceof Error))
|
|
557
|
+
return null;
|
|
558
|
+
const match = /^[a-z-]+ failed \((\d+)\): (.*)$/is.exec(error.message);
|
|
559
|
+
if (!match)
|
|
560
|
+
return null;
|
|
561
|
+
const status = Number(match[1]);
|
|
562
|
+
try {
|
|
563
|
+
return { status, body: JSON.parse(match[2] ?? "") };
|
|
564
|
+
}
|
|
565
|
+
catch {
|
|
566
|
+
return { status, body: match[2] ?? "" };
|
|
567
|
+
}
|
|
568
|
+
}
|
|
531
569
|
export async function openSeatSession(args) {
|
|
532
570
|
const fetchImpl = args.fetchImpl ?? fetch;
|
|
533
571
|
const product = args.productUrl.replace(/\/$/, "");
|
|
534
572
|
/* Read again while the product is coming back: a seat reopens its session
|
|
535
573
|
after every dropped stream, and the product answering 502 for the seconds
|
|
536
574
|
it restarts ended the seat as surely as a refusal would have. */
|
|
537
|
-
const offer = await fetchWhileRestarting(fetchImpl, `${product}/
|
|
575
|
+
const offer = await fetchWhileRestarting(fetchImpl, `${product}/v1/playground/matches/${args.offerId}`, args.restartRetry);
|
|
538
576
|
if (!offer.ok)
|
|
539
577
|
throw new Error(`offer read failed (${offer.status}): ${await offer.text()}`);
|
|
540
578
|
const record = (await offer.json());
|
|
@@ -581,7 +619,7 @@ export async function openSeatSession(args) {
|
|
|
581
619
|
}
|
|
582
620
|
export async function playSeat(args) {
|
|
583
621
|
const fetchImpl = args.fetchImpl ?? fetch;
|
|
584
|
-
|
|
622
|
+
let { client, product, executionHex, coordinatorKey, timeAuthorityKey, executionId, } = await openSeatSession(args);
|
|
585
623
|
const record = {
|
|
586
624
|
admission: {
|
|
587
625
|
execution_id: executionId,
|
|
@@ -923,6 +961,22 @@ export async function playSeat(args) {
|
|
|
923
961
|
client joined this seat with this key; fighting it back would evict
|
|
924
962
|
a reconnect that may be the operator's own, so this one steps aside
|
|
925
963
|
and says so. Everything else is transient, and resume is right. */
|
|
964
|
+
const failed = httpFailure(error);
|
|
965
|
+
if (failed?.status === 409 && ownershipFenced(failed.body)) {
|
|
966
|
+
const ready = await waitForReadyOwner({
|
|
967
|
+
productUrl: product,
|
|
968
|
+
executionId: executionHex,
|
|
969
|
+
fetchImpl,
|
|
970
|
+
timeoutMs: 30_000,
|
|
971
|
+
pauseMs: 200,
|
|
972
|
+
});
|
|
973
|
+
client = new SessionClient(ready.sessionOrigin, args.agent, args.seat, args.agentId, client.executionId, client.executionManifestDigest, client.clientNonce, fetchImpl);
|
|
974
|
+
client.token = originToken;
|
|
975
|
+
await client.resume(lastContext, lastCursor);
|
|
976
|
+
originToken = client.token ?? originToken;
|
|
977
|
+
reconnects += 1;
|
|
978
|
+
continue;
|
|
979
|
+
}
|
|
926
980
|
const answer = afterRefusal(error);
|
|
927
981
|
if (answer === "step-aside")
|
|
928
982
|
return {
|
|
@@ -1004,7 +1058,7 @@ export function normaliseCardCode(code) {
|
|
|
1004
1058
|
export async function readDisclosedEntitlement(fetchImpl, product, executionId, seat, capability, options = {}) {
|
|
1005
1059
|
const attempts = options.attempts ?? 15;
|
|
1006
1060
|
const pauseMs = options.pauseMs ?? 1_000;
|
|
1007
|
-
const target = `/
|
|
1061
|
+
const target = `/v1/spectator/executions/${executionId}`;
|
|
1008
1062
|
for (let attempt = 0; attempt < attempts; attempt += 1) {
|
|
1009
1063
|
try {
|
|
1010
1064
|
const header = capability ? await capability("GET", target) : null;
|
|
@@ -1032,7 +1086,7 @@ export async function readDisclosedEntitlement(fetchImpl, product, executionId,
|
|
|
1032
1086
|
* gone -- which is precisely the moment this question is being asked. */
|
|
1033
1087
|
export async function readSittingStatus(fetchImpl, product, executionHex) {
|
|
1034
1088
|
try {
|
|
1035
|
-
const response = await fetchImpl(`${product}/
|
|
1089
|
+
const response = await fetchImpl(`${product}/v1/history/matches/${executionHex}`);
|
|
1036
1090
|
if (!response.ok)
|
|
1037
1091
|
return { state: "unknown" };
|
|
1038
1092
|
const wire = (await response.json());
|
|
@@ -1073,7 +1127,7 @@ export function agentReadCapability(agent, agentId) {
|
|
|
1073
1127
|
export async function readPublicTable(fetchImpl, product, executionHex, names = new Map(), capability) {
|
|
1074
1128
|
/* Bound to the target the server reconstructs from the request, which is the
|
|
1075
1129
|
origin-form path and not the absolute URL the fetch is given. */
|
|
1076
|
-
const target = `/
|
|
1130
|
+
const target = `/v1/spectator/executions/${executionHex}`;
|
|
1077
1131
|
try {
|
|
1078
1132
|
const header = capability ? await capability("GET", target) : null;
|
|
1079
1133
|
const response = await fetchImpl(`${product}${target}`, header === null
|
|
@@ -1134,14 +1188,14 @@ export async function readPublicTable(fetchImpl, product, executionHex, names =
|
|
|
1134
1188
|
return null;
|
|
1135
1189
|
}
|
|
1136
1190
|
}
|
|
1137
|
-
/** What an agent is called, from `GET /
|
|
1191
|
+
/** What an agent is called, from `GET /v1/agents/{id}/custody`, read
|
|
1138
1192
|
* once and remembered in `names`. Null where the read did not answer. */
|
|
1139
1193
|
async function readAgentNaming(fetchImpl, product, agentId, names) {
|
|
1140
1194
|
const known = names.get(agentId);
|
|
1141
1195
|
if (known !== undefined)
|
|
1142
1196
|
return known;
|
|
1143
1197
|
try {
|
|
1144
|
-
const response = await fetchImpl(`${product}/
|
|
1198
|
+
const response = await fetchImpl(`${product}/v1/agents/${agentId}/custody`);
|
|
1145
1199
|
if (!response.ok) {
|
|
1146
1200
|
names.set(agentId, null);
|
|
1147
1201
|
return null;
|
|
@@ -1164,7 +1218,7 @@ async function readAgentNaming(fetchImpl, product, agentId, names) {
|
|
|
1164
1218
|
* table: an empty list where the read did not answer. */
|
|
1165
1219
|
export async function readTableTalk(fetchImpl, product, executionHex, handIndex) {
|
|
1166
1220
|
try {
|
|
1167
|
-
const response = await fetchImpl(`${product}/
|
|
1221
|
+
const response = await fetchImpl(`${product}/v1/executions/${executionHex}/talk`);
|
|
1168
1222
|
if (!response.ok)
|
|
1169
1223
|
return [];
|
|
1170
1224
|
const wire = (await response.json());
|
|
@@ -1200,7 +1254,7 @@ function potChips(pot) {
|
|
|
1200
1254
|
/** File one line at the table, signed as this seat's agent. True when the
|
|
1201
1255
|
* product accepted it. */
|
|
1202
1256
|
async function sayAtTable(fetchImpl, product, executionHex, args, say) {
|
|
1203
|
-
const target = `/
|
|
1257
|
+
const target = `/v1/executions/${executionHex}/talk`;
|
|
1204
1258
|
const body = textBytes(JSON.stringify({ say }));
|
|
1205
1259
|
try {
|
|
1206
1260
|
const { header } = await mintAgentHttpCapability(args.agent, args.agentId, {
|
package/dist/sessionCodec.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export declare const SEAT_AUTHORIZATION_RESPONSE_TAG = 16;
|
|
|
13
13
|
export declare const PREDICTION_GATE_RELEASED_TAG = 17;
|
|
14
14
|
export declare const PREDICTION_GATE_PREPARED_TAG = 18;
|
|
15
15
|
export declare const PREDICTION_GATE_OPENED_TAG = 19;
|
|
16
|
+
export declare const PREDICTION_GATE_RELEASED_V4_TAG = 20;
|
|
16
17
|
export declare const MAX_TRANSPORT_FRAME_BYTES: number;
|
|
17
18
|
export interface WireEnvelope {
|
|
18
19
|
message: string;
|
|
@@ -104,6 +105,9 @@ export interface PredictionGateRelease {
|
|
|
104
105
|
lockCappedMs: bigint;
|
|
105
106
|
budgetMs: bigint;
|
|
106
107
|
participantDeadlineMs: bigint;
|
|
108
|
+
/** Digest of the protected LLM terminal decision, when bound. A release
|
|
109
|
+
* with none is the version-three notice; a bound one is version four. */
|
|
110
|
+
terminalDigest: Uint8Array | null;
|
|
107
111
|
}
|
|
108
112
|
/** The gate facts a participant retains for one revision. */
|
|
109
113
|
export type PredictionGateStatus = {
|
package/dist/sessionCodec.js
CHANGED
|
@@ -23,6 +23,12 @@ export const SEAT_AUTHORIZATION_RESPONSE_TAG = 0x10;
|
|
|
23
23
|
export const PREDICTION_GATE_RELEASED_TAG = 0x11;
|
|
24
24
|
export const PREDICTION_GATE_PREPARED_TAG = 0x12;
|
|
25
25
|
export const PREDICTION_GATE_OPENED_TAG = 0x13;
|
|
26
|
+
/* The released notice carries a version per terminal-digest binding: a
|
|
27
|
+
release with no protected-terminal digest is the byte-identical
|
|
28
|
+
version-three notice, and one bound to a digest is this notice with the
|
|
29
|
+
raw 32-byte digest after the overlay. `arena_session::wire` picks the
|
|
30
|
+
same tag from the same fact. */
|
|
31
|
+
export const PREDICTION_GATE_RELEASED_V4_TAG = 0x14;
|
|
26
32
|
export const MAX_TRANSPORT_FRAME_BYTES = 1 << 20;
|
|
27
33
|
export function encodeAckFrame(context, cursor) {
|
|
28
34
|
const sequence = typeof cursor === "object" ? cursor.sequence : cursor;
|
|
@@ -276,7 +282,11 @@ export function bindPredictionGateOpening(fields) {
|
|
|
276
282
|
throw new Error("prediction gate closes at or before it opened");
|
|
277
283
|
return fields;
|
|
278
284
|
}
|
|
279
|
-
|
|
285
|
+
/* `bound` is the notice version, not a field the sender may vary: the
|
|
286
|
+
version-three notice ends at the overlay and names no digest, and the
|
|
287
|
+
version-four notice ends with the raw digest and no option byte. Reading
|
|
288
|
+
an option here would read the cursor that follows. */
|
|
289
|
+
function readPredictionGateRelease(reader, bound) {
|
|
280
290
|
const window = readPredictionWindow(reader);
|
|
281
291
|
const actingSeat = reader.readU16("prediction gate acting seat");
|
|
282
292
|
const state = readState(reader, "prediction gate state nonce", "prediction gate state commitment");
|
|
@@ -288,6 +298,9 @@ function readPredictionGateRelease(reader) {
|
|
|
288
298
|
const arrivalMs = reader.readU64("prediction gate arrival milliseconds");
|
|
289
299
|
const lockedAtMs = reader.readU64("prediction gate locked-at milliseconds");
|
|
290
300
|
const budgetMs = reader.readU64("participant deadline budget milliseconds");
|
|
301
|
+
const terminalDigest = bound
|
|
302
|
+
? reader.readFixed(32, "prediction gate terminal digest")
|
|
303
|
+
: null;
|
|
291
304
|
return bindPredictionGateRelease({
|
|
292
305
|
window,
|
|
293
306
|
actingSeat,
|
|
@@ -298,6 +311,7 @@ function readPredictionGateRelease(reader) {
|
|
|
298
311
|
arrivalMs,
|
|
299
312
|
lockedAtMs,
|
|
300
313
|
budgetMs,
|
|
314
|
+
terminalDigest,
|
|
301
315
|
});
|
|
302
316
|
}
|
|
303
317
|
/** The structural refusals of `PredictionGateRelease::new`, with the bounded
|
|
@@ -566,8 +580,9 @@ export function decodeAuthorityMessage(bytes) {
|
|
|
566
580
|
};
|
|
567
581
|
break;
|
|
568
582
|
}
|
|
569
|
-
case PREDICTION_GATE_RELEASED_TAG:
|
|
570
|
-
|
|
583
|
+
case PREDICTION_GATE_RELEASED_TAG:
|
|
584
|
+
case PREDICTION_GATE_RELEASED_V4_TAG: {
|
|
585
|
+
const release = readPredictionGateRelease(reader, tag === PREDICTION_GATE_RELEASED_V4_TAG);
|
|
571
586
|
const cursor = readCursor(reader);
|
|
572
587
|
message = {
|
|
573
588
|
type: "predictionGateReleased",
|
package/dist/sessionWire.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Join, action, and resume signing bodies live here; acknowledgements are
|
|
5
5
|
* unsigned and encoded next to the authority decoder. The layouts are pinned
|
|
6
|
-
* by `libs/dopa-open
|
|
6
|
+
* by `libs/dopa-open/client-rs/vectors/ts-signer-parity.json`.
|
|
7
7
|
*/
|
|
8
8
|
import { ByteWriter, frameSigningBytes, textBytes } from "./bytes.js";
|
|
9
9
|
const JOIN_DOMAIN = textBytes("arena_session::join");
|
package/dist/settlement.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/** The Product API's deployed default origin. `dopa-open`'s `--product-url`
|
|
2
|
+
* (and `DOPA_OPEN_PRODUCT_URL`) default here, matching the Rust client and
|
|
3
|
+
* CLI's `DEFAULT_OPEN_API_BASE_URL`, so a caller only has to override it for
|
|
4
|
+
* a local stack or a non-default plane. */
|
|
5
|
+
export declare const DEFAULT_OPEN_API_BASE_URL = "https://open.dopamint.fun";
|
|
1
6
|
export interface SeatEntitlement {
|
|
2
7
|
seat: number;
|
|
3
8
|
amount: bigint;
|
|
@@ -52,5 +57,4 @@ export declare function buildConsentRequest(args: ConsentDisclosure & {
|
|
|
52
57
|
signature: Uint8Array;
|
|
53
58
|
}): ConsentRequest;
|
|
54
59
|
export declare function settlementConsentPath(executionIdHex: string): string;
|
|
55
|
-
export declare function authorityOriginFromSessionBase(sessionBaseUrl: string): string;
|
|
56
60
|
export declare function digestForPrompt(prompt: ConsentPrompt): Uint8Array;
|
package/dist/settlement.js
CHANGED
|
@@ -2,6 +2,11 @@ import { ByteReader, ByteWriter, equalBytes, fromHex, textBytes, toHex0x, } from
|
|
|
2
2
|
import { digestFramed } from "./crypto.js";
|
|
3
3
|
const ANCHOR_DOMAIN_ID_V1 = textBytes("arena_tunnel::anchor_domain_id_v1");
|
|
4
4
|
const SETTLEMENT_PURPOSE = textBytes("arena_tunnel::settlement");
|
|
5
|
+
/** The Product API's deployed default origin. `dopa-open`'s `--product-url`
|
|
6
|
+
* (and `DOPA_OPEN_PRODUCT_URL`) default here, matching the Rust client and
|
|
7
|
+
* CLI's `DEFAULT_OPEN_API_BASE_URL`, so a caller only has to override it for
|
|
8
|
+
* a local stack or a non-default plane. */
|
|
9
|
+
export const DEFAULT_OPEN_API_BASE_URL = "https://open.dopamint.fun";
|
|
5
10
|
export function encodeTerminalState(state) {
|
|
6
11
|
const writer = new ByteWriter()
|
|
7
12
|
.pushU16(1)
|
|
@@ -103,13 +108,7 @@ export function buildConsentRequest(args) {
|
|
|
103
108
|
}
|
|
104
109
|
export function settlementConsentPath(executionIdHex) {
|
|
105
110
|
const hex = executionIdHex.replace(/^0x/, "");
|
|
106
|
-
return `/
|
|
107
|
-
}
|
|
108
|
-
export function authorityOriginFromSessionBase(sessionBaseUrl) {
|
|
109
|
-
const idx = sessionBaseUrl.indexOf("/v1/exec/");
|
|
110
|
-
if (idx <= 0)
|
|
111
|
-
throw new Error(`admission session_base_url is not an execution session URL: ${sessionBaseUrl}`);
|
|
112
|
-
return sessionBaseUrl.slice(0, idx);
|
|
111
|
+
return `/v1/authority/executions/${hex}/settlements`;
|
|
113
112
|
}
|
|
114
113
|
export function digestForPrompt(prompt) {
|
|
115
114
|
const terminal = decodeTerminalState(fromHex(prompt.encoded_terminal_state));
|
package/dist/tour.js
CHANGED
|
@@ -63,8 +63,8 @@ function unavailable(error) {
|
|
|
63
63
|
}
|
|
64
64
|
export async function enterTour(client, tour, floor = {}) {
|
|
65
65
|
const target = tour === "playground"
|
|
66
|
-
? "/
|
|
67
|
-
: "/
|
|
66
|
+
? "/v1/tours/playground/entries"
|
|
67
|
+
: "/v1/tours/tournament/entries";
|
|
68
68
|
if (floor.minAgents !== undefined && tour !== "playground")
|
|
69
69
|
throw new Error("a floor of real agents only applies to the playground");
|
|
70
70
|
/* No body at all when nothing is stated: the join every client sent before
|
|
@@ -124,13 +124,13 @@ export async function queueUntilSeated(client, tour, options = {}) {
|
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
126
|
export async function readPosition(client, tableId) {
|
|
127
|
-
const { status, json } = await signedFetch(client, "GET", `/
|
|
127
|
+
const { status, json } = await signedFetch(client, "GET", `/v1/tables/${tableId}/decision`);
|
|
128
128
|
if (status !== 200)
|
|
129
129
|
throw new Error(refusalMessage("decision read", status, json));
|
|
130
130
|
return json;
|
|
131
131
|
}
|
|
132
132
|
export async function act(client, tableId, move) {
|
|
133
|
-
const { status, json } = await signedFetch(client, "POST", `/
|
|
133
|
+
const { status, json } = await signedFetch(client, "POST", `/v1/tables/${tableId}/actions`, move);
|
|
134
134
|
if (status !== 200)
|
|
135
135
|
throw new Error(refusalMessage("action", status, json));
|
|
136
136
|
return json;
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dopamint-fun/open-sdk",
|
|
3
|
-
"version": "0.2.0-dev.
|
|
3
|
+
"version": "0.2.0-dev.11",
|
|
4
4
|
"description": "DOPA-OPEN client SDK: generate and hold your own agent key, sign registrations, and play a Participant Session",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/CommandOSSLabs/dopamint-arena.git",
|
|
9
|
-
"directory": "libs/dopa-open
|
|
9
|
+
"directory": "libs/dopa-open/client-ts"
|
|
10
10
|
},
|
|
11
11
|
"type": "module",
|
|
12
12
|
"main": "dist/index.js",
|