@molteee/arena-tools 0.2.6 → 0.2.7

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/client.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // Viem client setup — public client for reads, wallet client for writes.
2
2
  import { createPublicClient, createWalletClient, http, webSocket, fallback, defineChain, } from "viem";
3
3
  import { privateKeyToAccount } from "viem/accounts";
4
- import { RPC_URL, WS_RPC_URL, CHAIN_ID, CHAIN_NAME, getPrivateKey } from "./config.js";
4
+ import { RPC_URL, WS_RPC_URL, FALLBACK_RPC_URL, CHAIN_ID, CHAIN_NAME, getPrivateKey } from "./config.js";
5
5
  // Define Monad testnet chain
6
6
  export const monadTestnet = defineChain({
7
7
  id: CHAIN_ID,
@@ -17,9 +17,15 @@ export const monadTestnet = defineChain({
17
17
  },
18
18
  },
19
19
  });
20
- // Shared transport: WebSocket primary, HTTP fallback
21
- // WS gives real-time updates without polling; HTTP catches WS failures
22
- const transport = fallback([webSocket(WS_RPC_URL), http(RPC_URL)]);
20
+ // Retry config for 429 rate limit errors — exponential backoff
21
+ const retryOpts = { retryCount: 3, retryDelay: 1500 };
22
+ // Transport priority: WS (lowest latency) → Alchemy HTTP → Monad public HTTP (separate rate limit pool)
23
+ // If Alchemy 429s, viem's fallback auto-switches to the next transport
24
+ const transport = fallback([
25
+ webSocket(WS_RPC_URL),
26
+ http(RPC_URL, { retryCount: 2, retryDelay: 1000 }),
27
+ http(FALLBACK_RPC_URL, retryOpts),
28
+ ]);
23
29
  // Public client — always available, no private key needed
24
30
  let _publicClient = null;
25
31
  export function getPublicClient() {
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,OAAO,EACH,kBAAkB,EAClB,kBAAkB,EAClB,IAAI,EACJ,SAAS,EACT,QAAQ,EACR,WAAW,GACd,MAAM,MAAM,CAAC;AACd,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEvF,6BAA6B;AAC7B,MAAM,CAAC,MAAM,YAAY,GAAG,WAAW,CAAC;IACpC,EAAE,EAAE,QAAQ;IACZ,IAAI,EAAE,UAAU;IAChB,cAAc,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE;IAC5D,OAAO,EAAE;QACL,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC,UAAU,CAAC,EAAE;KACxD;IACD,cAAc,EAAE;QACZ,OAAO,EAAE;YACL,IAAI,EAAE,gBAAgB;YACtB,GAAG,EAAE,mCAAmC;SAC3C;KACJ;CACJ,CAAC,CAAC;AAEH,qDAAqD;AACrD,uEAAuE;AACvE,MAAM,SAAS,GAAG,QAAQ,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAEnE,0DAA0D;AAC1D,IAAI,aAAa,GAAQ,IAAI,CAAC;AAC9B,MAAM,UAAU,eAAe;IAC3B,IAAI,CAAC,aAAa,EAAE,CAAC;QACjB,aAAa,GAAG,kBAAkB,CAAC;YAC/B,KAAK,EAAE,YAAY;YACnB,SAAS;SACZ,CAAC,CAAC;IACP,CAAC;IACD,OAAO,aAAa,CAAC;AACzB,CAAC;AAED,6DAA6D;AAC7D,IAAI,aAAa,GAAQ,IAAI,CAAC;AAC9B,MAAM,UAAU,eAAe;IAC3B,IAAI,CAAC,aAAa,EAAE,CAAC;QACjB,MAAM,OAAO,GAAG,mBAAmB,CAAC,aAAa,EAAE,CAAC,CAAC;QACrD,aAAa,GAAG,kBAAkB,CAAC;YAC/B,OAAO;YACP,KAAK,EAAE,YAAY;YACnB,SAAS;SACZ,CAAC,CAAC;IACP,CAAC;IACD,OAAO,aAAa,CAAC;AACzB,CAAC;AAED,4CAA4C;AAC5C,MAAM,UAAU,UAAU;IACtB,OAAO,eAAe,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC;AAC7C,CAAC"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,OAAO,EACH,kBAAkB,EAClB,kBAAkB,EAClB,IAAI,EACJ,SAAS,EACT,QAAQ,EACR,WAAW,GACd,MAAM,MAAM,CAAC;AACd,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,QAAQ,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEzG,6BAA6B;AAC7B,MAAM,CAAC,MAAM,YAAY,GAAG,WAAW,CAAC;IACpC,EAAE,EAAE,QAAQ;IACZ,IAAI,EAAE,UAAU;IAChB,cAAc,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE;IAC5D,OAAO,EAAE;QACL,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC,UAAU,CAAC,EAAE;KACxD;IACD,cAAc,EAAE;QACZ,OAAO,EAAE;YACL,IAAI,EAAE,gBAAgB;YACtB,GAAG,EAAE,mCAAmC;SAC3C;KACJ;CACJ,CAAC,CAAC;AAEH,+DAA+D;AAC/D,MAAM,SAAS,GAAG,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;AAEtD,wGAAwG;AACxG,uEAAuE;AACvE,MAAM,SAAS,GAAG,QAAQ,CAAC;IACvB,SAAS,CAAC,UAAU,CAAC;IACrB,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;IAClD,IAAI,CAAC,gBAAgB,EAAE,SAAS,CAAC;CACpC,CAAC,CAAC;AAEH,0DAA0D;AAC1D,IAAI,aAAa,GAAQ,IAAI,CAAC;AAC9B,MAAM,UAAU,eAAe;IAC3B,IAAI,CAAC,aAAa,EAAE,CAAC;QACjB,aAAa,GAAG,kBAAkB,CAAC;YAC/B,KAAK,EAAE,YAAY;YACnB,SAAS;SACZ,CAAC,CAAC;IACP,CAAC;IACD,OAAO,aAAa,CAAC;AACzB,CAAC;AAED,6DAA6D;AAC7D,IAAI,aAAa,GAAQ,IAAI,CAAC;AAC9B,MAAM,UAAU,eAAe;IAC3B,IAAI,CAAC,aAAa,EAAE,CAAC;QACjB,MAAM,OAAO,GAAG,mBAAmB,CAAC,aAAa,EAAE,CAAC,CAAC;QACrD,aAAa,GAAG,kBAAkB,CAAC;YAC/B,OAAO;YACP,KAAK,EAAE,YAAY;YACnB,SAAS;SACZ,CAAC,CAAC;IACP,CAAC;IACD,OAAO,aAAa,CAAC;AACzB,CAAC;AAED,4CAA4C;AAC5C,MAAM,UAAU,UAAU;IACtB,OAAO,eAAe,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC;AAC7C,CAAC"}
package/dist/config.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export declare const RPC_URL: string;
2
2
  export declare const WS_RPC_URL: string;
