starknet 10.5.0 → 10.5.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/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## [10.5.2](https://github.com/starknet-io/starknet.js/compare/v10.5.1...v10.5.2) (2026-07-22)
2
+
3
+ ### Bug Fixes
4
+
5
+ - provider: correct getBlock() default return type and add JSDoc ([b161c46](https://github.com/starknet-io/starknet.js/commit/b161c468613133c9325c4fe38d20bb09524afbea))
6
+
7
+ ## [10.5.1](https://github.com/starknet-io/starknet.js/compare/v10.5.0...v10.5.1) (2026-07-21)
8
+
9
+ ### Bug Fixes
10
+
11
+ - ws bound reconnection of a flapping connection ([#1650](https://github.com/starknet-io/starknet.js/issues/1650)) ([241c6c1](https://github.com/starknet-io/starknet.js/commit/241c6c11301a29a22e09a4b8873c236e39326d29))
12
+
1
13
  # [10.5.0](https://github.com/starknet-io/starknet.js/compare/v10.4.0...v10.5.0) (2026-07-06)
2
14
 
3
15
  ### Features
package/README.md CHANGED
@@ -29,9 +29,6 @@
29
29
  <a href="https://starkware.co/">
30
30
  <img src="https://img.shields.io/badge/powered_by-StarkWare-navy">
31
31
  </a>
32
- <a href="https://twitter.com/starknetjs">
33
- <img src="https://img.shields.io/badge/follow_us-Twitter-blue">
34
- </a>
35
32
  <a href="https://www.drips.network/app/projects/github/starknet-io/starknet.js" target="_blank">
36
33
  <img src="https://www.drips.network/api/embed/project/https%3A%2F%2Fgithub.com%2Fstarknet-io%2Fstarknet.js/support.png?background=light&style=github&text=project&stat=none" alt="Support starknet.js on drips.network" height="20">
37
34
  </a>
@@ -58,6 +55,22 @@ How to [Guides](https://starknet-io.github.io/starknet.js/docs/guides/intro) :bo
58
55
 
59
56
  Play with [Code Examples](https://github.com/PhilippeR26/starknet.js-workshop-typescript) :video_game:
60
57
 
58
+ ## 🤖 Using AI
59
+
60
+ AI training data about starknet.js is often outdated. To give your AI coding agent accurate, up-to-date guidance, install the official starknet.js skill ([`skills/starknet-js/`](./skills/starknet-js/)). It works with Claude Code, Codex, Cursor, Gemini CLI, and any other agent supporting the open [Agent Skills](https://agentskills.io/) standard.
61
+
62
+ ```bash
63
+ npx skills add starknet-io/starknet.js
64
+ ```
65
+
66
+ or copy the skill files directly:
67
+
68
+ ```bash
69
+ mkdir -p ~/.claude/skills/starknet-js && curl -s --output-dir ~/.claude/skills/starknet-js --remote-name-all "https://raw.githubusercontent.com/starknet-io/starknet.js/develop/skills/starknet-js/{SKILL.md,calldata.md,interacting.md}"
70
+ ```
71
+
72
+ > This command installs into Claude Code's skills folder — adapt the target directory for other agents.
73
+
61
74
  ## ✏️ Contributing
62
75
 
63
76
  If you consider to contribute to this project please read [CONTRIBUTING.md](https://github.com/starknet-io/starknet.js/blob/main/CONTRIBUTING.md) first.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as RPCSPEC0103 from '@starknet-io/starknet-types-0103';
2
- import { PAYMASTER_API, CONTRACT, EDataAvailabilityMode as EDataAvailabilityMode$1, ETransactionType, SUBSCRIPTION_BLOCK_ID, TypedData, CONTRACT_STORAGE_KEYS, StorageProof, CASM_COMPILED_CONTRACT_CLASS, OutsideExecutionTypedData, ETransactionVersion3 as ETransactionVersion3$1, IsType, TransactionReceipt as TransactionReceipt$1, IsSucceeded, IsReverted, PRE_CONFIRMED_BLOCK_WITH_TX_HASHES, BLOCK_WITH_TX_HASHES, TransactionHash, BlockHash, FAILED_TO_RECEIVE_TXN, NO_TRACE_AVAILABLE, CONTRACT_NOT_FOUND, ENTRYPOINT_NOT_FOUND, BLOCK_NOT_FOUND, INVALID_TXN_INDEX, CLASS_HASH_NOT_FOUND, TXN_HASH_NOT_FOUND, PAGE_SIZE_TOO_BIG, NO_BLOCKS, INVALID_CONTINUATION_TOKEN, TOO_MANY_KEYS_IN_FILTER, CONTRACT_ERROR, TRANSACTION_EXECUTION_ERROR, STORAGE_PROOF_NOT_SUPPORTED, CLASS_ALREADY_DECLARED, INVALID_TRANSACTION_NONCE, INSUFFICIENT_RESOURCES_FOR_VALIDATE, INSUFFICIENT_ACCOUNT_BALANCE, VALIDATION_FAILURE, COMPILATION_FAILED, CONTRACT_CLASS_SIZE_IS_TOO_LARGE, NON_ACCOUNT, DUPLICATE_TX, COMPILED_CLASS_HASH_MISMATCH, UNSUPPORTED_TX_VERSION, UNSUPPORTED_CONTRACT_CLASS_VERSION, UNEXPECTED_ERROR, REPLACEMENT_TRANSACTION_UNDERPRICED, FEE_BELOW_MINIMUM, INVALID_SUBSCRIPTION_ID, TOO_MANY_ADDRESSES_IN_FILTER, TOO_MANY_BLOCKS_BACK, COMPILATION_ERROR, ETransactionVersion as ETransactionVersion$1, SUBSCRIPTION_ID, TXN_FINALITY_STATUS, STATUS_ACCEPTED_ON_L1, TXN_STATUS_WITHOUT_L1, StarknetEventsEvent, TransactionsStatusEvent, NewTransactionReceiptsEvent, NewTransactionEvent, NewHeadsEvent, STORAGE_RESULT, INVOKE_TXN_V3, StarknetWindowObject, AccountChangeEventHandler, NetworkChangeEventHandler, WatchAssetParameters, AddStarknetChainParameters, Signature as Signature$1, STRK20_PROOF, Address, STRK20_BALANCE_ENTRY, STRK20_ACTION, STRK20_CALL_AND_PROOF, EDAMode as EDAMode$1, StarknetType, StarknetMerkleType, TypedDataRevision, OutsideCallV1, OutsideCallV2, EmittedEvent as EmittedEvent$1, Event as Event$2, Permission, ChainId, AccountDeploymentData, AddInvokeTransactionParameters, AddInvokeTransactionResult, AddDeclareTransactionParameters, AddDeclareTransactionResult, SpecVersion, API_VERSION as API_VERSION$1 } from '@starknet-io/starknet-types-0103';
2
+ import { PAYMASTER_API, CONTRACT, EDataAvailabilityMode as EDataAvailabilityMode$1, ETransactionType, SUBSCRIPTION_BLOCK_ID, TypedData, CONTRACT_STORAGE_KEYS, StorageProof, CASM_COMPILED_CONTRACT_CLASS, OutsideExecutionTypedData, ETransactionVersion3 as ETransactionVersion3$1, IsType, TransactionReceipt as TransactionReceipt$1, IsSucceeded, IsReverted, BLOCK_WITH_TX_HASHES, PRE_CONFIRMED_BLOCK_WITH_TX_HASHES, TransactionHash, BlockHash, FAILED_TO_RECEIVE_TXN, NO_TRACE_AVAILABLE, CONTRACT_NOT_FOUND, ENTRYPOINT_NOT_FOUND, BLOCK_NOT_FOUND, INVALID_TXN_INDEX, CLASS_HASH_NOT_FOUND, TXN_HASH_NOT_FOUND, PAGE_SIZE_TOO_BIG, NO_BLOCKS, INVALID_CONTINUATION_TOKEN, TOO_MANY_KEYS_IN_FILTER, CONTRACT_ERROR, TRANSACTION_EXECUTION_ERROR, STORAGE_PROOF_NOT_SUPPORTED, CLASS_ALREADY_DECLARED, INVALID_TRANSACTION_NONCE, INSUFFICIENT_RESOURCES_FOR_VALIDATE, INSUFFICIENT_ACCOUNT_BALANCE, VALIDATION_FAILURE, COMPILATION_FAILED, CONTRACT_CLASS_SIZE_IS_TOO_LARGE, NON_ACCOUNT, DUPLICATE_TX, COMPILED_CLASS_HASH_MISMATCH, UNSUPPORTED_TX_VERSION, UNSUPPORTED_CONTRACT_CLASS_VERSION, UNEXPECTED_ERROR, REPLACEMENT_TRANSACTION_UNDERPRICED, FEE_BELOW_MINIMUM, INVALID_SUBSCRIPTION_ID, TOO_MANY_ADDRESSES_IN_FILTER, TOO_MANY_BLOCKS_BACK, COMPILATION_ERROR, ETransactionVersion as ETransactionVersion$1, SUBSCRIPTION_ID, TXN_FINALITY_STATUS, STATUS_ACCEPTED_ON_L1, TXN_STATUS_WITHOUT_L1, StarknetEventsEvent, TransactionsStatusEvent, NewTransactionReceiptsEvent, NewTransactionEvent, NewHeadsEvent, STORAGE_RESULT, INVOKE_TXN_V3, StarknetWindowObject, AccountChangeEventHandler, NetworkChangeEventHandler, WatchAssetParameters, AddStarknetChainParameters, Signature as Signature$1, STRK20_PROOF, Address, STRK20_BALANCE_ENTRY, STRK20_ACTION, STRK20_CALL_AND_PROOF, EDAMode as EDAMode$1, StarknetType, StarknetMerkleType, TypedDataRevision, OutsideCallV1, OutsideCallV2, EmittedEvent as EmittedEvent$1, Event as Event$2, Permission, ChainId, AccountDeploymentData, AddInvokeTransactionParameters, AddInvokeTransactionResult, AddDeclareTransactionParameters, AddDeclareTransactionResult, SpecVersion, API_VERSION as API_VERSION$1 } from '@starknet-io/starknet-types-0103';
3
3
  export { STRK20_ACTION, STRK20_BALANCE_ENTRY, STRK20_CALLDATA_ITEM, STRK20_CALLDATA_PLACEHOLDER, STRK20_CALL_AND_PROOF, STRK20_DEPOSIT_ACTION, STRK20_INVOKE_ACTION, STRK20_PROOF, STRK20_TRANSFER_ACTION, STRK20_WITHDRAW_ACTION, StarknetDomain, StarknetEnumType, StarknetMerkleType, StarknetType, TypedData, TypedDataRevision } from '@starknet-io/starknet-types-0103';
4
4
  import * as RPC$1 from '@starknet-io/starknet-types-0101';
5
5
  import { WatchAssetParameters as WatchAssetParameters$1, AddStarknetChainParameters as AddStarknetChainParameters$1, Signature as Signature$2, Address as Address$1, Permission as Permission$1, ChainId as ChainId$1, AccountDeploymentData as AccountDeploymentData$1, AddInvokeTransactionParameters as AddInvokeTransactionParameters$1, AddInvokeTransactionResult as AddInvokeTransactionResult$1, AddDeclareTransactionParameters as AddDeclareTransactionParameters$1, AddDeclareTransactionResult as AddDeclareTransactionResult$1, TypedData as TypedData$1, SpecVersion as SpecVersion$1, API_VERSION as API_VERSION$2 } from '@starknet-io/starknet-types-0101';
@@ -1008,11 +1008,50 @@ declare abstract class ProviderInterface {
1008
1008
  */
1009
1009
  abstract callContract(call: Call, blockIdentifier?: BlockIdentifier): Promise<CallContractResponse>;
1010
1010
  /**
1011
- * Gets the block information
1011
+ * Gets the header and the transaction hashes of a block (RPC `starknet_getBlockWithTxHashes`).
1012
1012
  *
1013
- * @returns the block object
1013
+ * The response contains the block metadata (hash, number, parent hash, timestamp, status,
1014
+ * gas prices, sequencer address, ...) plus a `transactions` array holding only the **hashes**
1015
+ * of the transactions included in the block — not their content.
1016
+ * To get the full transactions use {@link getBlockWithTxs}, and for their receipts use
1017
+ * {@link getBlockWithReceipts}.
1018
+ *
1019
+ * @param blockIdentifier - which block to fetch. Accepts:
1020
+ * - a block number: `number` or decimal `string` (e.g. `123456`)
1021
+ * - a block hash: hex `string` or `bigint` (e.g. `'0x3a1b...'`)
1022
+ * - a block tag `string`:
1023
+ * - `'latest'` — the most recent block already accepted on L2
1024
+ * - `'pre_confirmed'` — the block currently being built, not yet closed (its fields differ:
1025
+ * no `block_hash`/`status`, hence the dedicated {@link PreConfirmedBlock} return type)
1026
+ * - `null` — resolved as the `'latest'` tag
1027
+ *
1028
+ * When omitted, the provider's default block identifier is used (`'latest'`).
1029
+ *
1030
+ * @returns the block header together with the list of its transaction hashes
1031
+ *
1032
+ * @example
1033
+ * ```typescript
1034
+ * const block = await provider.getBlock('latest');
1035
+ * // {
1036
+ * // status: 'ACCEPTED_ON_L2',
1037
+ * // block_hash: '0x3a1b...',
1038
+ * // block_number: 123456,
1039
+ * // parent_hash: '0x28f5...',
1040
+ * // timestamp: 1700000000,
1041
+ * // sequencer_address: '0x1176a1...',
1042
+ * // transactions: ['0x1d2c...', '0x5e8f...'], // transaction hashes only
1043
+ * // ...
1044
+ * // }
1045
+ *
1046
+ * // By block number or hash:
1047
+ * await provider.getBlock(123456);
1048
+ * await provider.getBlock('0x3a1b...');
1049
+ *
1050
+ * // Block still being built (fields differ from a closed block):
1051
+ * const pending = await provider.getBlock('pre_confirmed');
1052
+ * ```
1014
1053
  */
1015
- abstract getBlock(): Promise<PreConfirmedBlock>;
1054
+ abstract getBlock(): Promise<Block$1>;
1016
1055
  abstract getBlock(blockIdentifier: 'pre_confirmed'): Promise<PreConfirmedBlock>;
1017
1056
  abstract getBlock(blockIdentifier: 'latest'): Promise<Block$1>;
1018
1057
  abstract getBlock(blockIdentifier: BlockIdentifier): Promise<GetBlockResponse>;
@@ -5006,6 +5045,14 @@ type ReconnectOptions = {
5006
5045
  * @default true
5007
5046
  */
5008
5047
  exponential?: number | boolean;
5048
+ /**
5049
+ * The minimum time in milliseconds a reconnected connection must stay open before
5050
+ * it is considered stable and the retry counter is reset. This prevents a gateway
5051
+ * that accepts the connection then immediately drops it (a "flapping" connection)
5052
+ * from resetting the counter on every cycle and reconnecting forever.
5053
+ * @default 5000
5054
+ */
5055
+ stableConnectionThreshold?: number;
5009
5056
  };
5010
5057
  /**
5011
5058
  * The type of the WebSocket implementation.
@@ -5098,6 +5145,7 @@ declare class WebSocketChannel {
5098
5145
  private reconnectAttempts;
5099
5146
  private userInitiatedClose;
5100
5147
  private reconnectTimeoutId;
5148
+ private reconnectStabilityTimeoutId;
5101
5149
  private requestQueue;
5102
5150
  private events;
5103
5151
  private openListener;
@@ -5192,6 +5240,13 @@ declare class WebSocketChannel {
5192
5240
  reconnect(): void;
5193
5241
  private _processRequestQueue;
5194
5242
  private _restoreSubscriptions;
5243
+ /**
5244
+ * Reset the reconnection attempt counter, but only once the current connection has
5245
+ * stayed open for `stableConnectionThreshold` ms. A connection that opens and then
5246
+ * immediately drops (a flapping gateway) never reaches this point, so its attempts
5247
+ * keep accumulating toward the retry cap instead of resetting every cycle.
5248
+ */
5249
+ private scheduleReconnectAttemptsReset;
5195
5250
  private _startReconnect;
5196
5251
  private onCloseProxy;
5197
5252
  private onMessageProxy;
@@ -5543,7 +5598,7 @@ declare class RpcProvider implements ProviderInterface {
5543
5598
  setUpSpecVersion(): Promise<"0.9.0" | "0.10.0" | "0.10.2" | "0.10.3">;
5544
5599
  getStarknetVersion(blockIdentifier?: BlockIdentifier): Promise<string>;
5545
5600
  getNonceForAddress(contractAddress: BigNumberish, blockIdentifier?: BlockIdentifier): Promise<string>;
5546
- getBlock(): Promise<PreConfirmedBlock>;
5601
+ getBlock(): Promise<Block$1>;
5547
5602
  getBlock(blockIdentifier: 'pre_confirmed'): Promise<PreConfirmedBlock>;
5548
5603
  getBlock(blockIdentifier: 'latest'): Promise<Block$1>;
5549
5604
  getBlock(blockIdentifier: BlockIdentifier): Promise<GetBlockResponse>;
@@ -12608,9 +12608,15 @@ ${indent}}` : "}";
12608
12608
  reconnectAttempts = 0;
12609
12609
  userInitiatedClose = false;
12610
12610
  reconnectTimeoutId = null;
12611
+ // Fires once a (re)connection has stayed open long enough to be considered stable,
12612
+ // resetting the reconnection attempt counter.
12613
+ reconnectStabilityTimeoutId = null;
12611
12614
  requestQueue = [];
12612
12615
  events = new EventEmitter();
12613
- openListener = (ev) => this.events.emit("open", ev);
12616
+ openListener = (ev) => {
12617
+ this.scheduleReconnectAttemptsReset();
12618
+ this.events.emit("open", ev);
12619
+ };
12614
12620
  closeListener = this.onCloseProxy.bind(this);
12615
12621
  messageListener = this.onMessageProxy.bind(this);
12616
12622
  errorListener = (ev) => this.events.emit("error", ev);
@@ -12630,7 +12636,8 @@ ${indent}}` : "}";
12630
12636
  this.reconnectOptions = {
12631
12637
  retries: options.reconnectOptions?.retries ?? 5,
12632
12638
  delay: options.reconnectOptions?.delay ?? 2e3,
12633
- exponential: options.reconnectOptions?.exponential ?? true
12639
+ exponential: options.reconnectOptions?.exponential ?? true,
12640
+ stableConnectionThreshold: options.reconnectOptions?.stableConnectionThreshold ?? 5e3
12634
12641
  };
12635
12642
  this.requestTimeout = options.requestTimeout ?? 6e4;
12636
12643
  this.WsImplementation = options.websocket || config.get("websocket") || ws_default;
@@ -12777,8 +12784,12 @@ ${indent}}` : "}";
12777
12784
  clearTimeout(this.reconnectTimeoutId);
12778
12785
  this.reconnectTimeoutId = null;
12779
12786
  }
12780
- this.websocket.close(code, reason);
12787
+ if (this.reconnectStabilityTimeoutId) {
12788
+ clearTimeout(this.reconnectStabilityTimeoutId);
12789
+ this.reconnectStabilityTimeoutId = null;
12790
+ }
12781
12791
  this.userInitiatedClose = true;
12792
+ this.websocket.close(code, reason);
12782
12793
  }
12783
12794
  /**
12784
12795
  * Returns a Promise that resolves when the WebSocket connection is closed.
@@ -12865,12 +12876,30 @@ ${indent}}` : "}";
12865
12876
  });
12866
12877
  await Promise.all(restorePromises);
12867
12878
  }
12879
+ /**
12880
+ * Reset the reconnection attempt counter, but only once the current connection has
12881
+ * stayed open for `stableConnectionThreshold` ms. A connection that opens and then
12882
+ * immediately drops (a flapping gateway) never reaches this point, so its attempts
12883
+ * keep accumulating toward the retry cap instead of resetting every cycle.
12884
+ */
12885
+ scheduleReconnectAttemptsReset() {
12886
+ if (this.reconnectStabilityTimeoutId) {
12887
+ clearTimeout(this.reconnectStabilityTimeoutId);
12888
+ }
12889
+ this.reconnectStabilityTimeoutId = setTimeout(() => {
12890
+ this.reconnectAttempts = 0;
12891
+ this.reconnectStabilityTimeoutId = null;
12892
+ }, this.reconnectOptions.stableConnectionThreshold);
12893
+ }
12868
12894
  _startReconnect() {
12869
12895
  if (this.isReconnecting || !this.autoReconnect) {
12870
12896
  return;
12871
12897
  }
12898
+ if (this.reconnectStabilityTimeoutId) {
12899
+ clearTimeout(this.reconnectStabilityTimeoutId);
12900
+ this.reconnectStabilityTimeoutId = null;
12901
+ }
12872
12902
  this.isReconnecting = true;
12873
- this.reconnectAttempts = 0;
12874
12903
  const tryReconnect = () => {
12875
12904
  if (this.reconnectAttempts >= this.reconnectOptions.retries) {
12876
12905
  logger.error("WebSocket: Maximum reconnection retries reached. Giving up.");
@@ -12885,7 +12914,6 @@ ${indent}}` : "}";
12885
12914
  this.websocket.onopen = async () => {
12886
12915
  logger.info("WebSocket: Reconnection successful.");
12887
12916
  this.isReconnecting = false;
12888
- this.reconnectAttempts = 0;
12889
12917
  await this._restoreSubscriptions();
12890
12918
  this._processRequestQueue();
12891
12919
  this.events.emit("open", new Event("open"));