@block52/poker-vm-sdk 1.4.0 → 1.4.1

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 CHANGED
@@ -45265,6 +45265,7 @@ declare enum NonPlayerActionType {
45265
45265
  SIT_IN = "sit-in",
45266
45266
  SIT_IN_AND_WAIT = "sit-in-and-wait",
45267
45267
  SIT_OUT = "sit-out",
45268
+ TIMEOUT = "timeout",
45268
45269
  TOP_UP = "top-up"
45269
45270
  }
45270
45271
  declare const AllPlayerActions: {
@@ -45278,6 +45279,7 @@ declare const AllPlayerActions: {
45278
45279
  SIT_IN: NonPlayerActionType.SIT_IN;
45279
45280
  SIT_IN_AND_WAIT: NonPlayerActionType.SIT_IN_AND_WAIT;
45280
45281
  SIT_OUT: NonPlayerActionType.SIT_OUT;
45282
+ TIMEOUT: NonPlayerActionType.TIMEOUT;
45281
45283
  TOP_UP: NonPlayerActionType.TOP_UP;
45282
45284
  SMALL_BLIND: PlayerActionType.SMALL_BLIND;
45283
45285
  BIG_BLIND: PlayerActionType.BIG_BLIND;
@@ -46558,6 +46560,7 @@ interface SNGConfig {
46558
46560
  declare class SigningCosmosClient extends CosmosClient {
46559
46561
  private wallet?;
46560
46562
  private signingClient?;
46563
+ private readonly accountNumbers;
46561
46564
  private gasPrice;
46562
46565
  constructor(config: SigningCosmosConfig);
46563
46566
  /**
@@ -46656,6 +46659,11 @@ declare class SigningCosmosClient extends CosmosClient {
46656
46659
  *
46657
46660
  * Returns the tx hash on CheckTx success; throws if CheckTx
46658
46661
  * rejects (invalid signature, malformed msg, insufficient gas).
46662
+ *
46663
+ * Deliberately NOT routed through `assertExecuted` (#2609): there is no
46664
+ * DeliverTx result to check at this point — the hash is a CheckTx receipt,
46665
+ * and the execution outcome arrives over the WebSocket. Every other
46666
+ * broadcasting method in this class waits for inclusion and must check.
46659
46667
  */
46660
46668
  performActionSync(gameId: string, action: string, amount?: bigint, data?: string): Promise<string>;
46661
46669
  /**
@@ -46709,6 +46717,13 @@ declare class SigningCosmosClient extends CosmosClient {
46709
46717
  * long a replay of this exact tx is rejected.
46710
46718
  */
46711
46719
  private signUnordered;
46720
+ /**
46721
+ * account_number for the unordered sign doc. It is assigned once when the
46722
+ * account is created and never changes, so look it up once per signer —
46723
+ * performActionSync signs on every player action and shouldn't pay a REST
46724
+ * round trip (or inherit its failure modes) each time.
46725
+ */
46726
+ private unorderedAccountNumber;
46712
46727
  /**
46713
46728
  * Sign-only MsgJoinGame: builds and signs the player's buy-in tx WITHOUT
46714
46729
  * broadcasting, returning the base64 TxRaw for the gateway to relay
@@ -46816,6 +46831,69 @@ declare class SigningCosmosClient extends CosmosClient {
46816
46831
  */
46817
46832
  declare function createSigningClientFromMnemonic(config: CosmosConfig, mnemonic: string): Promise<SigningCosmosClient>;
46818
46833
 
46834
+ /**
46835
+ * The part of a broadcast result this module reads. Structurally a subset of
46836
+ * CosmJS's `DeliverTxResponse`, so both the real response and a test double fit.
46837
+ */
46838
+ interface ExecutionResult {
46839
+ transactionHash: string;
46840
+ code: number;
46841
+ rawLog?: string;
46842
+ }
46843
+ /**
46844
+ * Thrown when a transaction was broadcast and included in a block but its
46845
+ * EXECUTION failed (nonzero `DeliverTxResponse.code`). The hash, code and raw
46846
+ * log are retained so the failure can be looked up and shown. (#2609)
46847
+ */
46848
+ declare class TxExecutionError extends Error {
46849
+ readonly transactionHash: string;
46850
+ readonly code: number;
46851
+ readonly rawLog?: string;
46852
+ constructor(operation: string, result: ExecutionResult);
46853
+ }
46854
+ /**
46855
+ * Assert that a broadcast transaction actually EXECUTED successfully.
46856
+ *
46857
+ * CosmJS resolves `signAndBroadcast` normally when execution fails — a nonzero
46858
+ * `DeliverTxResponse.code` is the only failure signal, and it is easy to miss
46859
+ * because nothing throws. Returning `result.transactionHash` without checking
46860
+ * reports "insufficient funds" and "invalid request" to the caller as success.
46861
+ *
46862
+ * Every SDK method that broadcasts and waits for inclusion goes through this.
46863
+ * The exception is `performActionSync`, which returns a CheckTx-only hash by
46864
+ * design and whose caller waits on a WebSocket push for the committed result —
46865
+ * see the comment there before adding a check to it.
46866
+ */
46867
+ declare function assertExecuted(operation: string, result: ExecutionResult): void;
46868
+ /**
46869
+ * Where a failed SDK transaction call stopped. Lets a caller decide whether
46870
+ * chain state may have changed and whether resubmitting is safe:
46871
+ *
46872
+ * - `"not-broadcast"`: the node rejected the tx at CheckTx (CosmJS
46873
+ * `BroadcastTxError`). It never entered a block; nothing changed; fix the
46874
+ * cause and resubmit.
46875
+ * - `"execution-failed"`: the tx was included in a block but failed there
46876
+ * ({@link TxExecutionError}). The state change did not happen, the hash
46877
+ * exists, and resubmitting the same tx fails the same way unless the cause
46878
+ * changed.
46879
+ * - `"unknown"`: the mempool accepted the tx but inclusion was not observed
46880
+ * before CosmJS's timeout (`TimeoutError`). It MAY still execute — look the
46881
+ * hash up before retrying, or the retry can double-submit.
46882
+ */
46883
+ type TxFailurePhase = "not-broadcast" | "execution-failed" | "unknown";
46884
+ /**
46885
+ * Classify an error thrown by an SDK broadcast method. Returns `undefined` for
46886
+ * errors raised before any broadcast (argument validation, no wallet, signing)
46887
+ * or by another layer (REST queries, network) — those carry no transaction.
46888
+ */
46889
+ declare function txFailurePhase(error: unknown): TxFailurePhase | undefined;
46890
+ /**
46891
+ * The hash of the transaction behind a failed broadcast call, when one exists:
46892
+ * the included-but-failed tx for `"execution-failed"`, the pending tx for
46893
+ * `"unknown"`. `"not-broadcast"` and pre-broadcast errors have none.
46894
+ */
46895
+ declare function txFailureHash(error: unknown): string | undefined;
46896
+
46819
46897
  declare const Client: typeof IgniteClient & Constructor<{
46820
46898
  PokerchainPokerV_1: {
46821
46899
  query: ReturnType<typeof queryClient>;
@@ -47067,5 +47145,5 @@ declare const Client: typeof IgniteClient & Constructor<{
47067
47145
  }>;
47068
47146
  declare const registry: Registry;
47069
47147
 
47070
- export { AllPlayerActions, BLOCK52_HD_PATH, Board, COSMOS_CONSTANTS, Client, CosmosClient, Deck, GAME_NAME_MICRO_PER_CHAR, GameFormat, GameStatus, GameVariant, HandType, KEYS, MAX_GAME_NAME_LENGTH, MissingWalletError, NonPlayerActionType, Params, PlayerActionType, PlayerStatus, PokerGameIntegration, PokerSolver, RPCMethods, SIT_IN_METHOD_NEXT_BB, SIT_IN_METHOD_POST_NOW, SIT_OUT_METHOD_NEXT_BB, SIT_OUT_METHOD_NEXT_HAND, SUIT, SigningCosmosClient, TexasHoldemRound, ValidatorBond, WithdrawalRequest, computeGameNameFee, createSigningClientFromMnemonic, createWalletFromMnemonic, formatGameFormatDisplay, formatGameVariantDisplay, generateWallet, getActionByType, getAddressFromMnemonic, getDefaultCosmosConfig, getGameFormat, getGameFormatForCosmos, getGameFormatFromObject, getGameVariant, hasAction, isCashFormat, isEmptyAddress, isSitAndGoFormat, isTournamentFormat, isValidMnemonic, isValidPlayerAddress, parseGameFormat, parseGameVariant, registry };
47071
- export type { AccountDTO, ActionDTO, Block, BlockDTO, BlockHeader, BlockHeaderDTO, BlockID, BlockResponse, BurnResponseDTO, Card, EquityHand, EquityRequest, EquityResponse, EquityResult, GameListItem, GameOptions, GameOptionsDTO, GameOptionsResponse, GameStateResponse, GameStateResponseDTO, HandEvaluation, ISignedResponse, LegalActionDTO, PayoutPlaceDTO, PerformActionResponse, PlayerDTO, RPCRequest, RPCRequestParams, RPCResponse, RakeConfig, RakeConfigDTO, ResultDTO, SitInMethod, SitOutMethod, TexasHoldemGameState, TexasHoldemStateDTO, TransactionDTO, TransactionResponse, WalletInfo, WinnerDTO, WithdrawResponseDTO };
47148
+ export { AllPlayerActions, BLOCK52_HD_PATH, Board, COSMOS_CONSTANTS, Client, CosmosClient, Deck, GAME_NAME_MICRO_PER_CHAR, GameFormat, GameStatus, GameVariant, HandType, KEYS, MAX_GAME_NAME_LENGTH, MissingWalletError, NonPlayerActionType, Params, PlayerActionType, PlayerStatus, PokerGameIntegration, PokerSolver, RPCMethods, SIT_IN_METHOD_NEXT_BB, SIT_IN_METHOD_POST_NOW, SIT_OUT_METHOD_NEXT_BB, SIT_OUT_METHOD_NEXT_HAND, SUIT, SigningCosmosClient, TexasHoldemRound, TxExecutionError, ValidatorBond, WithdrawalRequest, assertExecuted, computeGameNameFee, createSigningClientFromMnemonic, createWalletFromMnemonic, formatGameFormatDisplay, formatGameVariantDisplay, generateWallet, getActionByType, getAddressFromMnemonic, getDefaultCosmosConfig, getGameFormat, getGameFormatForCosmos, getGameFormatFromObject, getGameVariant, hasAction, isCashFormat, isEmptyAddress, isSitAndGoFormat, isTournamentFormat, isValidMnemonic, isValidPlayerAddress, parseGameFormat, parseGameVariant, registry, txFailureHash, txFailurePhase };
47149
+ export type { AccountDTO, ActionDTO, Block, BlockDTO, BlockHeader, BlockHeaderDTO, BlockID, BlockResponse, BurnResponseDTO, Card, EquityHand, EquityRequest, EquityResponse, EquityResult, ExecutionResult, GameListItem, GameOptions, GameOptionsDTO, GameOptionsResponse, GameStateResponse, GameStateResponseDTO, HandEvaluation, ISignedResponse, LegalActionDTO, PayoutPlaceDTO, PerformActionResponse, PlayerDTO, RPCRequest, RPCRequestParams, RPCResponse, RakeConfig, RakeConfigDTO, ResultDTO, SitInMethod, SitOutMethod, TexasHoldemGameState, TexasHoldemStateDTO, TransactionDTO, TransactionResponse, TxFailurePhase, WalletInfo, WinnerDTO, WithdrawResponseDTO };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAkC/C,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEV,CAAC;AAEH,QAAA,MAAM,QAAQ,UAiCZ,CAAA;AAGF,cAAc,6BAA6B,CAAA;AAG3C,cAAc,cAAc,CAAA;AAG5B,cAAc,SAAS,CAAA;AAGvB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAGpG,cAAc,eAAe,CAAA;AAG7B,cAAc,eAAe,CAAA;AAG7B,cAAc,yBAAyB,CAAA;AAGvC,cAAc,qBAAqB,CAAA;AAGnC,cAAc,sBAAsB,CAAA;AAGpC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAGrE,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAG7B,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAG/B,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAG7D,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACvF,OAAO,EAAE,mBAAmB,EAAE,+BAA+B,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAGvG,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAGzF,OAAO,EACL,MAAM,EACN,QAAQ,EACR,kBAAkB,EACnB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAkC/C,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEV,CAAC;AAEH,QAAA,MAAM,QAAQ,UAiCZ,CAAA;AAGF,cAAc,6BAA6B,CAAA;AAG3C,cAAc,cAAc,CAAA;AAG5B,cAAc,SAAS,CAAA;AAGvB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAGpG,cAAc,eAAe,CAAA;AAG7B,cAAc,eAAe,CAAA;AAG7B,cAAc,yBAAyB,CAAA;AAGvC,cAAc,qBAAqB,CAAA;AAGnC,cAAc,sBAAsB,CAAA;AAGpC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAGrE,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAG7B,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAG/B,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAG7D,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACvF,OAAO,EAAE,mBAAmB,EAAE,+BAA+B,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAIvG,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,KAAK,cAAc,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAA;AAGvI,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAGzF,OAAO,EACL,MAAM,EACN,QAAQ,EACR,kBAAkB,EACnB,CAAA"}
package/dist/index.esm.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { Registry, DirectSecp256k1HdWallet, encodePubkey, makeAuthInfoBytes, makeSignDoc } from '@cosmjs/proto-signing';
2
- import { SigningStargateClient, GasPrice } from '@cosmjs/stargate';
2
+ import { SigningStargateClient, BroadcastTxError, TimeoutError, GasPrice } from '@cosmjs/stargate';
3
3
  import { EventEmitter } from 'events';
4
4
  import { stringToPath } from '@cosmjs/crypto';
5
5
  import { createHash, createHmac } from 'crypto';
6
- import { toBase64, fromBase64 } from '@cosmjs/encoding';
6
+ import { fromBase64, toBase64 } from '@cosmjs/encoding';
7
7
  import { encodeSecp256k1Pubkey } from '@cosmjs/amino';
8
8
 
9
9
  /// <reference path="./types.d.ts" />
@@ -56165,6 +56165,14 @@ var NonPlayerActionType;
56165
56165
  // so each has a single responsibility. Sets WAITING_FOR_BIG_BLIND. (#2139)
56166
56166
  NonPlayerActionType["SIT_IN_AND_WAIT"] = "sit-in-and-wait";
56167
56167
  NonPlayerActionType["SIT_OUT"] = "sit-out";
56168
+ // Action clock enforcement (poker-vm#2523): submitted by ANY address once the
56169
+ // next-to-act player's turn deadline (last recorded action timestamp +
56170
+ // gameOptions.timeout seconds) has passed. The engine plays that player's
56171
+ // forced default action on their behalf — CHECK if legal else FOLD in a
56172
+ // betting round, the owed blind post or DEAL in ANTE, MUCK if legal else
56173
+ // SHOW at showdown — and records THAT action; no "timeout" turn is ever
56174
+ // written to previousActions. Rejected while the turn has time remaining.
56175
+ NonPlayerActionType["TIMEOUT"] = "timeout";
56168
56176
  NonPlayerActionType["TOP_UP"] = "top-up";
56169
56177
  })(NonPlayerActionType || (NonPlayerActionType = {}));
56170
56178
  const AllPlayerActions = { ...PlayerActionType, ...NonPlayerActionType };
@@ -61154,6 +61162,79 @@ function requireTx () {
61154
61162
 
61155
61163
  var txExports = requireTx();
61156
61164
 
61165
+ /**
61166
+ * Thrown when a transaction was broadcast and included in a block but its
61167
+ * EXECUTION failed (nonzero `DeliverTxResponse.code`). The hash, code and raw
61168
+ * log are retained so the failure can be looked up and shown. (#2609)
61169
+ */
61170
+ class TxExecutionError extends Error {
61171
+ constructor(operation, result) {
61172
+ super(`Failed to ${operation}: transaction ${result.transactionHash} failed with code ${result.code}` +
61173
+ (result.rawLog ? ` — ${result.rawLog}` : ""));
61174
+ this.name = "TxExecutionError";
61175
+ this.transactionHash = result.transactionHash;
61176
+ this.code = result.code;
61177
+ this.rawLog = result.rawLog;
61178
+ }
61179
+ }
61180
+ /**
61181
+ * Assert that a broadcast transaction actually EXECUTED successfully.
61182
+ *
61183
+ * CosmJS resolves `signAndBroadcast` normally when execution fails — a nonzero
61184
+ * `DeliverTxResponse.code` is the only failure signal, and it is easy to miss
61185
+ * because nothing throws. Returning `result.transactionHash` without checking
61186
+ * reports "insufficient funds" and "invalid request" to the caller as success.
61187
+ *
61188
+ * Every SDK method that broadcasts and waits for inclusion goes through this.
61189
+ * The exception is `performActionSync`, which returns a CheckTx-only hash by
61190
+ * design and whose caller waits on a WebSocket push for the committed result —
61191
+ * see the comment there before adding a check to it.
61192
+ */
61193
+ function assertExecuted(operation, result) {
61194
+ // A real DeliverTxResponse always carries `code`. If it is missing we cannot
61195
+ // tell success from failure, so fail closed and say why — reporting it as
61196
+ // "code undefined" would send someone hunting a chain error that does not
61197
+ // exist, when the actual problem is a malformed response or a partial mock.
61198
+ if (typeof result?.code !== "number") {
61199
+ throw new Error(`Failed to ${operation}: broadcast response has no execution code, so success cannot be confirmed ` +
61200
+ `(transaction ${result?.transactionHash ?? "unknown"})`);
61201
+ }
61202
+ if (result.code !== 0) {
61203
+ throw new TxExecutionError(operation, result);
61204
+ }
61205
+ }
61206
+ /**
61207
+ * Classify an error thrown by an SDK broadcast method. Returns `undefined` for
61208
+ * errors raised before any broadcast (argument validation, no wallet, signing)
61209
+ * or by another layer (REST queries, network) — those carry no transaction.
61210
+ */
61211
+ function txFailurePhase(error) {
61212
+ if (error instanceof TxExecutionError) {
61213
+ return "execution-failed";
61214
+ }
61215
+ if (error instanceof BroadcastTxError) {
61216
+ return "not-broadcast";
61217
+ }
61218
+ if (error instanceof TimeoutError) {
61219
+ return "unknown";
61220
+ }
61221
+ return undefined;
61222
+ }
61223
+ /**
61224
+ * The hash of the transaction behind a failed broadcast call, when one exists:
61225
+ * the included-but-failed tx for `"execution-failed"`, the pending tx for
61226
+ * `"unknown"`. `"not-broadcast"` and pre-broadcast errors have none.
61227
+ */
61228
+ function txFailureHash(error) {
61229
+ if (error instanceof TxExecutionError) {
61230
+ return error.transactionHash;
61231
+ }
61232
+ if (error instanceof TimeoutError) {
61233
+ return error.txId;
61234
+ }
61235
+ return undefined;
61236
+ }
61237
+
61157
61238
  /**
61158
61239
  * Default gas limit for all transactions
61159
61240
  */
@@ -61162,6 +61243,18 @@ const DEFAULT_GAS_LIMIT = 1000000;
61162
61243
  // hand-building an unordered TxBody (signUnordered). Module-level so it's built
61163
61244
  // once and shared with the stargate client's registry semantics.
61164
61245
  const pokerRegistry = new Registry(msgTypes$u);
61246
+ // The chain dedups unordered txs on (signer, timeout_timestamp), so two txs
61247
+ // from one account must never share a timeout. Date has millisecond resolution
61248
+ // and a client fires blind + deal + action back to back, so track the last
61249
+ // timeout handed out per signer and keep it strictly increasing. Module-level:
61250
+ // callers rebuild the client (e.g. after a transport error) mid-session.
61251
+ const lastUnorderedTimeoutMs = new Map();
61252
+ function nextUnorderedTimeoutMs(signer, ttlSeconds) {
61253
+ const wanted = Date.now() + ttlSeconds * 1000;
61254
+ const timeoutMs = Math.max(wanted, (lastUnorderedTimeoutMs.get(signer) ?? 0) + 1);
61255
+ lastUnorderedTimeoutMs.set(signer, timeoutMs);
61256
+ return timeoutMs;
61257
+ }
61165
61258
  /**
61166
61259
  * Create a gasless fee object with specified gas limit
61167
61260
  * Chain is configured with min-gas-prices = "0stake" so no fee tokens required
@@ -61187,6 +61280,7 @@ class SigningCosmosClient extends CosmosClient {
61187
61280
  gasPrice: typeof config.gasPrice === 'string' ? config.gasPrice : (config.gasPrice?.toString() || COSMOS_CONSTANTS.DEFAULT_GAS_PRICE)
61188
61281
  };
61189
61282
  super(baseConfig);
61283
+ this.accountNumbers = new Map();
61190
61284
  this.wallet = config.wallet;
61191
61285
  // Handle gasPrice - convert string to GasPrice if needed
61192
61286
  if (typeof config.gasPrice === 'string') {
@@ -61244,13 +61338,16 @@ class SigningCosmosClient extends CosmosClient {
61244
61338
  const coins = [{ denom: denom, amount: amount.toString() }];
61245
61339
  const fee = gaslessFee();
61246
61340
  const result = await this.signingClient.sendTokens(fromAddress, toAddress, coins, fee, memo || "");
61341
+ assertExecuted("send tokens", result);
61247
61342
  return result.transactionHash;
61248
61343
  }
61249
61344
  /**
61250
61345
  * Send B52USDC tokens
61251
61346
  */
61252
61347
  async sendB52USDC(fromAddress, toAddress, amount, memo) {
61253
- return this.sendTokens(fromAddress, toAddress, amount, memo);
61348
+ // `denom` is the 4th parameter — passing `memo` here put the memo text
61349
+ // into the coin denom and always sent an empty memo.
61350
+ return this.sendTokens(fromAddress, toAddress, amount, undefined, memo);
61254
61351
  }
61255
61352
  /**
61256
61353
  * Create a new poker game
@@ -61340,6 +61437,7 @@ class SigningCosmosClient extends CosmosClient {
61340
61437
  });
61341
61438
  try {
61342
61439
  const result = await this.signingClient.signAndBroadcast(creator, [msg], fee, memo);
61440
+ assertExecuted("create game", result);
61343
61441
  console.log("✅ Game creation transaction successful:", result.transactionHash);
61344
61442
  return result.transactionHash;
61345
61443
  }
@@ -61377,6 +61475,7 @@ class SigningCosmosClient extends CosmosClient {
61377
61475
  console.log("🪑 Joining game:", { gameId, seat, buyInAmount: buyInAmount.toString() });
61378
61476
  try {
61379
61477
  const result = await this.signingClient.signAndBroadcast(player, [msg], fee, memo);
61478
+ assertExecuted("join game", result);
61380
61479
  console.log("✅ Join game transaction successful:", result.transactionHash);
61381
61480
  return result.transactionHash;
61382
61481
  }
@@ -61424,6 +61523,7 @@ class SigningCosmosClient extends CosmosClient {
61424
61523
  console.log("🚪 Leaving game:", { gameId });
61425
61524
  try {
61426
61525
  const result = await this.signingClient.signAndBroadcast(creator, [msg], fee, memo);
61526
+ assertExecuted("leave game", result);
61427
61527
  console.log("✅ Leave game transaction successful:", result.transactionHash);
61428
61528
  return result.transactionHash;
61429
61529
  }
@@ -61456,6 +61556,7 @@ class SigningCosmosClient extends CosmosClient {
61456
61556
  const memo = "Record hand end via SDK";
61457
61557
  try {
61458
61558
  const result = await this.signingClient.signAndBroadcast(creator, [msg], fee, memo);
61559
+ assertExecuted("record hand end", result);
61459
61560
  return result.transactionHash;
61460
61561
  }
61461
61562
  catch (error) {
@@ -61489,6 +61590,7 @@ class SigningCosmosClient extends CosmosClient {
61489
61590
  console.log("🗑️ Deleting game:", { gameId });
61490
61591
  try {
61491
61592
  const result = await this.signingClient.signAndBroadcast(creator, [msg], fee, memo);
61593
+ assertExecuted("delete game", result);
61492
61594
  console.log("✅ Delete game transaction successful:", result.transactionHash);
61493
61595
  return result.transactionHash;
61494
61596
  }
@@ -61528,6 +61630,7 @@ class SigningCosmosClient extends CosmosClient {
61528
61630
  console.log("🛑 Force-closing game:", { gameId });
61529
61631
  try {
61530
61632
  const result = await this.signingClient.signAndBroadcast(creator, [msg], fee, memo);
61633
+ assertExecuted("force close game", result);
61531
61634
  console.log("✅ Force-close transaction successful:", result.transactionHash);
61532
61635
  return result.transactionHash;
61533
61636
  }
@@ -61576,6 +61679,7 @@ class SigningCosmosClient extends CosmosClient {
61576
61679
  });
61577
61680
  try {
61578
61681
  const result = await this.signingClient.signAndBroadcast(player, [msg], fee, memo);
61682
+ assertExecuted("perform action", result);
61579
61683
  console.log("✅ Action transaction successful:", result.transactionHash);
61580
61684
  return result.transactionHash;
61581
61685
  }
@@ -61608,6 +61712,11 @@ class SigningCosmosClient extends CosmosClient {
61608
61712
  *
61609
61713
  * Returns the tx hash on CheckTx success; throws if CheckTx
61610
61714
  * rejects (invalid signature, malformed msg, insufficient gas).
61715
+ *
61716
+ * Deliberately NOT routed through `assertExecuted` (#2609): there is no
61717
+ * DeliverTx result to check at this point — the hash is a CheckTx receipt,
61718
+ * and the execution outcome arrives over the WebSocket. Every other
61719
+ * broadcasting method in this class waits for inclusion and must check.
61611
61720
  */
61612
61721
  async performActionSync(gameId, action, amount = 0n, data) {
61613
61722
  await this.initializeSigningClient();
@@ -61616,26 +61725,30 @@ class SigningCosmosClient extends CosmosClient {
61616
61725
  }
61617
61726
  const [account] = await this.wallet.getAccounts();
61618
61727
  const player = account.address;
61619
- // Same msg shape as performAction — only the broadcast mode differs.
61620
- const msgPerformAction = {
61621
- player,
61622
- gameId,
61623
- action,
61624
- amount: Long.fromString(amount.toString(), true),
61625
- data: data || ""
61626
- };
61728
+ // Same msg shape as performAction — only signing + broadcast mode differ.
61627
61729
  const msg = {
61628
61730
  typeUrl: "/pokerchain.poker.v1.MsgPerformAction",
61629
- value: msgPerformAction
61731
+ value: {
61732
+ player,
61733
+ gameId,
61734
+ action,
61735
+ amount: Long.fromString(amount.toString(), true),
61736
+ data: data || ""
61737
+ }
61630
61738
  };
61631
- const fee = gaslessFee();
61632
- const memo = `Poker action (sync): ${action}`;
61633
61739
  try {
61634
- // signAndBroadcastSync returns just the txhash, no DeliverTx
61635
- // result. The caller waits on the WS push for the
61740
+ // UNORDERED (#2619): gameplay txs carry no account sequence. Sync
61741
+ // broadcast returns at CheckTx, not at commit, so an ordered tx
61742
+ // signed before the previous one commits re-reads the same
61743
+ // committed sequence and is rejected with code 32 — blind + deal +
61744
+ // action from one account inside a block did exactly that. This is
61745
+ // the chain-direct twin of signPerformAction's fix (#247, ui#520).
61746
+ const { base64 } = await this.signUnordered(msg);
61747
+ // broadcastTxSync returns just the txhash, no DeliverTx result, and
61748
+ // throws BroadcastTxError when CheckTx rejects — the same contract
61749
+ // signAndBroadcastSync had. The caller waits on the WS push for the
61636
61750
  // authoritative outcome.
61637
- const txHash = await this.signingClient.signAndBroadcastSync(player, [msg], fee, memo);
61638
- return txHash;
61751
+ return await this.signingClient.broadcastTxSync(fromBase64(base64));
61639
61752
  }
61640
61753
  catch (error) {
61641
61754
  console.error("❌ Action (sync) failed at CheckTx:", error);
@@ -61745,8 +61858,7 @@ class SigningCosmosClient extends CosmosClient {
61745
61858
  const player = account.address;
61746
61859
  // account_number + chainId are still needed for the sign doc; the
61747
61860
  // SEQUENCE is not — unordered txs must sign with sequence 0.
61748
- const accountInfo = await this.getAccount(player);
61749
- const accountNumber = Number(accountInfo.account.account_number);
61861
+ const accountNumber = await this.unorderedAccountNumber(player);
61750
61862
  const chainId = this.config.chainId;
61751
61863
  // Body with unordered=true + timeout_timestamp, messages packed as Any
61752
61864
  // via the poker registry. timeoutHeight stays 0 (we gate on timestamp).
@@ -61755,7 +61867,7 @@ class SigningCosmosClient extends CosmosClient {
61755
61867
  memo: "",
61756
61868
  timeoutHeight: Long.UZERO,
61757
61869
  unordered: true,
61758
- timeoutTimestamp: new Date(Date.now() + ttlSeconds * 1000)
61870
+ timeoutTimestamp: new Date(nextUnorderedTimeoutMs(player, ttlSeconds))
61759
61871
  })).finish();
61760
61872
  // AuthInfo with sequence 0 (required for unordered). CosmJS builds this
61761
61873
  // — the pubkey/fee encoding is unchanged from an ordered tx.
@@ -61771,6 +61883,22 @@ class SigningCosmosClient extends CosmosClient {
61771
61883
  })).finish());
61772
61884
  return { base64, accountNumber };
61773
61885
  }
61886
+ /**
61887
+ * account_number for the unordered sign doc. It is assigned once when the
61888
+ * account is created and never changes, so look it up once per signer —
61889
+ * performActionSync signs on every player action and shouldn't pay a REST
61890
+ * round trip (or inherit its failure modes) each time.
61891
+ */
61892
+ async unorderedAccountNumber(player) {
61893
+ const cached = this.accountNumbers.get(player);
61894
+ if (cached !== undefined) {
61895
+ return cached;
61896
+ }
61897
+ const accountInfo = await this.getAccount(player);
61898
+ const accountNumber = Number(accountInfo.account.account_number);
61899
+ this.accountNumbers.set(player, accountNumber);
61900
+ return accountNumber;
61901
+ }
61774
61902
  /**
61775
61903
  * Sign-only MsgJoinGame: builds and signs the player's buy-in tx WITHOUT
61776
61904
  * broadcasting, returning the base64 TxRaw for the gateway to relay
@@ -61869,6 +61997,7 @@ class SigningCosmosClient extends CosmosClient {
61869
61997
  });
61870
61998
  try {
61871
61999
  const result = await this.signingClient.signAndBroadcast(player, [msg], fee, memo);
62000
+ assertExecuted("top up", result);
61872
62001
  console.log("✅ Top-up transaction successful:", result.transactionHash);
61873
62002
  return result.transactionHash;
61874
62003
  }
@@ -61906,6 +62035,7 @@ class SigningCosmosClient extends CosmosClient {
61906
62035
  });
61907
62036
  try {
61908
62037
  const result = await this.signingClient.signAndBroadcast(creator, [msg], fee, memo);
62038
+ assertExecuted("process deposit", result);
61909
62039
  console.log("✅ Process deposit transaction successful:", result.transactionHash);
61910
62040
  return result.transactionHash;
61911
62041
  }
@@ -61945,6 +62075,7 @@ class SigningCosmosClient extends CosmosClient {
61945
62075
  });
61946
62076
  try {
61947
62077
  const result = await this.signingClient.signAndBroadcast(creator, [msg], fee, memo);
62078
+ assertExecuted("initiate withdrawal", result);
61948
62079
  console.log("✅ Withdrawal initiation successful:", result.transactionHash);
61949
62080
  return result.transactionHash;
61950
62081
  }
@@ -61981,6 +62112,7 @@ class SigningCosmosClient extends CosmosClient {
61981
62112
  });
61982
62113
  try {
61983
62114
  const result = await this.signingClient.signAndBroadcast(signer, [msg], fee, memo);
62115
+ assertExecuted("sign withdrawal", result);
61984
62116
  console.log("✅ Withdrawal signing successful:", result.transactionHash);
61985
62117
  return result.transactionHash;
61986
62118
  }
@@ -62061,6 +62193,7 @@ class SigningCosmosClient extends CosmosClient {
62061
62193
  });
62062
62194
  try {
62063
62195
  const result = await this.signingClient.signAndBroadcast(creator, [msg], fee, memo);
62196
+ assertExecuted("register NFT avatar", result);
62064
62197
  console.log("✅ NFT avatar registration successful:", result.transactionHash);
62065
62198
  return result.transactionHash;
62066
62199
  }
@@ -62242,5 +62375,5 @@ const registry = new Registry([
62242
62375
  ...msgTypes,
62243
62376
  ]);
62244
62377
 
62245
- export { AllPlayerActions, BLOCK52_HD_PATH, Board, COSMOS_CONSTANTS, Client, CosmosClient, Deck, GAME_NAME_MICRO_PER_CHAR, GameFormat, GameStatus, GameVariant, HandType, KEYS, MAX_GAME_NAME_LENGTH, MissingWalletError, NonPlayerActionType, Params$c as Params, PlayerActionType, PlayerStatus, PokerGameIntegration, PokerSolver, RPCMethods, SIT_IN_METHOD_NEXT_BB, SIT_IN_METHOD_POST_NOW, SIT_OUT_METHOD_NEXT_BB, SIT_OUT_METHOD_NEXT_HAND, SUIT, SigningCosmosClient, TexasHoldemRound, ValidatorBond, WithdrawalRequest, computeGameNameFee, createSigningClientFromMnemonic, createWalletFromMnemonic, formatGameFormatDisplay, formatGameVariantDisplay, generateWallet, getActionByType, getAddressFromMnemonic, getDefaultCosmosConfig, getGameFormat, getGameFormatForCosmos, getGameFormatFromObject, getGameVariant, hasAction, isCashFormat, isEmptyAddress, isSitAndGoFormat, isTournamentFormat, isValidMnemonic, isValidPlayerAddress, parseGameFormat, parseGameVariant, registry };
62378
+ export { AllPlayerActions, BLOCK52_HD_PATH, Board, COSMOS_CONSTANTS, Client, CosmosClient, Deck, GAME_NAME_MICRO_PER_CHAR, GameFormat, GameStatus, GameVariant, HandType, KEYS, MAX_GAME_NAME_LENGTH, MissingWalletError, NonPlayerActionType, Params$c as Params, PlayerActionType, PlayerStatus, PokerGameIntegration, PokerSolver, RPCMethods, SIT_IN_METHOD_NEXT_BB, SIT_IN_METHOD_POST_NOW, SIT_OUT_METHOD_NEXT_BB, SIT_OUT_METHOD_NEXT_HAND, SUIT, SigningCosmosClient, TexasHoldemRound, TxExecutionError, ValidatorBond, WithdrawalRequest, assertExecuted, computeGameNameFee, createSigningClientFromMnemonic, createWalletFromMnemonic, formatGameFormatDisplay, formatGameVariantDisplay, generateWallet, getActionByType, getAddressFromMnemonic, getDefaultCosmosConfig, getGameFormat, getGameFormatForCosmos, getGameFormatFromObject, getGameVariant, hasAction, isCashFormat, isEmptyAddress, isSitAndGoFormat, isTournamentFormat, isValidMnemonic, isValidPlayerAddress, parseGameFormat, parseGameVariant, registry, txFailureHash, txFailurePhase };
62246
62379
  //# sourceMappingURL=index.esm.js.map