@provable-games/dm-engine 0.1.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/dist/actions.d.ts +18 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/actions.js +88 -0
- package/dist/actions.js.map +1 -0
- package/dist/constants/beast.d.ts +28 -0
- package/dist/constants/beast.d.ts.map +1 -0
- package/dist/constants/beast.js +216 -0
- package/dist/constants/beast.js.map +1 -0
- package/dist/constants/game.d.ts +23 -0
- package/dist/constants/game.d.ts.map +1 -0
- package/dist/constants/game.js +26 -0
- package/dist/constants/game.js.map +1 -0
- package/dist/constants/loot.d.ts +341 -0
- package/dist/constants/loot.d.ts.map +1 -0
- package/dist/constants/loot.js +456 -0
- package/dist/constants/loot.js.map +1 -0
- package/dist/constants/obstacle.d.ts +4 -0
- package/dist/constants/obstacle.d.ts.map +1 -0
- package/dist/constants/obstacle.js +81 -0
- package/dist/constants/obstacle.js.map +1 -0
- package/dist/events.d.ts +50 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +2 -0
- package/dist/events.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/packing.d.ts +6 -0
- package/dist/packing.d.ts.map +1 -0
- package/dist/packing.js +76 -0
- package/dist/packing.js.map +1 -0
- package/dist/protocol.d.ts +55 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +250 -0
- package/dist/protocol.js.map +1 -0
- package/dist/replay.d.ts +35 -0
- package/dist/replay.d.ts.map +1 -0
- package/dist/replay.js +856 -0
- package/dist/replay.js.map +1 -0
- package/dist/rules/beast.d.ts +264 -0
- package/dist/rules/beast.d.ts.map +1 -0
- package/dist/rules/beast.js +535 -0
- package/dist/rules/beast.js.map +1 -0
- package/dist/rules/game.d.ts +35 -0
- package/dist/rules/game.d.ts.map +1 -0
- package/dist/rules/game.js +462 -0
- package/dist/rules/game.js.map +1 -0
- package/dist/rules/gameSimulation.d.ts +158 -0
- package/dist/rules/gameSimulation.d.ts.map +1 -0
- package/dist/rules/gameSimulation.js +845 -0
- package/dist/rules/gameSimulation.js.map +1 -0
- package/dist/rules/health.d.ts +3 -0
- package/dist/rules/health.d.ts.map +1 -0
- package/dist/rules/health.js +7 -0
- package/dist/rules/health.js.map +1 -0
- package/dist/rules/loot.d.ts +100 -0
- package/dist/rules/loot.d.ts.map +1 -0
- package/dist/rules/loot.js +626 -0
- package/dist/rules/loot.js.map +1 -0
- package/dist/rules/market.d.ts +28 -0
- package/dist/rules/market.d.ts.map +1 -0
- package/dist/rules/market.js +83 -0
- package/dist/rules/market.js.map +1 -0
- package/dist/rules/processFutures.d.ts +79 -0
- package/dist/rules/processFutures.d.ts.map +1 -0
- package/dist/rules/processFutures.js +429 -0
- package/dist/rules/processFutures.js.map +1 -0
- package/dist/rules/tokenId.d.ts +31 -0
- package/dist/rules/tokenId.d.ts.map +1 -0
- package/dist/rules/tokenId.js +102 -0
- package/dist/rules/tokenId.js.map +1 -0
- package/dist/staging.d.ts +18 -0
- package/dist/staging.d.ts.map +1 -0
- package/dist/staging.js +27 -0
- package/dist/staging.js.map +1 -0
- package/dist/transcript.d.ts +64 -0
- package/dist/transcript.d.ts.map +1 -0
- package/dist/transcript.js +92 -0
- package/dist/transcript.js.map +1 -0
- package/dist/types.d.ts +141 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/view.d.ts +4 -0
- package/dist/view.d.ts.map +1 -0
- package/dist/view.js +18 -0
- package/dist/view.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Denshokan game id for Death Mountain. Defined here rather than imported from the
|
|
3
|
+
* client's Denshokan React context so this module stays runtime-agnostic; the client
|
|
4
|
+
* re-exports it from `@/contexts/denshokan`.
|
|
5
|
+
*/
|
|
6
|
+
export declare const GAME_ID = 1;
|
|
7
|
+
export interface PackedTokenId {
|
|
8
|
+
game_id: number;
|
|
9
|
+
minted_by: number;
|
|
10
|
+
settings_id: number;
|
|
11
|
+
start_delay: number;
|
|
12
|
+
soulbound: boolean;
|
|
13
|
+
has_context: boolean;
|
|
14
|
+
paymaster: boolean;
|
|
15
|
+
minted_at: number;
|
|
16
|
+
end_delay: number;
|
|
17
|
+
objective_id: number;
|
|
18
|
+
tx_hash: number;
|
|
19
|
+
salt: number;
|
|
20
|
+
metadata: number;
|
|
21
|
+
}
|
|
22
|
+
export declare function unpackTokenId(tokenId: number | bigint | string): PackedTokenId;
|
|
23
|
+
export declare function packTokenId(params?: Partial<PackedTokenId>): bigint;
|
|
24
|
+
export declare function unpackGameId(tokenId: number | bigint | string): number;
|
|
25
|
+
export declare function unpackSettingsId(tokenId: number | bigint | string): number;
|
|
26
|
+
export declare function unpackMintedBy(tokenId: number | bigint | string): number;
|
|
27
|
+
export declare function unpackMintedAt(tokenId: number | bigint | string): number;
|
|
28
|
+
export declare function unpackStartDelay(tokenId: number | bigint | string): number;
|
|
29
|
+
export declare function unpackEndDelay(tokenId: number | bigint | string): number;
|
|
30
|
+
export declare function unpackObjectiveId(tokenId: number | bigint | string): number;
|
|
31
|
+
//# sourceMappingURL=tokenId.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenId.d.ts","sourceRoot":"","sources":["../../src/rules/tokenId.ts"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,eAAO,MAAM,OAAO,IAAI,CAAC;AAWzB,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,aAAa,CA8C9E;AAED,wBAAgB,WAAW,CAAC,MAAM,GAAE,OAAO,CAAC,aAAa,CAAM,GAAG,MAAM,CAmCvE;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAEtE;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAE1E;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAExE;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAExE;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAE1E;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAExE;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAE3E"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// Decodes fields from a packed token ID (felt252).
|
|
2
|
+
//
|
|
3
|
+
// Bit layout (251 bits, u128-aligned):
|
|
4
|
+
// Low u128: game_id(30) | minted_by(40) | settings_id(30) | start_delay(25) | soulbound(1) | has_context(1) | paymaster(1)
|
|
5
|
+
// High u128: minted_at(35) | end_delay(25) | objective_id(30) | tx_hash(10) | salt(10) | metadata(13)
|
|
6
|
+
/**
|
|
7
|
+
* Denshokan game id for Death Mountain. Defined here rather than imported from the
|
|
8
|
+
* client's Denshokan React context so this module stays runtime-agnostic; the client
|
|
9
|
+
* re-exports it from `@/contexts/denshokan`.
|
|
10
|
+
*/
|
|
11
|
+
export const GAME_ID = 1;
|
|
12
|
+
const MASK_1 = 0x1n;
|
|
13
|
+
const MASK_10 = 0x3ffn;
|
|
14
|
+
const MASK_13 = 0x1fffn;
|
|
15
|
+
const MASK_25 = 0x1ffffffn;
|
|
16
|
+
const MASK_30 = 0x3fffffffn;
|
|
17
|
+
const MASK_35 = 0x7ffffffffn;
|
|
18
|
+
const MASK_40 = 0xffffffffffn;
|
|
19
|
+
const MASK_128 = (1n << 128n) - 1n;
|
|
20
|
+
export function unpackTokenId(tokenId) {
|
|
21
|
+
const packed = BigInt(tokenId);
|
|
22
|
+
let low = packed & MASK_128;
|
|
23
|
+
let high = packed >> 128n;
|
|
24
|
+
const game_id = Number(low & MASK_30);
|
|
25
|
+
low >>= 30n;
|
|
26
|
+
const minted_by = Number(low & MASK_40);
|
|
27
|
+
low >>= 40n;
|
|
28
|
+
const settings_id = Number(low & MASK_30);
|
|
29
|
+
low >>= 30n;
|
|
30
|
+
const start_delay = Number(low & MASK_25);
|
|
31
|
+
low >>= 25n;
|
|
32
|
+
const soulbound = (low & MASK_1) === 1n;
|
|
33
|
+
low >>= 1n;
|
|
34
|
+
const has_context = (low & MASK_1) === 1n;
|
|
35
|
+
low >>= 1n;
|
|
36
|
+
const paymaster = (low & MASK_1) === 1n;
|
|
37
|
+
const minted_at = Number(high & MASK_35);
|
|
38
|
+
high >>= 35n;
|
|
39
|
+
const end_delay = Number(high & MASK_25);
|
|
40
|
+
high >>= 25n;
|
|
41
|
+
const objective_id = Number(high & MASK_30);
|
|
42
|
+
high >>= 30n;
|
|
43
|
+
const tx_hash = Number(high & MASK_10);
|
|
44
|
+
high >>= 10n;
|
|
45
|
+
const salt = Number(high & MASK_10);
|
|
46
|
+
high >>= 10n;
|
|
47
|
+
const metadata = Number(high & MASK_13);
|
|
48
|
+
return {
|
|
49
|
+
game_id,
|
|
50
|
+
minted_by,
|
|
51
|
+
settings_id,
|
|
52
|
+
start_delay,
|
|
53
|
+
soulbound,
|
|
54
|
+
has_context,
|
|
55
|
+
paymaster,
|
|
56
|
+
minted_at,
|
|
57
|
+
end_delay,
|
|
58
|
+
objective_id,
|
|
59
|
+
tx_hash,
|
|
60
|
+
salt,
|
|
61
|
+
metadata,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
export function packTokenId(params = {}) {
|
|
65
|
+
const { game_id = GAME_ID, minted_by = 0, settings_id = 0, start_delay = 0, soulbound = false, has_context = false, paymaster = false, minted_at = Math.round(Date.now() / 1000), end_delay = 0, objective_id = 0, tx_hash = Math.floor(Math.random() * 1000), salt = Math.floor(Math.random() * 1000), metadata = 0, } = params;
|
|
66
|
+
const low = (BigInt(game_id) & MASK_30) |
|
|
67
|
+
((BigInt(minted_by) & MASK_40) << 30n) |
|
|
68
|
+
((BigInt(settings_id) & MASK_30) << 70n) |
|
|
69
|
+
((BigInt(start_delay) & MASK_25) << 100n) |
|
|
70
|
+
((soulbound ? 1n : 0n) << 125n) |
|
|
71
|
+
((has_context ? 1n : 0n) << 126n) |
|
|
72
|
+
((paymaster ? 1n : 0n) << 127n);
|
|
73
|
+
const high = (BigInt(minted_at) & MASK_35) |
|
|
74
|
+
((BigInt(end_delay) & MASK_25) << 35n) |
|
|
75
|
+
((BigInt(objective_id) & MASK_30) << 60n) |
|
|
76
|
+
((BigInt(tx_hash) & MASK_10) << 90n) |
|
|
77
|
+
((BigInt(salt) & MASK_10) << 100n) |
|
|
78
|
+
((BigInt(metadata) & MASK_13) << 110n);
|
|
79
|
+
return (high << 128n) | low;
|
|
80
|
+
}
|
|
81
|
+
export function unpackGameId(tokenId) {
|
|
82
|
+
return Number(BigInt(tokenId) & MASK_30);
|
|
83
|
+
}
|
|
84
|
+
export function unpackSettingsId(tokenId) {
|
|
85
|
+
return Number((BigInt(tokenId) >> 70n) & MASK_30);
|
|
86
|
+
}
|
|
87
|
+
export function unpackMintedBy(tokenId) {
|
|
88
|
+
return Number((BigInt(tokenId) >> 30n) & MASK_40);
|
|
89
|
+
}
|
|
90
|
+
export function unpackMintedAt(tokenId) {
|
|
91
|
+
return Number((BigInt(tokenId) >> 128n) & MASK_35);
|
|
92
|
+
}
|
|
93
|
+
export function unpackStartDelay(tokenId) {
|
|
94
|
+
return Number((BigInt(tokenId) >> 100n) & MASK_25);
|
|
95
|
+
}
|
|
96
|
+
export function unpackEndDelay(tokenId) {
|
|
97
|
+
return Number((BigInt(tokenId) >> 163n) & MASK_25);
|
|
98
|
+
}
|
|
99
|
+
export function unpackObjectiveId(tokenId) {
|
|
100
|
+
return Number((BigInt(tokenId) >> 188n) & MASK_30);
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=tokenId.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenId.js","sourceRoot":"","sources":["../../src/rules/tokenId.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Adventurer } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Whether an action can be held back and committed alongside the next real one.
|
|
4
|
+
*
|
|
5
|
+
* Two conditions, both from `replay.cairo`, and both necessary:
|
|
6
|
+
*
|
|
7
|
+
* 1. The action must consume NO entropy, because staging means simulating it before its block hash
|
|
8
|
+
* exists. SELECT_STATS, BUY and DROP never do; EQUIP does, but only in battle, where it
|
|
9
|
+
* triggers a counterattack.
|
|
10
|
+
* 2. It must be legal out of battle -- which is where the `beast_health` test really comes from.
|
|
11
|
+
* The live actions behind all four of these assert `!in_battle`, so staging one mid-fight would
|
|
12
|
+
* build a commitment that settlement rejects.
|
|
13
|
+
*
|
|
14
|
+
* Both collapse to the same test, so it is written once.
|
|
15
|
+
*/
|
|
16
|
+
export declare function isStageableDeterministicAction(actionType: string, beastHealth: number): boolean;
|
|
17
|
+
export declare function encodePendingIdleEquip(adventurer: Adventurer | null, committedView: Adventurer | null): bigint | null;
|
|
18
|
+
//# sourceMappingURL=staging.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staging.d.ts","sourceRoot":"","sources":["../src/staging.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAO7C;;;;;;;;;;;;;GAaG;AACH,wBAAgB,8BAA8B,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAE/F;AAED,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,UAAU,GAAG,IAAI,EAC7B,aAAa,EAAE,UAAU,GAAG,IAAI,GAC/B,MAAM,GAAG,IAAI,CAMf"}
|
package/dist/staging.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { getNewItemsEquipped } from "./rules/game.js";
|
|
2
|
+
import { encodeEquip } from "./protocol.js";
|
|
3
|
+
const STAGEABLE_ACTIONS = new Set(["select_stat_upgrades", "buy_items", "equip", "drop"]);
|
|
4
|
+
/**
|
|
5
|
+
* Whether an action can be held back and committed alongside the next real one.
|
|
6
|
+
*
|
|
7
|
+
* Two conditions, both from `replay.cairo`, and both necessary:
|
|
8
|
+
*
|
|
9
|
+
* 1. The action must consume NO entropy, because staging means simulating it before its block hash
|
|
10
|
+
* exists. SELECT_STATS, BUY and DROP never do; EQUIP does, but only in battle, where it
|
|
11
|
+
* triggers a counterattack.
|
|
12
|
+
* 2. It must be legal out of battle -- which is where the `beast_health` test really comes from.
|
|
13
|
+
* The live actions behind all four of these assert `!in_battle`, so staging one mid-fight would
|
|
14
|
+
* build a commitment that settlement rejects.
|
|
15
|
+
*
|
|
16
|
+
* Both collapse to the same test, so it is written once.
|
|
17
|
+
*/
|
|
18
|
+
export function isStageableDeterministicAction(actionType, beastHealth) {
|
|
19
|
+
return STAGEABLE_ACTIONS.has(actionType) && beastHealth === 0;
|
|
20
|
+
}
|
|
21
|
+
export function encodePendingIdleEquip(adventurer, committedView) {
|
|
22
|
+
if (!adventurer || !committedView || adventurer.beast_health !== 0)
|
|
23
|
+
return null;
|
|
24
|
+
const items = getNewItemsEquipped(adventurer.equipment, committedView.equipment).map((item) => item.id);
|
|
25
|
+
return items.length === 0 ? null : encodeEquip(items);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=staging.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staging.js","sourceRoot":"","sources":["../src/staging.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,CAAC,sBAAsB,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;AAE1F;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,8BAA8B,CAAC,UAAkB,EAAE,WAAmB;IACpF,OAAO,iBAAiB,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,WAAW,KAAK,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,UAA6B,EAC7B,aAAgC;IAEhC,IAAI,CAAC,UAAU,IAAI,CAAC,aAAa,IAAI,UAAU,CAAC,YAAY,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAChF,MAAM,KAAK,GAAG,mBAAmB,CAAC,UAAU,CAAC,SAAS,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC,GAAG,CAClF,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAClB,CAAC;IACF,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;AACxD,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export interface ActionCommittedEvent {
|
|
2
|
+
adventurerId: bigint;
|
|
3
|
+
/** One call may carry many actions. They fold individually but share a commit block. */
|
|
4
|
+
encodedActions: bigint[];
|
|
5
|
+
blockNumber: bigint;
|
|
6
|
+
transactionHash: string;
|
|
7
|
+
transactionIndex: number;
|
|
8
|
+
eventIndex: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Decode one `ActionCommitted { #[key] adventurer_id, encoded_actions: Span<felt252> }`.
|
|
12
|
+
*
|
|
13
|
+
* Serde writes a `Span` as a length followed by its elements, so `data[0]` is the count.
|
|
14
|
+
*/
|
|
15
|
+
export declare function decodeActionCommitted(keys: string[], data: string[], position: {
|
|
16
|
+
blockNumber: bigint;
|
|
17
|
+
transactionHash: string;
|
|
18
|
+
transactionIndex: number;
|
|
19
|
+
eventIndex: number;
|
|
20
|
+
}): ActionCommittedEvent;
|
|
21
|
+
export interface GameSettledEvent {
|
|
22
|
+
adventurerId: bigint;
|
|
23
|
+
settler: bigint;
|
|
24
|
+
protocolVersion: number;
|
|
25
|
+
finalCommitment: bigint;
|
|
26
|
+
committedActionCount: number;
|
|
27
|
+
terminalActionIndex: number;
|
|
28
|
+
terminalReason: number;
|
|
29
|
+
packedAdventurer: bigint;
|
|
30
|
+
packedBag: bigint;
|
|
31
|
+
settledAtBlock: bigint;
|
|
32
|
+
}
|
|
33
|
+
/** Decode one `GameSettled { #[key] adventurer_id, #[key] settler, ...8 felts }`. */
|
|
34
|
+
export declare function decodeGameSettled(keys: string[], data: string[]): GameSettledEvent;
|
|
35
|
+
/**
|
|
36
|
+
* Chain order for commit events.
|
|
37
|
+
*
|
|
38
|
+
* `(block_number, transaction_index, event_index)`. Block number alone is NOT enough: two
|
|
39
|
+
* commits for one adventurer can land in the same block, and folding them the wrong way round
|
|
40
|
+
* yields a different commitment and different entropy for every action after.
|
|
41
|
+
*/
|
|
42
|
+
export declare function compareCommitOrder(a: ActionCommittedEvent, b: ActionCommittedEvent): number;
|
|
43
|
+
export interface Transcript {
|
|
44
|
+
adventurerId: bigint;
|
|
45
|
+
/** Flat, one entry per action -- not per commit call. Parallel with `blocks`. */
|
|
46
|
+
actions: bigint[];
|
|
47
|
+
/** The commit block of each action; repeats are the normal signature of a bundle. */
|
|
48
|
+
blocks: bigint[];
|
|
49
|
+
/** The rolling commitment after each action; action `i`'s entropy is derived from `rolling[i]`. */
|
|
50
|
+
rollings: bigint[];
|
|
51
|
+
/** The value that must equal `get_commitment(adventurer_id)` on chain. */
|
|
52
|
+
finalCommitment: bigint;
|
|
53
|
+
/** Index of the first SURRENDER, or null. A death is invisible here -- only replay finds it. */
|
|
54
|
+
surrenderIndex: number | null;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Re-fold a game's commit events into the transcript settlement expects.
|
|
58
|
+
*
|
|
59
|
+
* The output `actions`/`blocks` pair is exactly what `settle_game(id, actions, blocks)` takes,
|
|
60
|
+
* and `finalCommitment` is what it will check against the stored felt -- so a caller can verify
|
|
61
|
+
* its own reconstruction before spending gas on a settlement that would revert.
|
|
62
|
+
*/
|
|
63
|
+
export declare function reconstructTranscript(adventurerId: bigint, events: ActionCommittedEvent[]): Transcript;
|
|
64
|
+
//# sourceMappingURL=transcript.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcript.d.ts","sourceRoot":"","sources":["../src/transcript.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,wFAAwF;IACxF,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,EAAE,MAAM,EAAE,EACd,QAAQ,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACvG,oBAAoB,CAgBtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,qFAAqF;AACrF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAclF;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,oBAAoB,EAAE,CAAC,EAAE,oBAAoB,GAAG,MAAM,CAI3F;AAED,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,iFAAiF;IACjF,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,qFAAqF;IACrF,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,mGAAmG;IACnG,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,0EAA0E;IAC1E,eAAe,EAAE,MAAM,CAAC;IACxB,gGAAgG;IAChG,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,oBAAoB,EAAE,GAC7B,UAAU,CAsBZ"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { actionOpcode, fold, Opcode, root } from "./protocol.js";
|
|
2
|
+
/**
|
|
3
|
+
* Reading a commit-reveal GameCore's event log.
|
|
4
|
+
*
|
|
5
|
+
* The contract emits only `ActionCommitted`, and it carries the bare minimum: the game id and
|
|
6
|
+
* the felts committed. Everything else an indexer or a resuming client wants -- the rolling
|
|
7
|
+
* commitment, each action's index, whether the run has closed -- is *derived* here by re-folding
|
|
8
|
+
* the transcript, exactly as `commit_action` did when it wrote it.
|
|
9
|
+
*
|
|
10
|
+
* Shared by the indexer's off-chain replay and the client's resume path so both reconstruct a
|
|
11
|
+
* run the same way. If they disagreed, the client would act on a board the indexer never shows
|
|
12
|
+
* spectators, and one of the two would be wrong about what the chain holds.
|
|
13
|
+
*/
|
|
14
|
+
const felt = (value) => (value ? BigInt(value) : 0n);
|
|
15
|
+
/**
|
|
16
|
+
* Decode one `ActionCommitted { #[key] adventurer_id, encoded_actions: Span<felt252> }`.
|
|
17
|
+
*
|
|
18
|
+
* Serde writes a `Span` as a length followed by its elements, so `data[0]` is the count.
|
|
19
|
+
*/
|
|
20
|
+
export function decodeActionCommitted(keys, data, position) {
|
|
21
|
+
if (keys.length < 2)
|
|
22
|
+
throw new Error("ActionCommitted: missing adventurer_id key");
|
|
23
|
+
const length = Number(felt(data[0]));
|
|
24
|
+
// Validate before reading. A truncated payload would otherwise decode into a bundle of zeros,
|
|
25
|
+
// which fold happily and produce a commitment that can never reconcile with the chain.
|
|
26
|
+
if (data.length - 1 < length) {
|
|
27
|
+
throw new Error(`ActionCommitted: declared ${length} actions but only ${data.length - 1} felts follow`);
|
|
28
|
+
}
|
|
29
|
+
const encodedActions = [];
|
|
30
|
+
for (let i = 0; i < length; i++)
|
|
31
|
+
encodedActions.push(felt(data[1 + i]));
|
|
32
|
+
return { adventurerId: felt(keys[1]), encodedActions, ...position };
|
|
33
|
+
}
|
|
34
|
+
/** Decode one `GameSettled { #[key] adventurer_id, #[key] settler, ...8 felts }`. */
|
|
35
|
+
export function decodeGameSettled(keys, data) {
|
|
36
|
+
if (keys.length < 3)
|
|
37
|
+
throw new Error("GameSettled: missing keys");
|
|
38
|
+
return {
|
|
39
|
+
adventurerId: felt(keys[1]),
|
|
40
|
+
settler: felt(keys[2]),
|
|
41
|
+
protocolVersion: Number(felt(data[0])),
|
|
42
|
+
finalCommitment: felt(data[1]),
|
|
43
|
+
committedActionCount: Number(felt(data[2])),
|
|
44
|
+
terminalActionIndex: Number(felt(data[3])),
|
|
45
|
+
terminalReason: Number(felt(data[4])),
|
|
46
|
+
packedAdventurer: felt(data[5]),
|
|
47
|
+
packedBag: felt(data[6]),
|
|
48
|
+
settledAtBlock: felt(data[7]),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Chain order for commit events.
|
|
53
|
+
*
|
|
54
|
+
* `(block_number, transaction_index, event_index)`. Block number alone is NOT enough: two
|
|
55
|
+
* commits for one adventurer can land in the same block, and folding them the wrong way round
|
|
56
|
+
* yields a different commitment and different entropy for every action after.
|
|
57
|
+
*/
|
|
58
|
+
export function compareCommitOrder(a, b) {
|
|
59
|
+
if (a.blockNumber !== b.blockNumber)
|
|
60
|
+
return a.blockNumber < b.blockNumber ? -1 : 1;
|
|
61
|
+
if (a.transactionIndex !== b.transactionIndex)
|
|
62
|
+
return a.transactionIndex - b.transactionIndex;
|
|
63
|
+
return a.eventIndex - b.eventIndex;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Re-fold a game's commit events into the transcript settlement expects.
|
|
67
|
+
*
|
|
68
|
+
* The output `actions`/`blocks` pair is exactly what `settle_game(id, actions, blocks)` takes,
|
|
69
|
+
* and `finalCommitment` is what it will check against the stored felt -- so a caller can verify
|
|
70
|
+
* its own reconstruction before spending gas on a settlement that would revert.
|
|
71
|
+
*/
|
|
72
|
+
export function reconstructTranscript(adventurerId, events) {
|
|
73
|
+
const ordered = [...events].sort(compareCommitOrder);
|
|
74
|
+
let rolling = root(adventurerId);
|
|
75
|
+
const actions = [];
|
|
76
|
+
const blocks = [];
|
|
77
|
+
const rollings = [];
|
|
78
|
+
let surrenderIndex = null;
|
|
79
|
+
for (const event of ordered) {
|
|
80
|
+
for (const encoded of event.encodedActions) {
|
|
81
|
+
rolling = fold(rolling, encoded, event.blockNumber);
|
|
82
|
+
actions.push(encoded);
|
|
83
|
+
blocks.push(event.blockNumber);
|
|
84
|
+
rollings.push(rolling);
|
|
85
|
+
if (surrenderIndex === null && actionOpcode(encoded) === Opcode.SURRENDER) {
|
|
86
|
+
surrenderIndex = actions.length - 1;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return { adventurerId, actions, blocks, rollings, finalCommitment: rolling, surrenderIndex };
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=transcript.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcript.js","sourceRoot":"","sources":["../src/transcript.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
export interface Item {
|
|
2
|
+
id: number;
|
|
3
|
+
xp: number;
|
|
4
|
+
}
|
|
5
|
+
export interface Equipment {
|
|
6
|
+
weapon: Item;
|
|
7
|
+
chest: Item;
|
|
8
|
+
head: Item;
|
|
9
|
+
waist: Item;
|
|
10
|
+
foot: Item;
|
|
11
|
+
hand: Item;
|
|
12
|
+
neck: Item;
|
|
13
|
+
ring: Item;
|
|
14
|
+
}
|
|
15
|
+
export interface Adventurer {
|
|
16
|
+
health: number;
|
|
17
|
+
xp: number;
|
|
18
|
+
gold: number;
|
|
19
|
+
beast_health: number;
|
|
20
|
+
stat_upgrades_available: number;
|
|
21
|
+
stats: Stats;
|
|
22
|
+
equipment: Equipment;
|
|
23
|
+
item_specials_salt: number;
|
|
24
|
+
beast_salt: number;
|
|
25
|
+
level_salt: number;
|
|
26
|
+
}
|
|
27
|
+
export interface Bag {
|
|
28
|
+
item_1: Item;
|
|
29
|
+
item_2: Item;
|
|
30
|
+
item_3: Item;
|
|
31
|
+
item_4: Item;
|
|
32
|
+
item_5: Item;
|
|
33
|
+
item_6: Item;
|
|
34
|
+
item_7: Item;
|
|
35
|
+
item_8: Item;
|
|
36
|
+
item_9: Item;
|
|
37
|
+
item_10: Item;
|
|
38
|
+
item_11: Item;
|
|
39
|
+
item_12: Item;
|
|
40
|
+
item_13: Item;
|
|
41
|
+
item_14: Item;
|
|
42
|
+
item_15: Item;
|
|
43
|
+
}
|
|
44
|
+
export interface Beast {
|
|
45
|
+
id: number;
|
|
46
|
+
baseName: string;
|
|
47
|
+
name: string;
|
|
48
|
+
health: number;
|
|
49
|
+
level: number;
|
|
50
|
+
type: string;
|
|
51
|
+
tier: number;
|
|
52
|
+
specialPrefix: string | null;
|
|
53
|
+
specialSuffix: string | null;
|
|
54
|
+
isCollectable: boolean;
|
|
55
|
+
traitSeed: bigint;
|
|
56
|
+
}
|
|
57
|
+
export interface Stats {
|
|
58
|
+
strength: number;
|
|
59
|
+
dexterity: number;
|
|
60
|
+
vitality: number;
|
|
61
|
+
intelligence: number;
|
|
62
|
+
wisdom: number;
|
|
63
|
+
charisma: number;
|
|
64
|
+
luck: number;
|
|
65
|
+
}
|
|
66
|
+
export interface CombatStats {
|
|
67
|
+
baseDamage: number;
|
|
68
|
+
protection: number;
|
|
69
|
+
bestDamage: number;
|
|
70
|
+
bestProtection: number;
|
|
71
|
+
bestItems: Item[];
|
|
72
|
+
critChance: number;
|
|
73
|
+
criticalDamage: number;
|
|
74
|
+
gearScore: number;
|
|
75
|
+
maxBeastBaseDamage: number;
|
|
76
|
+
maxBeastCriticalDamage: number;
|
|
77
|
+
}
|
|
78
|
+
export interface ItemPurchase {
|
|
79
|
+
item_id: number;
|
|
80
|
+
equip: boolean;
|
|
81
|
+
}
|
|
82
|
+
export interface Obstacle {
|
|
83
|
+
id: number;
|
|
84
|
+
dodged: boolean;
|
|
85
|
+
damage: number;
|
|
86
|
+
location: string;
|
|
87
|
+
critical_hit: boolean;
|
|
88
|
+
}
|
|
89
|
+
export interface Attack {
|
|
90
|
+
damage: number;
|
|
91
|
+
location: string;
|
|
92
|
+
critical_hit: boolean;
|
|
93
|
+
}
|
|
94
|
+
export interface GameAction {
|
|
95
|
+
type: string;
|
|
96
|
+
statUpgrades?: Stats;
|
|
97
|
+
items?: number[];
|
|
98
|
+
itemPurchases?: ItemPurchase[];
|
|
99
|
+
potions?: number;
|
|
100
|
+
remainingGold?: number;
|
|
101
|
+
tillDamage?: number;
|
|
102
|
+
tillGold?: boolean;
|
|
103
|
+
tillHealth?: number;
|
|
104
|
+
tillBeastHealth?: number;
|
|
105
|
+
gameId?: string;
|
|
106
|
+
settings?: any;
|
|
107
|
+
weapon?: number;
|
|
108
|
+
}
|
|
109
|
+
export interface Payment {
|
|
110
|
+
paymentType: "Ticket" | "Golden Pass" | "DirectFee";
|
|
111
|
+
goldenPass?: {
|
|
112
|
+
address: string;
|
|
113
|
+
tokenId: number;
|
|
114
|
+
};
|
|
115
|
+
directFee?: {
|
|
116
|
+
tokenAddress: string;
|
|
117
|
+
amount: string;
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
export interface Collectable {
|
|
121
|
+
beast: Beast;
|
|
122
|
+
showPopup: boolean;
|
|
123
|
+
tokenURI: string | null;
|
|
124
|
+
}
|
|
125
|
+
export interface Quest {
|
|
126
|
+
id: number;
|
|
127
|
+
chapterId: number;
|
|
128
|
+
targetScore: number;
|
|
129
|
+
}
|
|
130
|
+
export interface GameSettingsData {
|
|
131
|
+
vrf_address: string;
|
|
132
|
+
name: string;
|
|
133
|
+
in_battle: boolean;
|
|
134
|
+
game_seed: number;
|
|
135
|
+
game_seed_until_xp: number;
|
|
136
|
+
base_damage_reduction: number;
|
|
137
|
+
market_size: number;
|
|
138
|
+
adventurer: Adventurer;
|
|
139
|
+
bag: Item[];
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/dist/view.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../src/view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAGnD,gFAAgF;AAChF,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,UAAU,CAcpF"}
|
package/dist/view.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ItemUtils } from "./rules/loot.js";
|
|
2
|
+
/** Apply the same temporary equipment/bag boosts used by the live load path. */
|
|
3
|
+
export function toPlayableAdventurer(adventurer, bag) {
|
|
4
|
+
const boosts = ItemUtils.getEquippedItemStats(adventurer, bag);
|
|
5
|
+
return {
|
|
6
|
+
...adventurer,
|
|
7
|
+
stats: {
|
|
8
|
+
strength: adventurer.stats.strength + boosts.strength,
|
|
9
|
+
dexterity: adventurer.stats.dexterity + boosts.dexterity,
|
|
10
|
+
vitality: adventurer.stats.vitality + boosts.vitality,
|
|
11
|
+
intelligence: adventurer.stats.intelligence + boosts.intelligence,
|
|
12
|
+
wisdom: adventurer.stats.wisdom + boosts.wisdom,
|
|
13
|
+
charisma: adventurer.stats.charisma + boosts.charisma,
|
|
14
|
+
luck: adventurer.stats.luck + boosts.luck,
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=view.js.map
|
package/dist/view.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view.js","sourceRoot":"","sources":["../src/view.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,gFAAgF;AAChF,MAAM,UAAU,oBAAoB,CAAC,UAAsB,EAAE,GAAW;IACtE,MAAM,MAAM,GAAG,SAAS,CAAC,oBAAoB,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IAC/D,OAAO;QACL,GAAG,UAAU;QACb,KAAK,EAAE;YACL,QAAQ,EAAE,UAAU,CAAC,KAAK,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ;YACrD,SAAS,EAAE,UAAU,CAAC,KAAK,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS;YACxD,QAAQ,EAAE,UAAU,CAAC,KAAK,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ;YACrD,YAAY,EAAE,UAAU,CAAC,KAAK,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY;YACjE,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM;YAC/C,QAAQ,EAAE,UAAU,CAAC,KAAK,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ;YACrD,IAAI,EAAE,UAAU,CAAC,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI;SAC1C;KACF,CAAC;AACJ,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@provable-games/dm-engine",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Death Mountain game rules and commit-reveal protocol, ported from the Cairo contracts. Shared by the client, the indexer and the API.",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/Provable-Games/super-death-mountain.git",
|
|
10
|
+
"directory": "packages/engine"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/Provable-Games/super-death-mountain/tree/main/packages/engine",
|
|
13
|
+
"publishConfig": {
|
|
14
|
+
"access": "public"
|
|
15
|
+
},
|
|
16
|
+
"sideEffects": false,
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"default": "./dist/index.js"
|
|
21
|
+
},
|
|
22
|
+
"./*": {
|
|
23
|
+
"types": "./dist/*.d.ts",
|
|
24
|
+
"default": "./dist/*.js"
|
|
25
|
+
},
|
|
26
|
+
"./*.js": {
|
|
27
|
+
"types": "./dist/*.d.ts",
|
|
28
|
+
"default": "./dist/*.js"
|
|
29
|
+
},
|
|
30
|
+
"./package.json": "./package.json"
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist"
|
|
34
|
+
],
|
|
35
|
+
"scripts": {
|
|
36
|
+
"prepare": "pnpm run build",
|
|
37
|
+
"build": "tsc -p tsconfig.build.json",
|
|
38
|
+
"typecheck": "tsc --noEmit",
|
|
39
|
+
"test": "vitest run",
|
|
40
|
+
"test:watch": "vitest"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@scure/starknet": "^1.1.0",
|
|
44
|
+
"starknet": "^7.1.0"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/node": "^22.0.0",
|
|
48
|
+
"typescript": "^5.7.0",
|
|
49
|
+
"vitest": "^3.1.1"
|
|
50
|
+
}
|
|
51
|
+
}
|