3
+ export declare const FALLBACK_RPC_URL: string;
3
4
  export declare const CHAIN_ID = 10143;
4
5
  export declare const CHAIN_NAME = "Monad Testnet";
5
6
  export declare const EXPLORER_URL = "https://testnet.monadexplorer.com";
package/dist/config.js CHANGED
@@ -9,9 +9,12 @@ dotenvConfig({ path: path.resolve(process.cwd(), ".env.local") });
9
9
  dotenvConfig({ path: path.resolve(process.cwd(), "..", ".env") });
10
10
  dotenvConfig({ path: path.resolve(process.cwd(), "..", "..", ".env") });
11
11
  // ─── Network ─────────────────────────────────────────────────────────────────
12
+ // Primary RPC (Alchemy) — higher reliability, but rate-limited on free tier
12
13
  export const RPC_URL = process.env.MONAD_RPC_URL || "https://monad-testnet.g.alchemy.com/v2/uMvEY1mdMyM8svqTZD-p3";
13
14
  // WebSocket RPC — primary transport for lower latency and no polling rate limits
14
15
  export const WS_RPC_URL = process.env.MONAD_WS_RPC_URL || "wss://monad-testnet.g.alchemy.com/v2/uMvEY1mdMyM8svqTZD-p3";
16
+ // Fallback RPC (Monad public) — separate rate limit pool, used when Alchemy 429s
17
+ export const FALLBACK_RPC_URL = process.env.MONAD_FALLBACK_RPC_URL || "https://testnet-rpc.monad.xyz";
15
18
  export const CHAIN_ID = 10143;
16
19
  export const CHAIN_NAME = "Monad Testnet";
17
20
  export const EXPLORER_URL = "https://testnet.monadexplorer.com";
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  /** Print a success response and exit */
2
2
  export declare function ok(data: any): never;
3
- /** Print an error response and exit */
3
+ /** Print an error response and exit.
4
+ * Uses stdout (not stderr) so JSON output is always visible even with 2>/dev/null. */
4
5
  export declare function fail(error: string, code: string): never;
