@peeramid-labs/sdk 3.7.3 → 3.8.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/cli/abis/MAODistribution.js +10 -0
- package/cli/abis/MAODistribution.js.map +1 -1
- package/cli/abis/RankToken.js +84 -0
- package/cli/abis/RankToken.js.map +1 -1
- package/cli/abis/superinterface.js +9 -3
- package/cli/abis/superinterface.js.map +1 -1
- package/cli/cli/commands/blockchain/index.js +9 -0
- package/cli/cli/commands/blockchain/index.js.map +1 -0
- package/cli/cli/commands/blockchain/mine.js +45 -0
- package/cli/cli/commands/blockchain/mine.js.map +1 -0
- package/cli/cli/commands/distributions/add.js +57 -31
- package/cli/cli/commands/distributions/add.js.map +1 -1
- package/cli/cli/commands/distributions/index.js +3 -1
- package/cli/cli/commands/distributions/index.js.map +1 -1
- package/cli/cli/commands/distributions/remove.js +67 -0
- package/cli/cli/commands/distributions/remove.js.map +1 -0
- package/cli/cli/commands/fellowship/create.js +97 -54
- package/cli/cli/commands/fellowship/create.js.map +1 -1
- package/cli/cli/commands/fellowship/game/cancel.js +45 -0
- package/cli/cli/commands/fellowship/game/cancel.js.map +1 -0
- package/cli/cli/commands/fellowship/game/create.js +91 -0
- package/cli/cli/commands/fellowship/game/create.js.map +1 -0
- package/cli/cli/commands/fellowship/game/end-turn.js +43 -0
- package/cli/cli/commands/fellowship/game/end-turn.js.map +1 -0
- package/cli/cli/commands/fellowship/game/index.js +31 -0
- package/cli/cli/commands/fellowship/game/index.js.map +1 -0
- package/cli/cli/commands/fellowship/game/join.js +131 -0
- package/cli/cli/commands/fellowship/game/join.js.map +1 -0
- package/cli/cli/commands/fellowship/{games.js → game/list.js} +6 -6
- package/cli/cli/commands/fellowship/game/list.js.map +1 -0
- package/cli/cli/commands/fellowship/game/propose.js +178 -0
- package/cli/cli/commands/fellowship/game/propose.js.map +1 -0
- package/cli/cli/commands/fellowship/game/start.js +117 -0
- package/cli/cli/commands/fellowship/game/start.js.map +1 -0
- package/cli/cli/commands/fellowship/game/vote.js +114 -0
- package/cli/cli/commands/fellowship/game/vote.js.map +1 -0
- package/cli/cli/commands/fellowship/index.js +4 -2
- package/cli/cli/commands/fellowship/index.js.map +1 -1
- package/cli/cli/commands/fellowship/params.js +49 -0
- package/cli/cli/commands/fellowship/params.js.map +1 -0
- package/cli/cli/commands/getPk.js +48 -0
- package/cli/cli/commands/getPk.js.map +1 -0
- package/cli/cli/commands/playbook.js +92 -0
- package/cli/cli/commands/playbook.js.map +1 -0
- package/cli/cli/getPk.js +62 -0
- package/cli/cli/getPk.js.map +1 -0
- package/cli/cli/helpers.js +64 -0
- package/cli/cli/helpers.js.map +1 -0
- package/cli/cli/index.js +6 -0
- package/cli/cli/index.js.map +1 -1
- package/cli/cli/utils.js +64 -0
- package/cli/cli/utils.js.map +1 -0
- package/cli/rankify/GameMaster.js +1066 -0
- package/cli/rankify/GameMaster.js.map +1 -0
- package/cli/rankify/InstanceBase.js +61 -36
- package/cli/rankify/InstanceBase.js.map +1 -1
- package/cli/rankify/MAODistributor.js +28 -0
- package/cli/rankify/MAODistributor.js.map +1 -1
- package/cli/rankify/Player.js +355 -0
- package/cli/rankify/Player.js.map +1 -0
- package/cli/utils/ApiError.js +11 -6
- package/cli/utils/ApiError.js.map +1 -1
- package/cli/utils/blockchain.js +62 -0
- package/cli/utils/blockchain.js.map +1 -0
- package/docs/classes/GameMaster.md +23 -63
- package/docs/classes/InstanceBase.md +23 -29
- package/docs/classes/InstancePlayer.md +27 -33
- package/docs/classes/MAODistributorClient.md +18 -1
- package/docs/docs/classes/GameMaster.md +23 -63
- package/docs/docs/classes/InstanceBase.md +23 -29
- package/docs/docs/classes/InstancePlayer.md +27 -33
- package/docs/docs/classes/MAODistributorClient.md +18 -1
- package/docs/docs/index.md +4 -4
- package/docs/index.md +4 -4
- package/lib.commonjs/abis/MAODistribution.d.ts +8 -0
- package/lib.commonjs/abis/MAODistribution.d.ts.map +1 -1
- package/lib.commonjs/abis/MAODistribution.js +10 -0
- package/lib.commonjs/abis/MAODistribution.js.map +1 -1
- package/lib.commonjs/abis/RankToken.d.ts +65 -0
- package/lib.commonjs/abis/RankToken.d.ts.map +1 -1
- package/lib.commonjs/abis/RankToken.js +84 -0
- package/lib.commonjs/abis/RankToken.js.map +1 -1
- package/lib.commonjs/abis/index.d.ts +74 -1
- package/lib.commonjs/abis/index.d.ts.map +1 -1
- package/lib.commonjs/abis/superinterface.d.ts +1 -1
- package/lib.commonjs/abis/superinterface.d.ts.map +1 -1
- package/lib.commonjs/abis/superinterface.js +9 -3
- package/lib.commonjs/abis/superinterface.js.map +1 -1
- package/lib.commonjs/multipass/MultipassBase.d.ts.map +1 -1
- package/lib.commonjs/multipass/Registrar.d.ts.map +1 -1
- package/lib.commonjs/rankify/GameMaster.d.ts +27 -34
- package/lib.commonjs/rankify/GameMaster.d.ts.map +1 -1
- package/lib.commonjs/rankify/GameMaster.js +218 -217
- package/lib.commonjs/rankify/GameMaster.js.map +1 -1
- package/lib.commonjs/rankify/InstanceBase.d.ts +65 -51
- package/lib.commonjs/rankify/InstanceBase.d.ts.map +1 -1
- package/lib.commonjs/rankify/InstanceBase.js +61 -36
- package/lib.commonjs/rankify/InstanceBase.js.map +1 -1
- package/lib.commonjs/rankify/MAODistributor.d.ts +1036 -0
- package/lib.commonjs/rankify/MAODistributor.d.ts.map +1 -1
- package/lib.commonjs/rankify/MAODistributor.js +28 -0
- package/lib.commonjs/rankify/MAODistributor.js.map +1 -1
- package/lib.commonjs/rankify/Player.d.ts.map +1 -1
- package/lib.commonjs/rankify/RankToken.d.ts.map +1 -1
- package/lib.commonjs/utils/ApiError.d.ts.map +1 -1
- package/lib.commonjs/utils/ApiError.js +11 -6
- package/lib.commonjs/utils/ApiError.js.map +1 -1
- package/lib.commonjs/utils/artifacts.d.ts.map +1 -1
- package/lib.commonjs/utils/blockchain.d.ts +32 -0
- package/lib.commonjs/utils/blockchain.d.ts.map +1 -0
- package/lib.commonjs/utils/blockchain.js +62 -0
- package/lib.commonjs/utils/blockchain.js.map +1 -0
- package/lib.commonjs/utils/index.d.ts.map +1 -1
- package/lib.commonjs/utils/permutations.d.ts.map +1 -1
- package/lib.esm/abis/MAODistribution.d.ts +8 -0
- package/lib.esm/abis/MAODistribution.d.ts.map +1 -1
- package/lib.esm/abis/MAODistribution.js +10 -0
- package/lib.esm/abis/MAODistribution.js.map +1 -1
- package/lib.esm/abis/RankToken.d.ts +65 -0
- package/lib.esm/abis/RankToken.d.ts.map +1 -1
- package/lib.esm/abis/RankToken.js +84 -0
- package/lib.esm/abis/RankToken.js.map +1 -1
- package/lib.esm/abis/index.d.ts +74 -1
- package/lib.esm/abis/index.d.ts.map +1 -1
- package/lib.esm/abis/superinterface.d.ts +1 -1
- package/lib.esm/abis/superinterface.d.ts.map +1 -1
- package/lib.esm/abis/superinterface.js +9 -3
- package/lib.esm/abis/superinterface.js.map +1 -1
- package/lib.esm/multipass/MultipassBase.d.ts.map +1 -1
- package/lib.esm/multipass/Registrar.d.ts.map +1 -1
- package/lib.esm/rankify/GameMaster.d.ts +27 -34
- package/lib.esm/rankify/GameMaster.d.ts.map +1 -1
- package/lib.esm/rankify/GameMaster.js +219 -218
- package/lib.esm/rankify/GameMaster.js.map +1 -1
- package/lib.esm/rankify/InstanceBase.d.ts +65 -51
- package/lib.esm/rankify/InstanceBase.d.ts.map +1 -1
- package/lib.esm/rankify/InstanceBase.js +61 -36
- package/lib.esm/rankify/InstanceBase.js.map +1 -1
- package/lib.esm/rankify/MAODistributor.d.ts +1036 -0
- package/lib.esm/rankify/MAODistributor.d.ts.map +1 -1
- package/lib.esm/rankify/MAODistributor.js +28 -0
- package/lib.esm/rankify/MAODistributor.js.map +1 -1
- package/lib.esm/rankify/Player.d.ts.map +1 -1
- package/lib.esm/rankify/RankToken.d.ts.map +1 -1
- package/lib.esm/utils/ApiError.d.ts.map +1 -1
- package/lib.esm/utils/ApiError.js +11 -6
- package/lib.esm/utils/ApiError.js.map +1 -1
- package/lib.esm/utils/artifacts.d.ts.map +1 -1
- package/lib.esm/utils/blockchain.d.ts +32 -0
- package/lib.esm/utils/blockchain.d.ts.map +1 -0
- package/lib.esm/utils/blockchain.js +58 -0
- package/lib.esm/utils/blockchain.js.map +1 -0
- package/lib.esm/utils/index.d.ts.map +1 -1
- package/lib.esm/utils/permutations.d.ts.map +1 -1
- package/package.json +8 -8
- package/zk_artifacts/circuits/proposals_integrity_15.circom/ProposalsIntegrity15.groth16.vkey.json +1 -0
- package/zk_artifacts/circuits/proposals_integrity_15.circom/ProposalsIntegrity15.groth16.zkey +0 -0
- package/zk_artifacts/circuits/proposals_integrity_15.circom/ProposalsIntegrity15.r1cs +0 -0
- package/zk_artifacts/circuits/proposals_integrity_15.circom/ProposalsIntegrity15.sym +19202 -0
- package/zk_artifacts/circuits/proposals_integrity_15.circom/ProposalsIntegrity15_artifacts.json +84 -0
- package/zk_artifacts/circuits/proposals_integrity_15.circom/ProposalsIntegrity15_js/ProposalsIntegrity15.wasm +0 -0
- package/zk_artifacts/circuits/proposals_integrity_15.circom/ProposalsIntegrity15_js/generate_witness.js +21 -0
- package/zk_artifacts/circuits/proposals_integrity_15.circom/ProposalsIntegrity15_js/witness_calculator.js +384 -0
- package/zk_artifacts/types/core/ProposalsIntegrity15.ts +163 -0
- package/zk_artifacts/types/core/index.ts +6 -0
- package/zk_artifacts/types/hardhat.d.ts +14 -0
- package/zk_artifacts/types/helpers.ts +44 -0
- package/zk_artifacts/types/index.ts +8 -0
- package/zk_artifacts/zk_artifacts/circuits/proposals_integrity_15.circom/ProposalsIntegrity15.groth16.vkey.json +1 -0
- package/zk_artifacts/zk_artifacts/circuits/proposals_integrity_15.circom/ProposalsIntegrity15.groth16.zkey +0 -0
- package/zk_artifacts/zk_artifacts/circuits/proposals_integrity_15.circom/ProposalsIntegrity15.r1cs +0 -0
- package/zk_artifacts/zk_artifacts/circuits/proposals_integrity_15.circom/ProposalsIntegrity15.sym +19202 -0
- package/zk_artifacts/zk_artifacts/circuits/proposals_integrity_15.circom/ProposalsIntegrity15_artifacts.json +84 -0
- package/zk_artifacts/zk_artifacts/circuits/proposals_integrity_15.circom/ProposalsIntegrity15_js/ProposalsIntegrity15.wasm +0 -0
- package/zk_artifacts/zk_artifacts/circuits/proposals_integrity_15.circom/ProposalsIntegrity15_js/generate_witness.js +21 -0
- package/zk_artifacts/zk_artifacts/circuits/proposals_integrity_15.circom/ProposalsIntegrity15_js/witness_calculator.js +384 -0
- package/zk_artifacts/zk_artifacts/types/core/ProposalsIntegrity15.ts +163 -0
- package/zk_artifacts/zk_artifacts/types/core/index.ts +6 -0
- package/zk_artifacts/zk_artifacts/types/hardhat.d.ts +14 -0
- package/zk_artifacts/zk_artifacts/types/helpers.ts +44 -0
- package/zk_artifacts/zk_artifacts/types/index.ts +8 -0
- package/cli/cli/commands/fellowship/games.js.map +0 -1
|
@@ -26,6 +26,7 @@ class GameMaster {
|
|
|
26
26
|
walletClient;
|
|
27
27
|
publicClient;
|
|
28
28
|
chainId;
|
|
29
|
+
maxSlotSizeForProofs = 15;
|
|
29
30
|
/**
|
|
30
31
|
* Creates a new GameMaster instance
|
|
31
32
|
|
|
@@ -74,37 +75,50 @@ class GameMaster {
|
|
|
74
75
|
* @param proposer - Optional proposer address to filter proposals
|
|
75
76
|
* @returns Array of decrypted proposals with proposer addresses
|
|
76
77
|
*/
|
|
77
|
-
decryptProposals = async ({ instanceAddress, gameId, turn,
|
|
78
|
-
|
|
78
|
+
decryptProposals = async ({ instanceAddress, gameId, turn, players, padToMaxSize = false, permute = false, }) => {
|
|
79
|
+
(0, log_1.logger)(`Getting proposals for instance ${instanceAddress}, game ${gameId}, turn ${turn.toString()}`);
|
|
80
|
+
const ProposalSubmittedEvents = await this.publicClient.getContractEvents({
|
|
79
81
|
abi: abis_1.RankifyDiamondInstanceAbi,
|
|
80
82
|
address: instanceAddress,
|
|
81
83
|
eventName: "ProposalSubmitted",
|
|
82
|
-
args: { gameId: gameId, turn: turn
|
|
84
|
+
args: { gameId: gameId, turn: turn },
|
|
83
85
|
fromBlock: 0n,
|
|
84
86
|
});
|
|
87
|
+
(0, log_1.logger)(`Found ${ProposalSubmittedEvents.length} proposals`);
|
|
85
88
|
const instance = new InstanceBase_1.default({ instanceAddress, publicClient: this.publicClient, chainId: this.chainId });
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
89
|
+
(0, log_1.logger)(`Decrypting ${ProposalSubmittedEvents.length} proposals`);
|
|
90
|
+
const proposalsForPlayers = await Promise.all((players)?.map(async (player) => {
|
|
91
|
+
const log = ProposalSubmittedEvents.find((log) => log.args.proposer === player);
|
|
92
|
+
if (!log) {
|
|
93
|
+
return {
|
|
94
|
+
proposer: player,
|
|
95
|
+
proposal: "",
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
(0, log_1.logger)(`Decrypting proposal ${log.args.proposer}`);
|
|
100
|
+
if (!log.args.proposer)
|
|
101
|
+
throw new Error("No proposer");
|
|
102
|
+
if (!log.args.encryptedProposal)
|
|
103
|
+
throw new Error("No proposalEncryptedByGM");
|
|
104
|
+
return {
|
|
102
105
|
proposer: log.args.proposer,
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
+
proposal: await this.decryptProposal({
|
|
107
|
+
proposal: log.args.encryptedProposal,
|
|
108
|
+
turn: turn,
|
|
109
|
+
instanceAddress: instanceAddress,
|
|
110
|
+
gameId: gameId,
|
|
111
|
+
proposer: log.args.proposer,
|
|
112
|
+
instance,
|
|
113
|
+
}),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
106
116
|
}));
|
|
107
|
-
|
|
117
|
+
if (permute) {
|
|
118
|
+
const proposalsPermuted = await this.permuteArray({ array: proposalsForPlayers, gameId, turn, verifierAddress: instanceAddress });
|
|
119
|
+
return padToMaxSize ? this.padProposalsArrayWithZeroAddress(proposalsPermuted) : proposalsPermuted;
|
|
120
|
+
}
|
|
121
|
+
return padToMaxSize ? this.padProposalsArrayWithZeroAddress(proposalsForPlayers) : proposalsForPlayers;
|
|
108
122
|
};
|
|
109
123
|
/**
|
|
110
124
|
* Generates a deterministic permutation for a specific game turn
|
|
@@ -115,11 +129,10 @@ class GameMaster {
|
|
|
115
129
|
* @returns The generated permutation, secret, and commitment
|
|
116
130
|
*/
|
|
117
131
|
getPermutation = async ({ gameId, turn, size, verifierAddress, }) => {
|
|
118
|
-
const maxSize = 15;
|
|
119
132
|
const turnSalt = await this.getTurnSalt({ gameId, turn, verifierAddress });
|
|
120
133
|
// Create deterministic seed from game parameters and GM's signature
|
|
121
134
|
// Use the seed to generate permutation
|
|
122
|
-
const permutation = Array.from({ length:
|
|
135
|
+
const permutation = Array.from({ length: this.maxSlotSizeForProofs }, (_, i) => i);
|
|
123
136
|
// Fisher-Yates shuffle with deterministic randomness
|
|
124
137
|
for (let i = size - 1; i >= 0; i--) {
|
|
125
138
|
// Generate deterministic random number for this position
|
|
@@ -130,7 +143,7 @@ class GameMaster {
|
|
|
130
143
|
[permutation[i], permutation[j]] = [permutation[j], permutation[i]];
|
|
131
144
|
}
|
|
132
145
|
// Ensure inactive slots map to themselves
|
|
133
|
-
for (let i = size; i <
|
|
146
|
+
for (let i = size; i < this.maxSlotSizeForProofs; i++) {
|
|
134
147
|
permutation[i] = i;
|
|
135
148
|
}
|
|
136
149
|
return { permutation, turnSalt };
|
|
@@ -155,7 +168,7 @@ class GameMaster {
|
|
|
155
168
|
const commitment = BigInt(poseidon.F.toObject(poseidon([PoseidonThird, turnSalt])));
|
|
156
169
|
return {
|
|
157
170
|
permutation,
|
|
158
|
-
|
|
171
|
+
turnSalt,
|
|
159
172
|
commitment,
|
|
160
173
|
};
|
|
161
174
|
};
|
|
@@ -224,58 +237,11 @@ class GameMaster {
|
|
|
224
237
|
verifierAddress,
|
|
225
238
|
size,
|
|
226
239
|
}).then((perm) => {
|
|
227
|
-
return (0, viem_1.keccak256)((0, viem_1.encodePacked)(["address", "uint256"], [player, perm.
|
|
240
|
+
return (0, viem_1.keccak256)((0, viem_1.encodePacked)(["address", "uint256"], [player, perm.turnSalt]));
|
|
228
241
|
});
|
|
229
242
|
(0, log_1.logger)(`Generated vote salt for player ${player}`);
|
|
230
243
|
return result;
|
|
231
244
|
};
|
|
232
|
-
getProposalsVotedUpon = async ({ instanceAddress, gameId, turn, }) => {
|
|
233
|
-
const oldProposals = [];
|
|
234
|
-
//Proposals sequence is directly corresponding to proposers sequence
|
|
235
|
-
if (turn != 1n) {
|
|
236
|
-
const endedEvents = await this.publicClient.getContractEvents({
|
|
237
|
-
address: instanceAddress,
|
|
238
|
-
abi: abis_1.RankifyDiamondInstanceAbi,
|
|
239
|
-
eventName: "TurnEnded",
|
|
240
|
-
args: { gameId, turn: turn - 1n },
|
|
241
|
-
fromBlock: 0n,
|
|
242
|
-
});
|
|
243
|
-
const evt = endedEvents[0];
|
|
244
|
-
if (endedEvents.length > 1)
|
|
245
|
-
throw new Error("Multiple turns ended");
|
|
246
|
-
const args = evt.args;
|
|
247
|
-
const decryptedProposals = await this.decryptProposals({ instanceAddress, gameId, turn: turn - 1n });
|
|
248
|
-
if (args.newProposals) {
|
|
249
|
-
args.newProposals.slice(0, args?.players?.length).forEach((proposal, idx) => {
|
|
250
|
-
if (proposal !== "") {
|
|
251
|
-
const proposer = decryptedProposals.find((p) => p.proposal === proposal)?.proposer;
|
|
252
|
-
if (!proposer)
|
|
253
|
-
throw new Error("No proposer found for proposal");
|
|
254
|
-
oldProposals[idx] = {
|
|
255
|
-
proposer,
|
|
256
|
-
proposal: proposal,
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
|
-
else {
|
|
262
|
-
const _players = await this.publicClient.readContract({
|
|
263
|
-
address: instanceAddress,
|
|
264
|
-
abi: abis_1.RankifyDiamondInstanceAbi,
|
|
265
|
-
functionName: "getPlayers",
|
|
266
|
-
args: [gameId],
|
|
267
|
-
});
|
|
268
|
-
// Boundary case if no-one proposed a thing
|
|
269
|
-
_players.forEach((p, idx) => {
|
|
270
|
-
oldProposals[idx] = {
|
|
271
|
-
proposer: p,
|
|
272
|
-
proposal: "",
|
|
273
|
-
};
|
|
274
|
-
});
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
return oldProposals;
|
|
278
|
-
};
|
|
279
245
|
/**
|
|
280
246
|
* Finds the index of a player's ongoing proposal
|
|
281
247
|
* @param gameId - ID of the game
|
|
@@ -283,31 +249,17 @@ class GameMaster {
|
|
|
283
249
|
* @returns Index of the player's proposal, -1 if not found
|
|
284
250
|
*/
|
|
285
251
|
findPlayerOngoingProposalIndex = async ({ instanceAddress, gameId, player, turn, }) => {
|
|
286
|
-
const baseInstance = new InstanceBase_1.default({ instanceAddress, publicClient: this.publicClient, chainId: this.chainId });
|
|
287
|
-
let currentTurn = 0n;
|
|
288
252
|
if (!turn) {
|
|
289
|
-
|
|
290
|
-
currentTurn = r.currentTurn;
|
|
291
|
-
if (currentTurn == 0n) {
|
|
292
|
-
console.error("No proposals in turn 0");
|
|
293
|
-
return -1;
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
else {
|
|
297
|
-
currentTurn = turn;
|
|
253
|
+
turn = await this.currentTurn({ instanceAddress, gameId });
|
|
298
254
|
}
|
|
299
|
-
const
|
|
300
|
-
|
|
255
|
+
const players = await this.getPlayers({ instanceAddress, gameId });
|
|
256
|
+
const decryptedProposalsPermuted = await this.decryptProposals({ instanceAddress, gameId, turn: turn - 1n, players: [...players], permute: true });
|
|
257
|
+
return decryptedProposalsPermuted.findIndex((p) => p?.proposer === player);
|
|
301
258
|
};
|
|
302
259
|
validateJoinGame = async (props) => {
|
|
303
260
|
const { gameId, participant, instanceAddress } = props;
|
|
304
261
|
try {
|
|
305
|
-
const
|
|
306
|
-
instanceAddress,
|
|
307
|
-
publicClient: this.publicClient,
|
|
308
|
-
chainId: this.chainId,
|
|
309
|
-
});
|
|
310
|
-
const gameState = await baseInstance.getGameStateDetails(gameId);
|
|
262
|
+
const gameState = await this.getGameState({ gameId, instanceAddress });
|
|
311
263
|
if (gameState.gamePhase !== types_1.gameStatusEnum.open) {
|
|
312
264
|
return { result: false, errorMessage: "Game is not open for registration" };
|
|
313
265
|
}
|
|
@@ -335,6 +287,10 @@ class GameMaster {
|
|
|
335
287
|
throw new Error("No account");
|
|
336
288
|
(0, log_1.logger)(`Signing joining game..`);
|
|
337
289
|
const { gameId, participant, instanceAddress, participantPubKeyHash } = props;
|
|
290
|
+
const { result: isValid, errorMessage } = await this.validateJoinGame({ gameId, participant, instanceAddress });
|
|
291
|
+
if (!isValid) {
|
|
292
|
+
throw new Error(errorMessage);
|
|
293
|
+
}
|
|
338
294
|
const baseInstance = new InstanceBase_1.default({ instanceAddress, publicClient: this.publicClient, chainId: this.chainId });
|
|
339
295
|
const eip712 = await baseInstance.getEIP712Domain();
|
|
340
296
|
(0, log_1.logger)({
|
|
@@ -398,19 +354,12 @@ class GameMaster {
|
|
|
398
354
|
* @returns Transaction hash
|
|
399
355
|
*/
|
|
400
356
|
submitVote = async ({ instanceAddress, gameId, vote, voter, voterSignature, ballotHash, ballotId, }) => {
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
const proposerIdx = await this.findPlayerOngoingProposalIndex({ instanceAddress, gameId, player: voter });
|
|
408
|
-
if (proposerIdx == -1)
|
|
409
|
-
throw new Error("You are not a proposer in this game");
|
|
410
|
-
if (vote[proposerIdx] !== 0n)
|
|
411
|
-
throw new Error("You cannot vote for your own proposal");
|
|
412
|
-
if (!this.walletClient?.account?.address)
|
|
413
|
-
throw new Error("No account address found");
|
|
357
|
+
const players = await this.getPlayers({ instanceAddress, gameId });
|
|
358
|
+
const turn = await this.currentTurn({ instanceAddress, gameId });
|
|
359
|
+
const validationResult = await this.validateVote({ gameId, turn, voter, vote, instanceAddress, players: [...players] });
|
|
360
|
+
if (!validationResult.result) {
|
|
361
|
+
throw new Error('Vote validation failed: ' + validationResult.reason);
|
|
362
|
+
}
|
|
414
363
|
try {
|
|
415
364
|
const { request } = await this.publicClient.simulateContract({
|
|
416
365
|
account: this.walletClient.account,
|
|
@@ -425,6 +374,84 @@ class GameMaster {
|
|
|
425
374
|
throw await (0, utils_1.handleRPCError)(e);
|
|
426
375
|
}
|
|
427
376
|
};
|
|
377
|
+
/**
|
|
378
|
+
* Gets the current turn progress in percent value
|
|
379
|
+
* @param instanceAddress - Address of the instance
|
|
380
|
+
* @param gameState - Current game state
|
|
381
|
+
* @param gameId - ID of the game
|
|
382
|
+
* @returns Current turn progress
|
|
383
|
+
*/
|
|
384
|
+
getTurnProgress = async ({ instanceAddress, gameState, gameId }) => {
|
|
385
|
+
const prevTurnProposals = await this.decryptProposals({ instanceAddress, gameId, turn: gameState.currentTurn - 1n, players: [...gameState.players] });
|
|
386
|
+
const proposalCountInPrevTurn = prevTurnProposals.filter(p => p.proposal !== "").length;
|
|
387
|
+
const proposalsMadeInCurrentTurn = await this.decryptProposals({ instanceAddress, gameId, turn: gameState.currentTurn, players: [...gameState.players] });
|
|
388
|
+
const proposalCountInCurrentTurn = proposalsMadeInCurrentTurn.filter(p => p.proposal !== "").length;
|
|
389
|
+
if (proposalCountInPrevTurn === 0) {
|
|
390
|
+
return (proposalCountInCurrentTurn / gameState.players.length) * 100;
|
|
391
|
+
}
|
|
392
|
+
else {
|
|
393
|
+
const votesMadeInCurrentTurn = await this.decryptTurnVotes({ instanceAddress, gameId, turn: gameState.currentTurn, players: [...gameState.players] });
|
|
394
|
+
const votesCount = votesMadeInCurrentTurn.filter(v => this.hasVoted({ vote: v })).length;
|
|
395
|
+
return ((votesCount + proposalCountInCurrentTurn) / (gameState.players.length * 2)) * 100;
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
hasVoted({ vote }) {
|
|
399
|
+
return vote?.reduce((a, b) => a + b, 0n) !== 0n;
|
|
400
|
+
}
|
|
401
|
+
;
|
|
402
|
+
validateVote = async ({ gameId, turn, voter, vote, instanceAddress, players }) => {
|
|
403
|
+
const decryptedProposals = await this.decryptProposals({ instanceAddress, gameId, turn: turn - 1n, players, permute: true });
|
|
404
|
+
//Invalid vote length
|
|
405
|
+
if (vote.length !== decryptedProposals.length) {
|
|
406
|
+
return { result: false, reason: "Invalid vote length" };
|
|
407
|
+
}
|
|
408
|
+
// Check if points used are correct (Quadratic voting system)
|
|
409
|
+
let pointsUsed = 0n;
|
|
410
|
+
for (let i = 0; i < vote.length; i++) {
|
|
411
|
+
if (vote[i] > 0n) {
|
|
412
|
+
pointsUsed += 1n ** vote[i];
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
const gameState = await this.getGameState({ gameId, instanceAddress });
|
|
416
|
+
if (pointsUsed > gameState.voteCredits) {
|
|
417
|
+
return { result: false, reason: "Too many points used" };
|
|
418
|
+
}
|
|
419
|
+
if (pointsUsed < gameState.voteCredits) {
|
|
420
|
+
return { result: false, reason: "Not all points used" };
|
|
421
|
+
}
|
|
422
|
+
// Check if voter voted for a non-proposed player or their own proposal
|
|
423
|
+
for (let i = 0; i < vote.length; i++) {
|
|
424
|
+
if (vote[i] === 0n)
|
|
425
|
+
continue;
|
|
426
|
+
if (decryptedProposals[i].proposal === "" || decryptedProposals[i].proposer === viem_1.zeroAddress) {
|
|
427
|
+
return { result: false, reason: "Vote for non existing proposal" };
|
|
428
|
+
}
|
|
429
|
+
if (decryptedProposals[i].proposer === voter) {
|
|
430
|
+
return { result: false, reason: "Voter cannot vote for their own proposal" };
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
// Valid vote
|
|
434
|
+
return { result: true, reason: "" };
|
|
435
|
+
};
|
|
436
|
+
getGameState({ gameId, instanceAddress }) {
|
|
437
|
+
const baseInstance = new InstanceBase_1.default({
|
|
438
|
+
instanceAddress,
|
|
439
|
+
publicClient: this.publicClient,
|
|
440
|
+
chainId: this.chainId,
|
|
441
|
+
});
|
|
442
|
+
return baseInstance.getGameStateDetails(gameId);
|
|
443
|
+
}
|
|
444
|
+
padProposalsArrayWithZeroAddress = (proposals) => {
|
|
445
|
+
if (proposals.length < this.maxSlotSizeForProofs) {
|
|
446
|
+
for (let i = proposals.length; i < this.maxSlotSizeForProofs; i++) {
|
|
447
|
+
proposals.push({
|
|
448
|
+
proposer: viem_1.zeroAddress,
|
|
449
|
+
proposal: "",
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
return proposals;
|
|
454
|
+
};
|
|
428
455
|
/**
|
|
429
456
|
* Types for proposal submission
|
|
430
457
|
*/
|
|
@@ -567,8 +594,6 @@ class GameMaster {
|
|
|
567
594
|
* @returns Transaction hash
|
|
568
595
|
*/
|
|
569
596
|
submitProposal = async ({ instanceAddress, submissionParams, proposerSignature, }) => {
|
|
570
|
-
// let proposalData: GetAbiItemParameters<typeof RankifyDiamondInstanceAbi, "submitProposal">["args"];
|
|
571
|
-
// proposalData[0].
|
|
572
597
|
const txParams = [
|
|
573
598
|
{
|
|
574
599
|
...submissionParams,
|
|
@@ -595,19 +620,23 @@ class GameMaster {
|
|
|
595
620
|
* @param turn - Turn number
|
|
596
621
|
* @returns Array of decrypted votes with player addresses
|
|
597
622
|
*/
|
|
598
|
-
decryptTurnVotes = async ({ instanceAddress, gameId, turn, }) => {
|
|
599
|
-
|
|
623
|
+
decryptTurnVotes = async ({ instanceAddress, gameId, turn, players = [], }) => {
|
|
624
|
+
(0, log_1.logger)(`Decrypting votes for game ${BigInt(gameId)} turn ${turn} at address ${instanceAddress} at ${await this.publicClient.getBlockNumber()} block`);
|
|
625
|
+
const VoteSubmittedEvents = await this.publicClient.getContractEvents({
|
|
600
626
|
address: instanceAddress,
|
|
601
627
|
abi: abis_1.RankifyDiamondInstanceAbi,
|
|
602
628
|
eventName: "VoteSubmitted",
|
|
603
|
-
|
|
629
|
+
fromBlock: 0n,
|
|
630
|
+
args: { turn, gameId },
|
|
604
631
|
});
|
|
605
|
-
(0, log_1.logger)(`Found ${
|
|
606
|
-
if (
|
|
632
|
+
(0, log_1.logger)(`Found ${VoteSubmittedEvents.length} events`);
|
|
633
|
+
if (VoteSubmittedEvents.length === 0)
|
|
607
634
|
return [];
|
|
608
|
-
//
|
|
635
|
+
//Decrypting votes from events
|
|
609
636
|
const votes = [];
|
|
610
|
-
|
|
637
|
+
console.log("Events:", VoteSubmittedEvents);
|
|
638
|
+
for (const event of VoteSubmittedEvents) {
|
|
639
|
+
console.log("Event:", event);
|
|
611
640
|
if (!event.args.player)
|
|
612
641
|
throw new Error("No player in event");
|
|
613
642
|
if (!event.args.sealedBallotId)
|
|
@@ -624,26 +653,13 @@ class GameMaster {
|
|
|
624
653
|
votes: decryptedVotes,
|
|
625
654
|
});
|
|
626
655
|
}
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
decryptVotes = async ({ instanceAddress, gameId }) => {
|
|
635
|
-
const currentTurn = await this.publicClient.readContract({
|
|
636
|
-
address: instanceAddress,
|
|
637
|
-
abi: abis_1.RankifyDiamondInstanceAbi,
|
|
638
|
-
functionName: "getTurn",
|
|
639
|
-
args: [gameId],
|
|
640
|
-
});
|
|
641
|
-
if (currentTurn === 0n) {
|
|
642
|
-
console.error("No proposals in turn 0");
|
|
643
|
-
return -1;
|
|
644
|
-
}
|
|
645
|
-
const votes = await this.decryptTurnVotes({ instanceAddress, gameId, turn: currentTurn });
|
|
646
|
-
return votes.length === 0 ? -1 : votes;
|
|
656
|
+
const votesForEachPlayer = await Promise.all(players.map(async (player) => {
|
|
657
|
+
const vote = votes.find((v) => v.player === player);
|
|
658
|
+
if (!vote?.votes)
|
|
659
|
+
return players.map(() => 0n);
|
|
660
|
+
return vote.votes;
|
|
661
|
+
}));
|
|
662
|
+
return votesForEachPlayer;
|
|
647
663
|
};
|
|
648
664
|
/**
|
|
649
665
|
* Checks if the current turn can be ended
|
|
@@ -651,12 +667,24 @@ class GameMaster {
|
|
|
651
667
|
* @returns Boolean indicating if turn can be ended
|
|
652
668
|
*/
|
|
653
669
|
canEndTurn = async ({ instanceAddress, gameId }) => {
|
|
654
|
-
|
|
670
|
+
const canEndTurn = await this.publicClient.readContract({
|
|
655
671
|
address: instanceAddress,
|
|
656
672
|
abi: abis_1.RankifyDiamondInstanceAbi,
|
|
657
673
|
functionName: "canEndTurn",
|
|
658
674
|
args: [gameId],
|
|
659
675
|
});
|
|
676
|
+
if (!canEndTurn)
|
|
677
|
+
return false;
|
|
678
|
+
//Extra check to not allow to end turn if current phase timeout is not passed and progress is less than 100% (probably must be fixed in contracts!)
|
|
679
|
+
// TODO: if fixed in contracts, remove this check
|
|
680
|
+
const gameState = await this.getGameState({ instanceAddress, gameId });
|
|
681
|
+
const lastBlock = await this.publicClient.getBlock({ blockNumber: BigInt(await this.publicClient.getBlockNumber()) });
|
|
682
|
+
if (gameState.currentPhaseTimeoutAt > lastBlock.timestamp) {
|
|
683
|
+
const turnProgress = await this.getTurnProgress({ instanceAddress, gameState, gameId });
|
|
684
|
+
if (turnProgress <= 100)
|
|
685
|
+
return false;
|
|
686
|
+
}
|
|
687
|
+
return true;
|
|
660
688
|
};
|
|
661
689
|
/**
|
|
662
690
|
* Gets the current turn number
|
|
@@ -700,49 +728,24 @@ class GameMaster {
|
|
|
700
728
|
* @returns Transaction hash
|
|
701
729
|
*/
|
|
702
730
|
endTurn = async ({ instanceAddress, gameId }) => {
|
|
731
|
+
(0, log_1.logger)(`Ending turn for game ${gameId}`, 2);
|
|
703
732
|
try {
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
abi: abis_1.RankifyDiamondInstanceAbi,
|
|
707
|
-
functionName: "getTurn",
|
|
708
|
-
args: [gameId],
|
|
709
|
-
});
|
|
710
|
-
const players = (await this.publicClient.readContract({
|
|
711
|
-
address: instanceAddress,
|
|
712
|
-
abi: abis_1.RankifyDiamondInstanceAbi,
|
|
713
|
-
functionName: "getPlayers",
|
|
714
|
-
args: [gameId],
|
|
715
|
-
}));
|
|
716
|
-
if (!Array.isArray(players)) {
|
|
717
|
-
throw new Error("Expected players to be an array");
|
|
733
|
+
if (!(await this.canEndTurn({ instanceAddress, gameId }))) {
|
|
734
|
+
throw new Error("Cannot end turn");
|
|
718
735
|
}
|
|
719
|
-
const
|
|
720
|
-
const
|
|
721
|
-
|
|
722
|
-
const
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
});
|
|
729
|
-
players.forEach((player) => {
|
|
730
|
-
let proposerIdx = oldProposals.findIndex((p) => player === p.proposer);
|
|
731
|
-
if (proposerIdx === -1)
|
|
732
|
-
proposerIdx = players.length; //Did not propose
|
|
733
|
-
proposerIndices.push(BigInt(proposerIdx));
|
|
734
|
-
});
|
|
735
|
-
const voteDecrypted = await this.decryptTurnVotes({ instanceAddress, gameId, turn });
|
|
736
|
-
const votes = await Promise.all(players.map(async (player) => {
|
|
737
|
-
const vote = voteDecrypted.find((v) => v.player === player);
|
|
738
|
-
if (!vote?.votes)
|
|
739
|
-
return players.map(() => 0n);
|
|
740
|
-
return vote.votes;
|
|
741
|
-
}));
|
|
736
|
+
const turn = await this.currentTurn({ instanceAddress, gameId });
|
|
737
|
+
const players = await this.getPlayers({ instanceAddress, gameId });
|
|
738
|
+
(0, log_1.logger)(`Current turn: ${turn}, Players count: ${players.length}`, 2);
|
|
739
|
+
const newPaddedDecryptedProposals = await this.decryptProposals({ instanceAddress, gameId, turn, players: [...players], padToMaxSize: true });
|
|
740
|
+
(0, log_1.logger)(`newPaddedDecryptedProposals:`);
|
|
741
|
+
(0, log_1.logger)(newPaddedDecryptedProposals);
|
|
742
|
+
const votesDecrypted = await this.decryptTurnVotes({ instanceAddress, gameId, turn, players: [...players] });
|
|
743
|
+
(0, log_1.logger)(`votesDecrypted:`);
|
|
744
|
+
(0, log_1.logger)(votesDecrypted);
|
|
742
745
|
const tableData = players.map((player, idx) => ({
|
|
743
746
|
player,
|
|
744
|
-
|
|
745
|
-
|
|
747
|
+
voted: this.hasVoted({ vote: votesDecrypted[idx] }),
|
|
748
|
+
proposal: newPaddedDecryptedProposals[idx]?.proposal.substring(0, 50) || "not-proposed",
|
|
746
749
|
}));
|
|
747
750
|
console.table(tableData);
|
|
748
751
|
const attested = await this.getProposalsIntegrity({
|
|
@@ -750,16 +753,14 @@ class GameMaster {
|
|
|
750
753
|
turn,
|
|
751
754
|
verifierAddress: instanceAddress,
|
|
752
755
|
size: players.length,
|
|
753
|
-
proposals,
|
|
756
|
+
proposals: newPaddedDecryptedProposals,
|
|
754
757
|
});
|
|
755
|
-
(0, log_1.logger)(`votes:`);
|
|
756
|
-
(0, log_1.logger)(votes);
|
|
757
758
|
const { request } = await this.publicClient.simulateContract({
|
|
758
759
|
abi: abis_1.RankifyDiamondInstanceAbi,
|
|
759
760
|
account: this.walletClient.account,
|
|
760
761
|
address: instanceAddress,
|
|
761
762
|
functionName: "endTurn",
|
|
762
|
-
args: [gameId,
|
|
763
|
+
args: [gameId, votesDecrypted, attested.newProposals, attested.prevTurnPermutation, attested.prevTurnSalt],
|
|
763
764
|
});
|
|
764
765
|
return this.walletClient.writeContract(request);
|
|
765
766
|
}
|
|
@@ -787,6 +788,8 @@ class GameMaster {
|
|
|
787
788
|
const instance = new InstanceBase_1.default({ instanceAddress, publicClient: this.publicClient, chainId: this.chainId });
|
|
788
789
|
const playerPubKey = await instance.getPlayerPubKey({ instanceAddress, gameId, player });
|
|
789
790
|
(0, log_1.logger)(`Player public key: ${playerPubKey}`, 2);
|
|
791
|
+
console.log("Player public key:", playerPubKey);
|
|
792
|
+
console.log("Game key:", await this.gameKey({ gameId, contractAddress: instanceAddress }));
|
|
790
793
|
return instance.sharedSigner({
|
|
791
794
|
publicKey: playerPubKey,
|
|
792
795
|
privateKey: await this.gameKey({ gameId, contractAddress: instanceAddress }),
|
|
@@ -819,7 +822,12 @@ class GameMaster {
|
|
|
819
822
|
*/
|
|
820
823
|
attestVote = async ({ voter, gameId, turn, vote, verifierAddress, }) => {
|
|
821
824
|
(0, log_1.logger)(`Attesting vote for player ${voter} in game ${gameId}, turn ${turn}`);
|
|
822
|
-
const
|
|
825
|
+
const players = await this.getPlayers({ instanceAddress: verifierAddress, gameId });
|
|
826
|
+
const validationResult = await this.validateVote({ gameId, turn, voter, vote, instanceAddress: verifierAddress, players: [...players] });
|
|
827
|
+
if (!validationResult.result) {
|
|
828
|
+
throw new Error('Vote validation failed: ' + validationResult.reason);
|
|
829
|
+
}
|
|
830
|
+
const gameSize = players.length;
|
|
823
831
|
const instance = new InstanceBase_1.default({
|
|
824
832
|
instanceAddress: verifierAddress,
|
|
825
833
|
publicClient: this.publicClient,
|
|
@@ -911,14 +919,14 @@ class GameMaster {
|
|
|
911
919
|
* @returns Integrity data including permutation, secret, and proof
|
|
912
920
|
*/
|
|
913
921
|
generateEndTurnIntegrity = async ({ gameId, turn, verifierAddress, size = 15, proposals, }) => {
|
|
914
|
-
|
|
915
|
-
const { permutation,
|
|
922
|
+
let _proposals = [...proposals];
|
|
923
|
+
const { permutation: prevTurnPermutation, turnSalt: prevTurnSalt } = await this.generateDeterministicPermutation({
|
|
916
924
|
gameId,
|
|
917
925
|
turn: turn - 1n,
|
|
918
926
|
verifierAddress,
|
|
919
927
|
size,
|
|
920
928
|
});
|
|
921
|
-
const values = await Promise.all(
|
|
929
|
+
const values = await Promise.all(_proposals.map((p) => p.proposal === ""
|
|
922
930
|
? {
|
|
923
931
|
proposalValue: 0n,
|
|
924
932
|
randomnessValue: 0n,
|
|
@@ -931,6 +939,8 @@ class GameMaster {
|
|
|
931
939
|
turn,
|
|
932
940
|
proposer: p.proposer,
|
|
933
941
|
})));
|
|
942
|
+
(0, log_1.logger)("proposals with added empty proposals:", 3);
|
|
943
|
+
(0, log_1.logger)(_proposals, 3);
|
|
934
944
|
const inputs = await this.createInputs({
|
|
935
945
|
numActive: size,
|
|
936
946
|
proposals: values.map((v) => v.proposalValue),
|
|
@@ -939,36 +949,26 @@ class GameMaster {
|
|
|
939
949
|
turn,
|
|
940
950
|
verifierAddress,
|
|
941
951
|
});
|
|
942
|
-
(0, log_1.logger)(inputs,
|
|
952
|
+
(0, log_1.logger)("inputs:", 3);
|
|
953
|
+
(0, log_1.logger)(inputs, 3);
|
|
943
954
|
// Apply permutation to proposals array
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
}
|
|
949
|
-
}
|
|
955
|
+
console.log("permutation used on new proposals:", inputs.permutation);
|
|
956
|
+
console.log("revealed permutation for prevTurn proposals:", prevTurnPermutation);
|
|
957
|
+
const permutedProposals = (0, permutations_1.permuteArray)({ array: _proposals, permutation: inputs.permutation });
|
|
958
|
+
console.log("permutedProposals:", permutedProposals);
|
|
950
959
|
const config = {
|
|
951
960
|
circuitName: "ProposalsIntegrity15",
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
verifierDirPath: path_1.default.join(__dirname, "../../node_modules/rankify-contracts/src/verifiers"),
|
|
961
|
+
circuitArtifactsPath: path_1.default.join(__dirname, "../../zk_artifacts/circuits/proposals_integrity_15.circom/"),
|
|
962
|
+
verifierDirPath: path_1.default.join(__dirname, "../../zk_artifacts/verifiers"),
|
|
955
963
|
};
|
|
956
964
|
const implementer = new zkit_1.Groth16Implementer();
|
|
957
965
|
const circuit = new zkit_1.CircuitZKit(config, implementer);
|
|
958
966
|
const proof = await circuit.generateProof(inputs);
|
|
967
|
+
(0, log_1.logger)("proof:", 3);
|
|
968
|
+
(0, log_1.logger)(proof, 3);
|
|
959
969
|
const callData = await circuit.generateCalldata(proof);
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
// let cached = loadFromCache(inputsKey);
|
|
963
|
-
// if (cached) {
|
|
964
|
-
// log(`Loaded proof from cache for inputsKey ${inputsKey}`, 2);
|
|
965
|
-
// } else {
|
|
966
|
-
// log(`Generating proof for inputsKey ${inputsKey}`, 2);
|
|
967
|
-
// const proof = await circuit.generateProof(inputs);
|
|
968
|
-
// saveToCache(inputsKey, proof);
|
|
969
|
-
// cached = proof;
|
|
970
|
-
// }
|
|
971
|
-
// const proof = "0x00";
|
|
970
|
+
(0, log_1.logger)("callData:", 3);
|
|
971
|
+
(0, log_1.logger)(callData, 3);
|
|
972
972
|
if (!proof) {
|
|
973
973
|
throw new Error("Proof not found");
|
|
974
974
|
}
|
|
@@ -978,8 +978,8 @@ class GameMaster {
|
|
|
978
978
|
const c = callData[2].map((c) => BigInt(c));
|
|
979
979
|
return {
|
|
980
980
|
commitment: inputs.permutationCommitment,
|
|
981
|
-
|
|
982
|
-
|
|
981
|
+
prevTurnSalt,
|
|
982
|
+
prevTurnPermutation,
|
|
983
983
|
permutedProposals: permutedProposals.map((proposal) => proposal.proposal),
|
|
984
984
|
a,
|
|
985
985
|
b,
|
|
@@ -993,7 +993,7 @@ class GameMaster {
|
|
|
993
993
|
*/
|
|
994
994
|
async getProposalsIntegrity({ size, gameId, turn, proposals, verifierAddress, }) {
|
|
995
995
|
(0, log_1.logger)(`Generating proposals integrity for game ${gameId}, turn ${turn} with ${size} players.`);
|
|
996
|
-
const { commitment,
|
|
996
|
+
const { commitment, prevTurnSalt, prevTurnPermutation, permutedProposals, a, b, c } = await this.generateEndTurnIntegrity({
|
|
997
997
|
gameId,
|
|
998
998
|
turn,
|
|
999
999
|
verifierAddress,
|
|
@@ -1009,9 +1009,9 @@ class GameMaster {
|
|
|
1009
1009
|
proposals: permutedProposals,
|
|
1010
1010
|
permutationCommitment: commitment,
|
|
1011
1011
|
},
|
|
1012
|
-
|
|
1012
|
+
prevTurnPermutation: prevTurnPermutation.map((p) => BigInt(p)),
|
|
1013
1013
|
proposalsNotPermuted: proposals.map((proposal) => proposal.proposal),
|
|
1014
|
-
|
|
1014
|
+
prevTurnSalt,
|
|
1015
1015
|
};
|
|
1016
1016
|
}
|
|
1017
1017
|
/**
|
|
@@ -1021,20 +1021,19 @@ class GameMaster {
|
|
|
1021
1021
|
*/
|
|
1022
1022
|
createInputs = async ({ numActive, proposals, commitmentRandomnesses, gameId, turn, verifierAddress, }) => {
|
|
1023
1023
|
const poseidon = await (0, circomlibjs_1.buildPoseidon)();
|
|
1024
|
-
const maxSize = 15;
|
|
1025
1024
|
// Initialize arrays with zeros
|
|
1026
|
-
const commitments = Array(
|
|
1027
|
-
const randomnesses = Array(
|
|
1028
|
-
const permutedProposals = Array(
|
|
1025
|
+
const commitments = Array(this.maxSlotSizeForProofs).fill(0n);
|
|
1026
|
+
const randomnesses = Array(this.maxSlotSizeForProofs).fill(0n);
|
|
1027
|
+
const permutedProposals = Array(this.maxSlotSizeForProofs).fill(0n);
|
|
1029
1028
|
// Generate deterministic permutation
|
|
1030
|
-
const { permutation, secret, commitment } = await this.generateDeterministicPermutation({
|
|
1029
|
+
const { permutation, turnSalt: secret, commitment } = await this.generateDeterministicPermutation({
|
|
1031
1030
|
gameId,
|
|
1032
1031
|
turn,
|
|
1033
1032
|
verifierAddress,
|
|
1034
1033
|
size: numActive,
|
|
1035
1034
|
});
|
|
1036
1035
|
// Fill arrays with values
|
|
1037
|
-
for (let i = 0; i <
|
|
1036
|
+
for (let i = 0; i < this.maxSlotSizeForProofs; i++) {
|
|
1038
1037
|
if (i < numActive) {
|
|
1039
1038
|
// Active slots
|
|
1040
1039
|
const proposal = proposals[i];
|
|
@@ -1046,6 +1045,7 @@ class GameMaster {
|
|
|
1046
1045
|
permutedProposals[permutation[i]] = proposal;
|
|
1047
1046
|
}
|
|
1048
1047
|
else {
|
|
1048
|
+
(0, log_1.logger)(`Inactive slot ${i}`, 3);
|
|
1049
1049
|
// Inactive slots
|
|
1050
1050
|
const hash = poseidon([0n, 0n]);
|
|
1051
1051
|
commitments[i] = BigInt(poseidon.F.toObject(hash));
|
|
@@ -1065,4 +1065,5 @@ class GameMaster {
|
|
|
1065
1065
|
};
|
|
1066
1066
|
}
|
|
1067
1067
|
exports.GameMaster = GameMaster;
|
|
1068
|
+
exports.default = GameMaster;
|
|
1068
1069
|
//# sourceMappingURL=GameMaster.js.map
|