bomb-panic-sdk 0.1.0 → 0.1.2
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/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/parse.d.ts +9 -0
- package/dist/parse.js +143 -0
- package/dist/read.d.ts +14 -0
- package/dist/read.js +127 -0
- package/dist/tx.d.ts +65 -0
- package/dist/tx.js +201 -0
- package/dist/types.d.ts +43 -0
- package/dist/types.js +1 -0
- package/package.json +9 -2
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
package/dist/parse.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ParsedGameState, ParsedRoom } from './types.js';
|
|
2
|
+
type MoveObjectContent = {
|
|
3
|
+
dataType?: string;
|
|
4
|
+
type?: string;
|
|
5
|
+
fields?: any;
|
|
6
|
+
};
|
|
7
|
+
export declare function parseRoom(content: MoveObjectContent | undefined): ParsedRoom | null;
|
|
8
|
+
export declare function parseGameState(content: MoveObjectContent | undefined): ParsedGameState | null;
|
|
9
|
+
export {};
|
package/dist/parse.js
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
function toBigInt(value) {
|
|
2
|
+
if (typeof value === 'bigint') {
|
|
3
|
+
return value;
|
|
4
|
+
}
|
|
5
|
+
if (typeof value === 'number') {
|
|
6
|
+
return BigInt(value);
|
|
7
|
+
}
|
|
8
|
+
if (typeof value === 'string' && value.length > 0) {
|
|
9
|
+
return BigInt(value);
|
|
10
|
+
}
|
|
11
|
+
return 0n;
|
|
12
|
+
}
|
|
13
|
+
function getObjectIdFromContent(content) {
|
|
14
|
+
if (!content || !content.fields)
|
|
15
|
+
return '';
|
|
16
|
+
return content.fields?.id?.id ?? content.fields?.id ?? '';
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Parse Move Option<T> type which can be serialized in multiple formats:
|
|
20
|
+
* - { vec: [value] } or { vec: [] } (common format)
|
|
21
|
+
* - { fields: { vec: [value] } } (nested format)
|
|
22
|
+
* - Direct value (rare edge case)
|
|
23
|
+
*
|
|
24
|
+
* Returns null if None, or the value if Some.
|
|
25
|
+
*/
|
|
26
|
+
function parseOption(optionField) {
|
|
27
|
+
if (optionField === null || optionField === undefined) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
// Handle { vec: [...] } format
|
|
31
|
+
if (typeof optionField === 'object' && 'vec' in optionField) {
|
|
32
|
+
const vec = optionField.vec;
|
|
33
|
+
if (Array.isArray(vec) && vec.length > 0) {
|
|
34
|
+
return vec[0];
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
// Handle { fields: { vec: [...] } } format
|
|
39
|
+
if (typeof optionField === 'object' && 'fields' in optionField) {
|
|
40
|
+
const fields = optionField.fields;
|
|
41
|
+
if (fields && 'vec' in fields) {
|
|
42
|
+
const vec = fields.vec;
|
|
43
|
+
if (Array.isArray(vec) && vec.length > 0) {
|
|
44
|
+
return vec[0];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
// Direct value (shouldn't happen for Option but handle defensively)
|
|
50
|
+
if (typeof optionField === 'string' && optionField.startsWith('0x')) {
|
|
51
|
+
return optionField;
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
export function parseRoom(content) {
|
|
56
|
+
if (!content || content.dataType !== 'moveObject')
|
|
57
|
+
return null;
|
|
58
|
+
const fields = content.fields ?? {};
|
|
59
|
+
const roomId = getObjectIdFromContent(content);
|
|
60
|
+
const status = fields.status?.variant ?? 'Unknown';
|
|
61
|
+
const entryFee = toBigInt(fields.entry_fee);
|
|
62
|
+
const maxPlayers = Number(fields.max_players ?? 0);
|
|
63
|
+
const playerCount = Number(fields.player_balances?.fields?.size ?? 0);
|
|
64
|
+
const poolValue = toBigInt(fields.pool?.fields?.value ?? fields.pool?.value ?? 0);
|
|
65
|
+
// Ready count: use ready_players table size
|
|
66
|
+
// The table contains all players who have called ready_to_play (value=true means ready)
|
|
67
|
+
// Since we can't iterate the table from serialized content, we use pool-based estimation
|
|
68
|
+
// When players ready, they deposit entry_fee into pool, so readyCount = poolValue / entryFee
|
|
69
|
+
// However, during Started status, pool may be drained, so we fall back to playerCount if pool is 0
|
|
70
|
+
let readyCount = 0;
|
|
71
|
+
if (status === 'Waiting' && entryFee > 0n && poolValue > 0n) {
|
|
72
|
+
readyCount = Number(poolValue / entryFee);
|
|
73
|
+
}
|
|
74
|
+
else if (status === 'Started' || status === 'Settled') {
|
|
75
|
+
// After game starts, assume all players were ready
|
|
76
|
+
readyCount = playerCount;
|
|
77
|
+
}
|
|
78
|
+
const readyTableId = fields.ready_players?.fields?.id?.id;
|
|
79
|
+
return {
|
|
80
|
+
roomId,
|
|
81
|
+
status,
|
|
82
|
+
entryFee,
|
|
83
|
+
maxPlayers,
|
|
84
|
+
playerCount,
|
|
85
|
+
poolValue,
|
|
86
|
+
readyCount,
|
|
87
|
+
readyTableId,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
export function parseGameState(content) {
|
|
91
|
+
if (!content || content.dataType !== 'moveObject')
|
|
92
|
+
return null;
|
|
93
|
+
const fields = content.fields ?? {};
|
|
94
|
+
const gameId = getObjectIdFromContent(content);
|
|
95
|
+
const phase = fields.phase?.variant ?? 'Unknown';
|
|
96
|
+
const roundId = toBigInt(fields.round_id ?? 0);
|
|
97
|
+
// Parse bomb_holder Option<address> using the helper
|
|
98
|
+
const bombHolder = parseOption(fields.bomb_holder);
|
|
99
|
+
const holderStartMs = toBigInt(fields.holder_start_ms ?? 0);
|
|
100
|
+
const roundStartMs = toBigInt(fields.round_start_ms ?? 0);
|
|
101
|
+
const poolValue = toBigInt(fields.pool_value ?? 0);
|
|
102
|
+
const entryFeePerPlayer = toBigInt(fields.entry_fee_per_player ?? 0);
|
|
103
|
+
const rewardPerSec = toBigInt(fields.reward_per_sec ?? 0);
|
|
104
|
+
const explosionRateBps = toBigInt(fields.explosion_rate_bps ?? 0);
|
|
105
|
+
const settlementConsumed = Boolean(fields.settlement_consumed);
|
|
106
|
+
const roomId = fields.room_id ?? '';
|
|
107
|
+
const rewards = new Map();
|
|
108
|
+
const holderRewards = fields.holder_rewards ?? [];
|
|
109
|
+
if (Array.isArray(holderRewards)) {
|
|
110
|
+
holderRewards.forEach((r) => {
|
|
111
|
+
const addr = r?.fields?.player ?? '';
|
|
112
|
+
if (addr)
|
|
113
|
+
rewards.set(addr, toBigInt(r?.fields?.amount ?? 0));
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
const players = Array.isArray(fields.players)
|
|
117
|
+
? fields.players.map((p) => {
|
|
118
|
+
const addr = p?.fields?.addr ?? '';
|
|
119
|
+
const reward = rewards.get(addr) ?? 0n;
|
|
120
|
+
return {
|
|
121
|
+
address: addr,
|
|
122
|
+
alive: Boolean(p?.fields?.alive),
|
|
123
|
+
reward,
|
|
124
|
+
isHolder: addr === bombHolder,
|
|
125
|
+
};
|
|
126
|
+
})
|
|
127
|
+
: [];
|
|
128
|
+
return {
|
|
129
|
+
gameId,
|
|
130
|
+
phase,
|
|
131
|
+
roundId,
|
|
132
|
+
bombHolder,
|
|
133
|
+
holderStartMs,
|
|
134
|
+
roundStartMs,
|
|
135
|
+
poolValue,
|
|
136
|
+
entryFeePerPlayer,
|
|
137
|
+
rewardPerSec,
|
|
138
|
+
explosionRateBps,
|
|
139
|
+
settlementConsumed,
|
|
140
|
+
roomId,
|
|
141
|
+
players,
|
|
142
|
+
};
|
|
143
|
+
}
|
package/dist/read.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { SuiClient } from '@onelabs/sui/client';
|
|
2
|
+
import type { SuiObjectResponse } from '@onelabs/sui/client';
|
|
3
|
+
import { ParsedGameState, ParsedRoom, RoomGamePair } from './types.js';
|
|
4
|
+
export declare function getLobbyRoomIds(client: SuiClient, lobbyId: string, limit?: number): Promise<string[]>;
|
|
5
|
+
export declare function getLobbyRoomGamePairs(client: SuiClient, lobbyId: string, limit?: number): Promise<RoomGamePair[]>;
|
|
6
|
+
export declare function getRooms(client: SuiClient, roomIds: string[]): Promise<SuiObjectResponse[]>;
|
|
7
|
+
export declare function getRoomAndGame(client: SuiClient, roomId: string, gameStateId: string): Promise<{
|
|
8
|
+
room: SuiObjectResponse;
|
|
9
|
+
game: SuiObjectResponse;
|
|
10
|
+
}>;
|
|
11
|
+
export declare function getRoomAndGameParsed(client: SuiClient, roomId: string, gameStateId: string): Promise<{
|
|
12
|
+
room: ParsedRoom | null;
|
|
13
|
+
game: ParsedGameState | null;
|
|
14
|
+
}>;
|
package/dist/read.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { parseGameState, parseRoom } from './parse.js';
|
|
2
|
+
// Helper function to check if a MoveStruct has fields property
|
|
3
|
+
function hasFields(fields) {
|
|
4
|
+
return fields !== null && typeof fields === 'object' && !Array.isArray(fields);
|
|
5
|
+
}
|
|
6
|
+
export async function getLobbyRoomIds(client, lobbyId, limit = 50) {
|
|
7
|
+
const lobbyObj = await client.getObject({
|
|
8
|
+
id: lobbyId,
|
|
9
|
+
options: { showContent: true },
|
|
10
|
+
});
|
|
11
|
+
const content = lobbyObj.data?.content;
|
|
12
|
+
if (!content || content.dataType !== 'moveObject') {
|
|
13
|
+
throw new Error('Lobby object not found or invalid');
|
|
14
|
+
}
|
|
15
|
+
const fields = content.fields;
|
|
16
|
+
if (!hasFields(fields)) {
|
|
17
|
+
throw new Error('Invalid lobby fields structure');
|
|
18
|
+
}
|
|
19
|
+
// After hasFields check, we know fields is an object
|
|
20
|
+
const roomToGame = fields.room_to_game;
|
|
21
|
+
if (!hasFields(roomToGame)) {
|
|
22
|
+
throw new Error('Invalid room_to_game structure');
|
|
23
|
+
}
|
|
24
|
+
const roomToGameFields = roomToGame.fields;
|
|
25
|
+
if (!hasFields(roomToGameFields)) {
|
|
26
|
+
throw new Error('Invalid room_to_game fields structure');
|
|
27
|
+
}
|
|
28
|
+
const id = roomToGameFields.id;
|
|
29
|
+
if (!hasFields(id)) {
|
|
30
|
+
throw new Error('Invalid id structure');
|
|
31
|
+
}
|
|
32
|
+
const roomToGameTableId = id.id;
|
|
33
|
+
if (typeof roomToGameTableId !== 'string') {
|
|
34
|
+
throw new Error('Lobby room_to_game table not found');
|
|
35
|
+
}
|
|
36
|
+
const roomEntries = await client.getDynamicFields({
|
|
37
|
+
parentId: roomToGameTableId,
|
|
38
|
+
limit,
|
|
39
|
+
});
|
|
40
|
+
return roomEntries.data.map(entry => entry.name.value);
|
|
41
|
+
}
|
|
42
|
+
export async function getLobbyRoomGamePairs(client, lobbyId, limit = 50) {
|
|
43
|
+
const lobbyObj = await client.getObject({
|
|
44
|
+
id: lobbyId,
|
|
45
|
+
options: { showContent: true },
|
|
46
|
+
});
|
|
47
|
+
const content = lobbyObj.data?.content;
|
|
48
|
+
if (!content || content.dataType !== 'moveObject') {
|
|
49
|
+
throw new Error('Lobby object not found or invalid');
|
|
50
|
+
}
|
|
51
|
+
const fields = content.fields;
|
|
52
|
+
if (!hasFields(fields)) {
|
|
53
|
+
throw new Error('Invalid lobby fields structure');
|
|
54
|
+
}
|
|
55
|
+
// After hasFields check, we know fields is an object
|
|
56
|
+
const roomToGame = fields.room_to_game;
|
|
57
|
+
if (!hasFields(roomToGame)) {
|
|
58
|
+
throw new Error('Invalid room_to_game structure');
|
|
59
|
+
}
|
|
60
|
+
const roomToGameFields = roomToGame.fields;
|
|
61
|
+
if (!hasFields(roomToGameFields)) {
|
|
62
|
+
throw new Error('Invalid room_to_game fields structure');
|
|
63
|
+
}
|
|
64
|
+
const id = roomToGameFields.id;
|
|
65
|
+
if (!hasFields(id)) {
|
|
66
|
+
throw new Error('Invalid id structure');
|
|
67
|
+
}
|
|
68
|
+
const roomToGameTableId = id.id;
|
|
69
|
+
if (typeof roomToGameTableId !== 'string') {
|
|
70
|
+
throw new Error('Lobby room_to_game table not found');
|
|
71
|
+
}
|
|
72
|
+
const roomEntries = await client.getDynamicFields({
|
|
73
|
+
parentId: roomToGameTableId,
|
|
74
|
+
limit,
|
|
75
|
+
});
|
|
76
|
+
const pairs = [];
|
|
77
|
+
for (const entry of roomEntries.data) {
|
|
78
|
+
const fieldObj = await client.getDynamicFieldObject({
|
|
79
|
+
parentId: roomToGameTableId,
|
|
80
|
+
name: entry.name,
|
|
81
|
+
});
|
|
82
|
+
const fieldContent = fieldObj.data?.content;
|
|
83
|
+
let gameStateId = null;
|
|
84
|
+
if (fieldContent && fieldContent.dataType === 'moveObject') {
|
|
85
|
+
const fieldFields = fieldContent.fields;
|
|
86
|
+
if (hasFields(fieldFields)) {
|
|
87
|
+
// After hasFields check, we know fieldFields is an object
|
|
88
|
+
const value = fieldFields.value;
|
|
89
|
+
if (typeof value === 'string') {
|
|
90
|
+
gameStateId = value;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
pairs.push({ roomId: entry.name.value, gameStateId });
|
|
95
|
+
}
|
|
96
|
+
return pairs;
|
|
97
|
+
}
|
|
98
|
+
export async function getRooms(client, roomIds) {
|
|
99
|
+
if (roomIds.length === 0)
|
|
100
|
+
return [];
|
|
101
|
+
return client.multiGetObjects({
|
|
102
|
+
ids: roomIds,
|
|
103
|
+
options: { showContent: true, showType: true },
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
export async function getRoomAndGame(client, roomId, gameStateId) {
|
|
107
|
+
const response = await client.multiGetObjects({
|
|
108
|
+
ids: [roomId, gameStateId],
|
|
109
|
+
options: { showContent: true },
|
|
110
|
+
});
|
|
111
|
+
const [room, game] = response;
|
|
112
|
+
return { room, game };
|
|
113
|
+
}
|
|
114
|
+
export async function getRoomAndGameParsed(client, roomId, gameStateId) {
|
|
115
|
+
const { room, game } = await getRoomAndGame(client, roomId, gameStateId);
|
|
116
|
+
// Convert SuiParsedData to the format expected by parse functions
|
|
117
|
+
const roomContent = room.data?.content?.dataType === 'moveObject'
|
|
118
|
+
? room.data.content
|
|
119
|
+
: undefined;
|
|
120
|
+
const gameContent = game.data?.content?.dataType === 'moveObject'
|
|
121
|
+
? game.data.content
|
|
122
|
+
: undefined;
|
|
123
|
+
return {
|
|
124
|
+
room: parseRoom(roomContent),
|
|
125
|
+
game: parseGameState(gameContent),
|
|
126
|
+
};
|
|
127
|
+
}
|
package/dist/tx.d.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Transaction } from '@onelabs/sui/transactions';
|
|
2
|
+
import { SdkConfig } from './types.js';
|
|
3
|
+
export declare function buildCreateRoomTx(config: SdkConfig, args: {
|
|
4
|
+
gameRegistryId: string;
|
|
5
|
+
configId: string;
|
|
6
|
+
entryFee: bigint | number | string;
|
|
7
|
+
maxPlayers: number;
|
|
8
|
+
creationFee: bigint | number | string;
|
|
9
|
+
gameType?: string;
|
|
10
|
+
}): Transaction;
|
|
11
|
+
export declare function buildCreateGameForRoomTx(config: SdkConfig, args: {
|
|
12
|
+
lobbyId: string;
|
|
13
|
+
roomId: string;
|
|
14
|
+
}): Transaction;
|
|
15
|
+
export declare function buildJoinTx(config: SdkConfig, args: {
|
|
16
|
+
roomId: string;
|
|
17
|
+
gameStateId: string;
|
|
18
|
+
}): Transaction;
|
|
19
|
+
export declare function buildReadyTx(config: SdkConfig, args: {
|
|
20
|
+
roomId: string;
|
|
21
|
+
entryFee: bigint | number | string;
|
|
22
|
+
}): Transaction;
|
|
23
|
+
export declare function buildJoinAndReadyTx(config: SdkConfig, args: {
|
|
24
|
+
roomId: string;
|
|
25
|
+
gameStateId: string;
|
|
26
|
+
entryFee: bigint | number | string;
|
|
27
|
+
}): Transaction;
|
|
28
|
+
export declare function buildReadyNextRoundTx(config: SdkConfig, args: {
|
|
29
|
+
roomId: string;
|
|
30
|
+
entryFee: bigint | number | string;
|
|
31
|
+
}): Transaction;
|
|
32
|
+
export declare function buildCancelReadyTx(config: SdkConfig, args: {
|
|
33
|
+
roomId: string;
|
|
34
|
+
}): Transaction;
|
|
35
|
+
export declare function buildLeaveRoomTx(config: SdkConfig, args: {
|
|
36
|
+
roomId: string;
|
|
37
|
+
}): Transaction;
|
|
38
|
+
export declare function buildLeaveGameTx(config: SdkConfig, args: {
|
|
39
|
+
gameStateId: string;
|
|
40
|
+
}): Transaction;
|
|
41
|
+
export declare function buildLeaveRoomAndGameTx(config: SdkConfig, args: {
|
|
42
|
+
roomId: string;
|
|
43
|
+
gameStateId: string;
|
|
44
|
+
}): Transaction;
|
|
45
|
+
export declare function buildPassBombTx(config: SdkConfig, args: {
|
|
46
|
+
gameStateId: string;
|
|
47
|
+
}): Transaction;
|
|
48
|
+
export declare function buildStartRoundWithHubTx(config: SdkConfig, args: {
|
|
49
|
+
gameStateId: string;
|
|
50
|
+
roomId: string;
|
|
51
|
+
adminCapId: string;
|
|
52
|
+
configId: string;
|
|
53
|
+
}): Transaction;
|
|
54
|
+
export declare function buildTryExplodeTx(config: SdkConfig, args: {
|
|
55
|
+
gameStateId: string;
|
|
56
|
+
}): Transaction;
|
|
57
|
+
export declare function buildSettleRoundWithHubTx(config: SdkConfig, args: {
|
|
58
|
+
gameStateId: string;
|
|
59
|
+
roomId: string;
|
|
60
|
+
gameCapId: string;
|
|
61
|
+
}): Transaction;
|
|
62
|
+
export declare function buildPrepareNextRoundTx(config: SdkConfig, args: {
|
|
63
|
+
gameStateId: string;
|
|
64
|
+
newRoomId: string;
|
|
65
|
+
}): Transaction;
|
package/dist/tx.js
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { Transaction } from '@onelabs/sui/transactions';
|
|
2
|
+
const DEFAULT_RANDOM = '0x8';
|
|
3
|
+
const DEFAULT_CLOCK = '0x6';
|
|
4
|
+
function toU64(value) {
|
|
5
|
+
return typeof value === 'bigint' ? value : BigInt(value);
|
|
6
|
+
}
|
|
7
|
+
function getGameType(packageId, coinType) {
|
|
8
|
+
return `${packageId}::bomb_panic::GameState<${coinType}>`;
|
|
9
|
+
}
|
|
10
|
+
export function buildCreateRoomTx(config, args) {
|
|
11
|
+
const tx = new Transaction();
|
|
12
|
+
const [creationFeeCoin] = tx.splitCoins(tx.gas, [tx.pure.u64(toU64(args.creationFee))]);
|
|
13
|
+
tx.moveCall({
|
|
14
|
+
target: `${config.packageId}::gamehub::create_room`,
|
|
15
|
+
arguments: [
|
|
16
|
+
tx.object(args.gameRegistryId),
|
|
17
|
+
tx.object(args.configId),
|
|
18
|
+
tx.pure.u64(toU64(args.entryFee)),
|
|
19
|
+
tx.pure.u8(args.maxPlayers),
|
|
20
|
+
creationFeeCoin,
|
|
21
|
+
],
|
|
22
|
+
typeArguments: [
|
|
23
|
+
config.coinType,
|
|
24
|
+
args.gameType ?? getGameType(config.packageId, config.coinType),
|
|
25
|
+
],
|
|
26
|
+
});
|
|
27
|
+
return tx;
|
|
28
|
+
}
|
|
29
|
+
export function buildCreateGameForRoomTx(config, args) {
|
|
30
|
+
const tx = new Transaction();
|
|
31
|
+
tx.moveCall({
|
|
32
|
+
target: `${config.packageId}::bomb_panic::create_game_for_room`,
|
|
33
|
+
arguments: [tx.object(args.lobbyId), tx.pure.address(args.roomId)],
|
|
34
|
+
typeArguments: [config.coinType],
|
|
35
|
+
});
|
|
36
|
+
return tx;
|
|
37
|
+
}
|
|
38
|
+
export function buildJoinTx(config, args) {
|
|
39
|
+
const tx = new Transaction();
|
|
40
|
+
tx.moveCall({
|
|
41
|
+
target: `${config.packageId}::gamehub::join_room`,
|
|
42
|
+
arguments: [tx.object(args.roomId)],
|
|
43
|
+
typeArguments: [config.coinType],
|
|
44
|
+
});
|
|
45
|
+
tx.moveCall({
|
|
46
|
+
target: `${config.packageId}::bomb_panic::join`,
|
|
47
|
+
arguments: [tx.object(args.gameStateId)],
|
|
48
|
+
typeArguments: [config.coinType],
|
|
49
|
+
});
|
|
50
|
+
return tx;
|
|
51
|
+
}
|
|
52
|
+
export function buildReadyTx(config, args) {
|
|
53
|
+
const tx = new Transaction();
|
|
54
|
+
const [entryCoin] = tx.splitCoins(tx.gas, [tx.pure.u64(toU64(args.entryFee))]);
|
|
55
|
+
tx.moveCall({
|
|
56
|
+
target: `${config.packageId}::gamehub::ready_to_play`,
|
|
57
|
+
arguments: [tx.object(args.roomId), entryCoin],
|
|
58
|
+
typeArguments: [config.coinType],
|
|
59
|
+
});
|
|
60
|
+
return tx;
|
|
61
|
+
}
|
|
62
|
+
export function buildJoinAndReadyTx(config, args) {
|
|
63
|
+
const tx = new Transaction();
|
|
64
|
+
const [entryCoin] = tx.splitCoins(tx.gas, [tx.pure.u64(toU64(args.entryFee))]);
|
|
65
|
+
tx.moveCall({
|
|
66
|
+
target: `${config.packageId}::gamehub::join_room`,
|
|
67
|
+
arguments: [tx.object(args.roomId)],
|
|
68
|
+
typeArguments: [config.coinType],
|
|
69
|
+
});
|
|
70
|
+
tx.moveCall({
|
|
71
|
+
target: `${config.packageId}::bomb_panic::join`,
|
|
72
|
+
arguments: [tx.object(args.gameStateId)],
|
|
73
|
+
typeArguments: [config.coinType],
|
|
74
|
+
});
|
|
75
|
+
tx.moveCall({
|
|
76
|
+
target: `${config.packageId}::gamehub::ready_to_play`,
|
|
77
|
+
arguments: [tx.object(args.roomId), entryCoin],
|
|
78
|
+
typeArguments: [config.coinType],
|
|
79
|
+
});
|
|
80
|
+
return tx;
|
|
81
|
+
}
|
|
82
|
+
export function buildReadyNextRoundTx(config, args) {
|
|
83
|
+
const tx = new Transaction();
|
|
84
|
+
const [entryCoin] = tx.splitCoins(tx.gas, [tx.pure.u64(toU64(args.entryFee))]);
|
|
85
|
+
tx.moveCall({
|
|
86
|
+
target: `${config.packageId}::gamehub::join_room`,
|
|
87
|
+
arguments: [tx.object(args.roomId)],
|
|
88
|
+
typeArguments: [config.coinType],
|
|
89
|
+
});
|
|
90
|
+
tx.moveCall({
|
|
91
|
+
target: `${config.packageId}::gamehub::ready_to_play`,
|
|
92
|
+
arguments: [tx.object(args.roomId), entryCoin],
|
|
93
|
+
typeArguments: [config.coinType],
|
|
94
|
+
});
|
|
95
|
+
return tx;
|
|
96
|
+
}
|
|
97
|
+
export function buildCancelReadyTx(config, args) {
|
|
98
|
+
const tx = new Transaction();
|
|
99
|
+
tx.moveCall({
|
|
100
|
+
target: `${config.packageId}::gamehub::cancel_ready`,
|
|
101
|
+
arguments: [tx.object(args.roomId)],
|
|
102
|
+
typeArguments: [config.coinType],
|
|
103
|
+
});
|
|
104
|
+
return tx;
|
|
105
|
+
}
|
|
106
|
+
export function buildLeaveRoomTx(config, args) {
|
|
107
|
+
const tx = new Transaction();
|
|
108
|
+
tx.moveCall({
|
|
109
|
+
target: `${config.packageId}::gamehub::leave_room`,
|
|
110
|
+
arguments: [tx.object(args.roomId)],
|
|
111
|
+
typeArguments: [config.coinType],
|
|
112
|
+
});
|
|
113
|
+
return tx;
|
|
114
|
+
}
|
|
115
|
+
export function buildLeaveGameTx(config, args) {
|
|
116
|
+
const tx = new Transaction();
|
|
117
|
+
tx.moveCall({
|
|
118
|
+
target: `${config.packageId}::bomb_panic::leave`,
|
|
119
|
+
arguments: [tx.object(args.gameStateId), tx.object(config.clockId ?? DEFAULT_CLOCK)],
|
|
120
|
+
typeArguments: [config.coinType],
|
|
121
|
+
});
|
|
122
|
+
return tx;
|
|
123
|
+
}
|
|
124
|
+
export function buildLeaveRoomAndGameTx(config, args) {
|
|
125
|
+
const tx = new Transaction();
|
|
126
|
+
tx.moveCall({
|
|
127
|
+
target: `${config.packageId}::gamehub::leave_room`,
|
|
128
|
+
arguments: [tx.object(args.roomId)],
|
|
129
|
+
typeArguments: [config.coinType],
|
|
130
|
+
});
|
|
131
|
+
tx.moveCall({
|
|
132
|
+
target: `${config.packageId}::bomb_panic::leave`,
|
|
133
|
+
arguments: [tx.object(args.gameStateId), tx.object(config.clockId ?? DEFAULT_CLOCK)],
|
|
134
|
+
typeArguments: [config.coinType],
|
|
135
|
+
});
|
|
136
|
+
return tx;
|
|
137
|
+
}
|
|
138
|
+
export function buildPassBombTx(config, args) {
|
|
139
|
+
const tx = new Transaction();
|
|
140
|
+
tx.moveCall({
|
|
141
|
+
target: `${config.packageId}::bomb_panic::pass_bomb`,
|
|
142
|
+
arguments: [
|
|
143
|
+
tx.object(config.randomId ?? DEFAULT_RANDOM),
|
|
144
|
+
tx.object(args.gameStateId),
|
|
145
|
+
tx.object(config.clockId ?? DEFAULT_CLOCK),
|
|
146
|
+
],
|
|
147
|
+
typeArguments: [config.coinType],
|
|
148
|
+
});
|
|
149
|
+
return tx;
|
|
150
|
+
}
|
|
151
|
+
export function buildStartRoundWithHubTx(config, args) {
|
|
152
|
+
const tx = new Transaction();
|
|
153
|
+
tx.moveCall({
|
|
154
|
+
target: `${config.packageId}::bomb_panic::start_round_with_hub`,
|
|
155
|
+
arguments: [
|
|
156
|
+
tx.object(config.randomId ?? DEFAULT_RANDOM),
|
|
157
|
+
tx.object(args.gameStateId),
|
|
158
|
+
tx.object(args.roomId),
|
|
159
|
+
tx.object(config.clockId ?? DEFAULT_CLOCK),
|
|
160
|
+
tx.object(args.adminCapId),
|
|
161
|
+
tx.object(args.configId),
|
|
162
|
+
],
|
|
163
|
+
typeArguments: [config.coinType],
|
|
164
|
+
});
|
|
165
|
+
return tx;
|
|
166
|
+
}
|
|
167
|
+
export function buildTryExplodeTx(config, args) {
|
|
168
|
+
const tx = new Transaction();
|
|
169
|
+
tx.moveCall({
|
|
170
|
+
target: `${config.packageId}::bomb_panic::try_explode`,
|
|
171
|
+
arguments: [
|
|
172
|
+
tx.object(args.gameStateId),
|
|
173
|
+
tx.object(config.clockId ?? DEFAULT_CLOCK),
|
|
174
|
+
tx.object(config.randomId ?? DEFAULT_RANDOM),
|
|
175
|
+
],
|
|
176
|
+
typeArguments: [config.coinType],
|
|
177
|
+
});
|
|
178
|
+
return tx;
|
|
179
|
+
}
|
|
180
|
+
export function buildSettleRoundWithHubTx(config, args) {
|
|
181
|
+
const tx = new Transaction();
|
|
182
|
+
tx.moveCall({
|
|
183
|
+
target: `${config.packageId}::bomb_panic::settle_round_with_hub`,
|
|
184
|
+
arguments: [
|
|
185
|
+
tx.object(args.gameStateId),
|
|
186
|
+
tx.object(args.roomId),
|
|
187
|
+
tx.object(args.gameCapId),
|
|
188
|
+
],
|
|
189
|
+
typeArguments: [config.coinType],
|
|
190
|
+
});
|
|
191
|
+
return tx;
|
|
192
|
+
}
|
|
193
|
+
export function buildPrepareNextRoundTx(config, args) {
|
|
194
|
+
const tx = new Transaction();
|
|
195
|
+
tx.moveCall({
|
|
196
|
+
target: `${config.packageId}::bomb_panic::prepare_next_round`,
|
|
197
|
+
arguments: [tx.object(args.gameStateId), tx.pure.address(args.newRoomId)],
|
|
198
|
+
typeArguments: [config.coinType],
|
|
199
|
+
});
|
|
200
|
+
return tx;
|
|
201
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export type SdkConfig = {
|
|
2
|
+
packageId: string;
|
|
3
|
+
coinType: string;
|
|
4
|
+
randomId?: string;
|
|
5
|
+
clockId?: string;
|
|
6
|
+
};
|
|
7
|
+
export type RoomStatus = 'Waiting' | 'Started' | 'Cancelled' | 'Settled' | string;
|
|
8
|
+
export type GamePhase = 'Waiting' | 'Playing' | 'Ended' | string;
|
|
9
|
+
export type ParsedRoom = {
|
|
10
|
+
roomId: string;
|
|
11
|
+
status: RoomStatus;
|
|
12
|
+
entryFee: bigint;
|
|
13
|
+
maxPlayers: number;
|
|
14
|
+
playerCount: number;
|
|
15
|
+
poolValue: bigint;
|
|
16
|
+
readyCount: number;
|
|
17
|
+
readyTableId?: string;
|
|
18
|
+
};
|
|
19
|
+
export type ParsedPlayer = {
|
|
20
|
+
address: string;
|
|
21
|
+
alive: boolean;
|
|
22
|
+
reward: bigint;
|
|
23
|
+
isHolder: boolean;
|
|
24
|
+
};
|
|
25
|
+
export type ParsedGameState = {
|
|
26
|
+
gameId: string;
|
|
27
|
+
phase: GamePhase;
|
|
28
|
+
roundId: bigint;
|
|
29
|
+
bombHolder: string | null;
|
|
30
|
+
holderStartMs: bigint;
|
|
31
|
+
roundStartMs: bigint;
|
|
32
|
+
poolValue: bigint;
|
|
33
|
+
entryFeePerPlayer: bigint;
|
|
34
|
+
rewardPerSec: bigint;
|
|
35
|
+
explosionRateBps: bigint;
|
|
36
|
+
settlementConsumed: boolean;
|
|
37
|
+
roomId: string;
|
|
38
|
+
players: ParsedPlayer[];
|
|
39
|
+
};
|
|
40
|
+
export type RoomGamePair = {
|
|
41
|
+
roomId: string;
|
|
42
|
+
gameStateId: string | null;
|
|
43
|
+
};
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bomb-panic-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
|
-
"files": [
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"README.md",
|
|
10
|
+
"LICENSE"
|
|
11
|
+
],
|
|
8
12
|
"scripts": {
|
|
9
13
|
"build": "tsc -p tsconfig.json"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"bomb-panic-sdk": "^0.1.0"
|
|
10
17
|
}
|
|
11
18
|
}
|