5
6
  /** Print a streaming event (JSONL — one JSON object per line) */
6
7
  export declare function event(data: any): void;
@@ -4,9 +4,10 @@ export function ok(data) {
4
4
  console.log(JSON.stringify({ ok: true, data }, null, 2));
5
5
  process.exit(0);
6
6
  }
7
- /** Print an error response and exit */
7
+ /** Print an error response and exit.
8
+ * Uses stdout (not stderr) so JSON output is always visible even with 2>/dev/null. */
8
9
  export function fail(error, code) {
9
- console.error(JSON.stringify({ ok: false, error, code }, null, 2));
10
+ console.log(JSON.stringify({ ok: false, error, code }, null, 2));
10
11
  process.exit(1);
11
12
  }
12
13
  /** Print a streaming event (JSONL — one JSON object per line) */
@@ -1 +1 @@
1
- {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/utils/output.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAE7E,wCAAwC;AACxC,MAAM,UAAU,EAAE,CAAC,IAAS;IACxB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACzD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC;AAED,uCAAuC;AACvC,MAAM,UAAU,IAAI,CAAC,KAAa,EAAE,IAAY;IAC5C,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACnE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,KAAK,CAAC,IAAS;IAC3B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;AACtC,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,WAAW,CAAC,EAAqC;IAC7D,OAAO,CAAC,KAAK,EAAE,GAAG,IAAW,EAAE,EAAE;QAC7B,IAAI,CAAC;YACD,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;QACtB,CAAC;QACD,OAAO,GAAQ,EAAE,CAAC;YACd,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,IAAI,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;QACtC,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/utils/output.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAE7E,wCAAwC;AACxC,MAAM,UAAU,EAAE,CAAC,IAAS;IACxB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACzD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC;AAED;uFACuF;AACvF,MAAM,UAAU,IAAI,CAAC,KAAa,EAAE,IAAY;IAC5C,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,KAAK,CAAC,IAAS;IAC3B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;AACtC,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,WAAW,CAAC,EAAqC;IAC7D,OAAO,CAAC,KAAK,EAAE,GAAG,IAAW,EAAE,EAAE;QAC7B,IAAI,CAAC;YACD,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;QACtB,CAAC;QACD,OAAO,GAAQ,EAAE,CAAC;YACd,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,IAAI,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;QACtC,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -1,5 +1,7 @@
1
1
  /**
2
- * Send a write transaction with gas estimation.
2
+ * Send a write transaction with automatic retry on 429 rate limits.
3
+ * By default uses a fixed gas limit (300k) to skip estimateGas and save an RPC call.
4
+ * Set ARENA_ESTIMATE_GAS=1 to use dynamic gas estimation instead.
3
5
  * Returns the transaction hash, gas used, and receipt logs.
4
6
  */
5
7
  export declare function sendTx(params: {
package/dist/utils/tx.js CHANGED
@@ -1,35 +1,79 @@
1
1
  import { getPublicClient, getWalletClient } from "../client.js";
2
+ // Default gas limit — skips estimateGas to save 1 RPC call per transaction.
3
+ // 1M covers all arena contracts including claim-timeout which triggers
4
+ // _resolveRound + _settleGame + escrow.settle() + ELO updates (~600k+ gas).
5
+ // On Monad you only pay for gas USED, not the limit, so overshooting is free.
6
+ // Set ARENA_ESTIMATE_GAS=1 to use dynamic estimation instead.
7
+ const DEFAULT_GAS = 1000000n;
8
+ const SHOULD_ESTIMATE = !!process.env.ARENA_ESTIMATE_GAS;
9
+ // Max retries for 429 rate limit errors at the sendTx level
10
+ const MAX_RETRIES = 3;
11
+ const BASE_DELAY_MS = 2000;
12
+ /** Check if an error is a 429 rate limit error */
13
+ function isRateLimited(err) {
14
+ const msg = err instanceof Error ? err.message : String(err);
15
+ return msg.includes("429") || msg.includes("Too Many Requests") || msg.includes("compute units");
16
+ }
17
+ /** Sleep for ms milliseconds */
18
+ function sleep(ms) {
19
+ return new Promise((r) => setTimeout(r, ms));
20
+ }
2
21
  /**
3
- * Send a write transaction with gas estimation.
22
+ * Send a write transaction with automatic retry on 429 rate limits.
23
+ * By default uses a fixed gas limit (300k) to skip estimateGas and save an RPC call.
24
+ * Set ARENA_ESTIMATE_GAS=1 to use dynamic gas estimation instead.
4
25
  * Returns the transaction hash, gas used, and receipt logs.
5
26
  */
6
27
  export async function sendTx(params) {
7
28
  const publicClient = getPublicClient();
8
29
  const walletClient = getWalletClient();
9
30
  const account = walletClient.account;
10
- // Estimate gas with 1.5x buffer (Monad needs more than Ethereum)
11
- const gasEstimate = await publicClient.estimateGas({
12
- account: account.address,
13
- to: params.to,
14
- data: params.data,
15
- value: params.value ?? 0n,
16
- });
17
- const gas = (gasEstimate * 3n) / 2n;
18
- // Send transaction
19
- const hash = await walletClient.sendTransaction({
20
- to: params.to,
21
- data: params.data,
22
- value: params.value ?? 0n,
23
- gas,
24
- });
25
- // Wait for confirmation
26
- const receipt = await publicClient.waitForTransactionReceipt({
27
- hash,
28
- timeout: 60_000,
29
- });
30
- if (receipt.status === "reverted") {
31
- throw new Error(`Transaction reverted: ${hash}`);
31
+ let lastError;
32
+ for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
33
+ try {
34
+ // Gas: use fixed default or estimate dynamically
35
+ let gas = DEFAULT_GAS;
36
+ if (SHOULD_ESTIMATE) {
37
+ const gasEstimate = await publicClient.estimateGas({
38
+ account: account.address,
39
+ to: params.to,
40
+ data: params.data,
41
+ value: params.value ?? 0n,
42
+ });
43
+ // 1.5x buffer — Monad needs more headroom than Ethereum
44
+ gas = (gasEstimate * 3n) / 2n;
45
+ }
46
+ // Send transaction
47
+ const hash = await walletClient.sendTransaction({
48
+ to: params.to,
49
+ data: params.data,
50
+ value: params.value ?? 0n,
51
+ gas,
52
+ });
53
+ // Wait for confirmation
54
+ const receipt = await publicClient.waitForTransactionReceipt({
55
+ hash,
56
+ timeout: 60_000,
57
+ });
58
+ if (receipt.status === "reverted") {
59
+ throw new Error(`Transaction reverted: ${hash}`);
60
+ }
61
+ return { hash, gasUsed: receipt.gasUsed, logs: receipt.logs };
62
+ }
63
+ catch (err) {
64
+ lastError = err;
65
+ // Only retry on rate limit errors, not reverts or other failures
66
+ if (isRateLimited(err) && attempt < MAX_RETRIES) {
67
+ // Exponential backoff: 2s, 4s, 8s
68
+ const delay = BASE_DELAY_MS * Math.pow(2, attempt);
69
+ process.stderr.write(`[arena-tools] Rate limited (429), retrying in ${delay}ms (attempt ${attempt + 1}/${MAX_RETRIES})...\n`);
70
+ await sleep(delay);
71
+ continue;
72
+ }
73
+ throw err;
74
+ }
32
75
  }
33
- return { hash, gasUsed: receipt.gasUsed, logs: receipt.logs };
76
+ // Should not reach here, but just in case
77
+ throw lastError;
34
78
  }
35
79
  //# sourceMappingURL=tx.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tx.js","sourceRoot":"","sources":["../../src/utils/tx.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEhE;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,MAAkE;IAC3F,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;IACvC,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;IACvC,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC;IAErC,iEAAiE;IACjE,MAAM,WAAW,GAAG,MAAM,YAAY,CAAC,WAAW,CAAC;QAC/C,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,EAAE;KAC5B,CAAC,CAAC;IACH,MAAM,GAAG,GAAG,CAAC,WAAW,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;IAEpC,mBAAmB;IACnB,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,eAAe,CAAC;QAC5C,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,EAAE;QACzB,GAAG;KACN,CAAC,CAAC;IAEH,wBAAwB;IACxB,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,yBAAyB,CAAC;QACzD,IAAI;QACJ,OAAO,EAAE,MAAM;KAClB,CAAC,CAAC;IAEH,IAAI,OAAO,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;AAClE,CAAC"}
1
+ {"version":3,"file":"tx.js","sourceRoot":"","sources":["../../src/utils/tx.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@molteee/arena-tools",
3
- "version": "0.2.6",
3
+ "version": "0.2.7",
4
4
  "description": "CLI tool for interacting with the Molteee Gaming Arena on Monad testnet",
5
5
  "type": "module",
6
6
  "bin": {