starknet 7.5.0 → 7.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/index.d.ts +309 -192
- package/dist/index.global.js +448 -299
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +454 -305
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +450 -301
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.global.js
CHANGED
|
@@ -38,7 +38,6 @@ var starknet = (() => {
|
|
|
38
38
|
Contract: () => Contract,
|
|
39
39
|
ContractFactory: () => ContractFactory,
|
|
40
40
|
ContractInterface: () => ContractInterface,
|
|
41
|
-
CustomError: () => CustomError,
|
|
42
41
|
EDAMode: () => EDAMode3,
|
|
43
42
|
EDataAvailabilityMode: () => EDataAvailabilityMode3,
|
|
44
43
|
ETH_ADDRESS: () => ETH_ADDRESS,
|
|
@@ -75,6 +74,8 @@ var starknet = (() => {
|
|
|
75
74
|
RpcProvider: () => RpcProvider2,
|
|
76
75
|
Signer: () => Signer,
|
|
77
76
|
SignerInterface: () => SignerInterface,
|
|
77
|
+
Subscription: () => Subscription,
|
|
78
|
+
TimeoutError: () => TimeoutError,
|
|
78
79
|
TransactionExecutionStatus: () => TransactionExecutionStatus,
|
|
79
80
|
TransactionFinalityStatus: () => TransactionFinalityStatus,
|
|
80
81
|
TransactionType: () => TransactionType,
|
|
@@ -91,9 +92,9 @@ var starknet = (() => {
|
|
|
91
92
|
UINT_512_MIN: () => UINT_512_MIN,
|
|
92
93
|
Uint: () => Uint,
|
|
93
94
|
ValidateType: () => ValidateType,
|
|
94
|
-
WSSubscriptions: () => WSSubscriptions,
|
|
95
95
|
WalletAccount: () => WalletAccount,
|
|
96
96
|
WebSocketChannel: () => WebSocketChannel,
|
|
97
|
+
WebSocketNotConnectedError: () => WebSocketNotConnectedError,
|
|
97
98
|
addAddressPadding: () => addAddressPadding,
|
|
98
99
|
byteArray: () => byteArray_exports,
|
|
99
100
|
cairo: () => cairo_exports,
|
|
@@ -107,8 +108,6 @@ var starknet = (() => {
|
|
|
107
108
|
eth: () => eth_exports,
|
|
108
109
|
events: () => events_exports,
|
|
109
110
|
extractContractHashes: () => extractContractHashes,
|
|
110
|
-
fixProto: () => fixProto,
|
|
111
|
-
fixStack: () => fixStack,
|
|
112
111
|
getCalldata: () => getCalldata,
|
|
113
112
|
getChecksumAddress: () => getChecksumAddress,
|
|
114
113
|
getLedgerPathBuffer: () => getLedgerPathBuffer111,
|
|
@@ -138,6 +137,7 @@ var starknet = (() => {
|
|
|
138
137
|
stark: () => stark_exports,
|
|
139
138
|
starknetId: () => starknetId_exports,
|
|
140
139
|
toAnyPatchVersion: () => toAnyPatchVersion,
|
|
140
|
+
toApiVersion: () => toApiVersion,
|
|
141
141
|
transaction: () => transaction_exports,
|
|
142
142
|
typedData: () => typedData_exports,
|
|
143
143
|
types: () => types_exports,
|
|
@@ -11763,6 +11763,10 @@ ${indent}}` : "}";
|
|
|
11763
11763
|
}
|
|
11764
11764
|
return `${parts[0]}.${parts[1]}.*`;
|
|
11765
11765
|
}
|
|
11766
|
+
function toApiVersion(version) {
|
|
11767
|
+
const [major, minor] = version.replace(/^v/, "").split(".");
|
|
11768
|
+
return `v${major}_${minor}`;
|
|
11769
|
+
}
|
|
11766
11770
|
function isPendingBlock(response) {
|
|
11767
11771
|
return response.status === "PENDING";
|
|
11768
11772
|
}
|
|
@@ -12047,6 +12051,18 @@ ${indent}}` : "}";
|
|
|
12047
12051
|
return rpc_default[typeName] === this.code;
|
|
12048
12052
|
}
|
|
12049
12053
|
};
|
|
12054
|
+
var TimeoutError = class extends LibraryError {
|
|
12055
|
+
constructor(message) {
|
|
12056
|
+
super(message);
|
|
12057
|
+
this.name = "TimeoutError";
|
|
12058
|
+
}
|
|
12059
|
+
};
|
|
12060
|
+
var WebSocketNotConnectedError = class extends LibraryError {
|
|
12061
|
+
constructor(message) {
|
|
12062
|
+
super(message);
|
|
12063
|
+
this.name = "WebSocketNotConnectedError";
|
|
12064
|
+
}
|
|
12065
|
+
};
|
|
12050
12066
|
|
|
12051
12067
|
// src/utils/eth.ts
|
|
12052
12068
|
var eth_exports = {};
|
|
@@ -12160,6 +12176,7 @@ ${indent}}` : "}";
|
|
|
12160
12176
|
createSierraContractClass: () => createSierraContractClass,
|
|
12161
12177
|
getDefaultNodeUrl: () => getDefaultNodeUrl,
|
|
12162
12178
|
getDefaultNodes: () => getDefaultNodes,
|
|
12179
|
+
getSupportedRpcVersions: () => getSupportedRpcVersions,
|
|
12163
12180
|
parseContract: () => parseContract,
|
|
12164
12181
|
validBlockTags: () => validBlockTags,
|
|
12165
12182
|
wait: () => wait
|
|
@@ -12197,15 +12214,17 @@ ${indent}}` : "}";
|
|
|
12197
12214
|
return nodes[randIdx];
|
|
12198
12215
|
};
|
|
12199
12216
|
function getDefaultNodes(rpcVersion) {
|
|
12200
|
-
const vToUrl = (versionString) => `v${versionString.replace(/^v/, "").replace(/\./g, "_")}`;
|
|
12201
12217
|
const nodes = { ...RPC_DEFAULT_NODES };
|
|
12202
12218
|
Object.keys(nodes).forEach(function(key, _) {
|
|
12203
12219
|
nodes[key] = nodes[key].map((it) => {
|
|
12204
|
-
return `${it}${
|
|
12220
|
+
return `${it}${toApiVersion(rpcVersion)}`;
|
|
12205
12221
|
});
|
|
12206
12222
|
});
|
|
12207
12223
|
return nodes;
|
|
12208
12224
|
}
|
|
12225
|
+
function getSupportedRpcVersions() {
|
|
12226
|
+
return [...new Set(Object.values(_SupportedRpcVersion))];
|
|
12227
|
+
}
|
|
12209
12228
|
var validBlockTags = Object.values(BlockTag);
|
|
12210
12229
|
var Block = class {
|
|
12211
12230
|
/**
|
|
@@ -13578,7 +13597,8 @@ ${indent}}` : "}";
|
|
|
13578
13597
|
type: esm_exports2.ETransactionType.INVOKE,
|
|
13579
13598
|
sender_address: invocation.contractAddress,
|
|
13580
13599
|
calldata: CallData.toHex(invocation.calldata),
|
|
13581
|
-
version: toHex(defaultVersions.v3),
|
|
13600
|
+
version: toHex(invocation.version || defaultVersions.v3),
|
|
13601
|
+
// invocation.version as simulate can use fee and normal version
|
|
13582
13602
|
...details
|
|
13583
13603
|
};
|
|
13584
13604
|
}
|
|
@@ -13596,7 +13616,8 @@ ${indent}}` : "}";
|
|
|
13596
13616
|
},
|
|
13597
13617
|
compiled_class_hash: invocation.compiledClassHash || "",
|
|
13598
13618
|
sender_address: invocation.senderAddress,
|
|
13599
|
-
version: toHex(defaultVersions.v3),
|
|
13619
|
+
version: toHex(invocation.version || defaultVersions.v3),
|
|
13620
|
+
// invocation.version as simulate can use fee and normal version
|
|
13600
13621
|
...details
|
|
13601
13622
|
};
|
|
13602
13623
|
}
|
|
@@ -13607,7 +13628,8 @@ ${indent}}` : "}";
|
|
|
13607
13628
|
constructor_calldata: CallData.toHex(invocation.constructorCalldata || []),
|
|
13608
13629
|
class_hash: toHex(invocation.classHash),
|
|
13609
13630
|
contract_address_salt: toHex(invocation.addressSalt || 0),
|
|
13610
|
-
version: toHex(defaultVersions.v3),
|
|
13631
|
+
version: toHex(invocation.version || defaultVersions.v3),
|
|
13632
|
+
// invocation.version as simulate can use fee and normal version
|
|
13611
13633
|
...restDetails
|
|
13612
13634
|
};
|
|
13613
13635
|
}
|
|
@@ -13615,6 +13637,31 @@ ${indent}}` : "}";
|
|
|
13615
13637
|
}
|
|
13616
13638
|
};
|
|
13617
13639
|
|
|
13640
|
+
// src/utils/eventEmitter.ts
|
|
13641
|
+
var EventEmitter = class {
|
|
13642
|
+
listeners = {};
|
|
13643
|
+
on(event, listener) {
|
|
13644
|
+
if (!this.listeners[event]) {
|
|
13645
|
+
this.listeners[event] = [];
|
|
13646
|
+
}
|
|
13647
|
+
this.listeners[event].push(listener);
|
|
13648
|
+
}
|
|
13649
|
+
off(event, listener) {
|
|
13650
|
+
if (!this.listeners[event]) {
|
|
13651
|
+
return;
|
|
13652
|
+
}
|
|
13653
|
+
this.listeners[event] = this.listeners[event].filter((l) => l !== listener);
|
|
13654
|
+
}
|
|
13655
|
+
emit(event, data) {
|
|
13656
|
+
if (this.listeners[event]) {
|
|
13657
|
+
this.listeners[event].forEach((listener) => listener(data));
|
|
13658
|
+
}
|
|
13659
|
+
}
|
|
13660
|
+
clear() {
|
|
13661
|
+
this.listeners = {};
|
|
13662
|
+
}
|
|
13663
|
+
};
|
|
13664
|
+
|
|
13618
13665
|
// src/utils/connect/ws.ts
|
|
13619
13666
|
var ws_default = typeof WebSocket !== "undefined" && WebSocket || typeof globalThis !== "undefined" && globalThis.WebSocket || typeof window !== "undefined" && window.WebSocket.bind(window) || typeof global !== "undefined" && global.WebSocket || class {
|
|
13620
13667
|
constructor() {
|
|
@@ -13624,152 +13671,184 @@ ${indent}}` : "}";
|
|
|
13624
13671
|
}
|
|
13625
13672
|
};
|
|
13626
13673
|
|
|
13627
|
-
// src/channel/
|
|
13628
|
-
var
|
|
13629
|
-
NEW_HEADS: "newHeads",
|
|
13630
|
-
EVENTS: "events",
|
|
13631
|
-
TRANSACTION_STATUS: "transactionStatus",
|
|
13632
|
-
PENDING_TRANSACTION: "pendingTransactions"
|
|
13633
|
-
};
|
|
13634
|
-
var WebSocketChannel = class {
|
|
13674
|
+
// src/channel/ws/subscription.ts
|
|
13675
|
+
var Subscription = class {
|
|
13635
13676
|
/**
|
|
13636
|
-
*
|
|
13637
|
-
* @
|
|
13677
|
+
* The containing `WebSocketChannel` instance.
|
|
13678
|
+
* @internal
|
|
13638
13679
|
*/
|
|
13639
|
-
|
|
13640
|
-
// public headers: object;
|
|
13641
|
-
// readonly retries: number;
|
|
13642
|
-
// public requestId: number;
|
|
13643
|
-
// readonly blockIdentifier: BlockIdentifier;
|
|
13644
|
-
// private chainId?: StarknetChainId;
|
|
13645
|
-
// private specVersion?: string;
|
|
13646
|
-
// private transactionRetryIntervalFallback?: number;
|
|
13647
|
-
// readonly waitMode: Boolean; // behave like web2 rpc and return when tx is processed
|
|
13648
|
-
// private batchClient?: BatchClient;
|
|
13680
|
+
channel;
|
|
13649
13681
|
/**
|
|
13650
|
-
*
|
|
13682
|
+
* The JSON-RPC method used to create this subscription.
|
|
13683
|
+
* @internal
|
|
13651
13684
|
*/
|
|
13652
|
-
|
|
13685
|
+
method;
|
|
13653
13686
|
/**
|
|
13654
|
-
*
|
|
13655
|
-
* @
|
|
13656
|
-
* ```typescript
|
|
13657
|
-
* webSocketChannel.onReorg = async function (data) {
|
|
13658
|
-
* // ... do something when reorg happens
|
|
13659
|
-
* }
|
|
13660
|
-
* ```
|
|
13687
|
+
* The parameters used to create this subscription.
|
|
13688
|
+
* @internal
|
|
13661
13689
|
*/
|
|
13662
|
-
|
|
13663
|
-
};
|
|
13690
|
+
params;
|
|
13664
13691
|
/**
|
|
13665
|
-
*
|
|
13666
|
-
* @
|
|
13667
|
-
* ```typescript
|
|
13668
|
-
* webSocketChannel.onNewHeads = async function (data) {
|
|
13669
|
-
* // ... do something with head data
|
|
13670
|
-
* }
|
|
13671
|
-
* ```
|
|
13672
|
-
*/
|
|
13673
|
-
onNewHeads = () => {
|
|
13674
|
-
};
|
|
13675
|
-
/**
|
|
13676
|
-
* Assign implementation method to get 'starknet events'
|
|
13677
|
-
* @example
|
|
13678
|
-
* ```typescript
|
|
13679
|
-
* webSocketChannel.onEvents = async function (data) {
|
|
13680
|
-
* // ... do something with event data
|
|
13681
|
-
* }
|
|
13682
|
-
* ```
|
|
13692
|
+
* The unique identifier for this subscription.
|
|
13693
|
+
* @internal
|
|
13683
13694
|
*/
|
|
13684
|
-
|
|
13685
|
-
|
|
13695
|
+
id;
|
|
13696
|
+
events = new EventEmitter();
|
|
13697
|
+
buffer = [];
|
|
13698
|
+
maxBufferSize;
|
|
13699
|
+
handler = null;
|
|
13700
|
+
_isClosed = false;
|
|
13686
13701
|
/**
|
|
13687
|
-
*
|
|
13688
|
-
* @
|
|
13689
|
-
*
|
|
13690
|
-
*
|
|
13691
|
-
*
|
|
13692
|
-
* }
|
|
13693
|
-
* ```
|
|
13702
|
+
* @internal
|
|
13703
|
+
* @param {WebSocketChannel} channel - The WebSocketChannel instance.
|
|
13704
|
+
* @param {string} method - The RPC method used for the subscription.
|
|
13705
|
+
* @param {any} params - The parameters for the subscription.
|
|
13706
|
+
* @param {SUBSCRIPTION_ID} id - The subscription ID.
|
|
13707
|
+
* @param {number} maxBufferSize - The maximum number of events to buffer.
|
|
13694
13708
|
*/
|
|
13695
|
-
|
|
13696
|
-
|
|
13709
|
+
constructor(channel, method, params, id, maxBufferSize) {
|
|
13710
|
+
this.channel = channel;
|
|
13711
|
+
this.method = method;
|
|
13712
|
+
this.params = params;
|
|
13713
|
+
this.id = id;
|
|
13714
|
+
this.maxBufferSize = maxBufferSize;
|
|
13715
|
+
}
|
|
13697
13716
|
/**
|
|
13698
|
-
*
|
|
13699
|
-
* @
|
|
13700
|
-
* ```typescript
|
|
13701
|
-
* webSocketChannel.onPendingTransaction = async function (data) {
|
|
13702
|
-
* // ... do something with pending tx data
|
|
13703
|
-
* }
|
|
13704
|
-
* ```
|
|
13717
|
+
* Indicates if the subscription has been closed.
|
|
13718
|
+
* @returns {boolean} `true` if unsubscribed, `false` otherwise.
|
|
13705
13719
|
*/
|
|
13706
|
-
|
|
13707
|
-
|
|
13720
|
+
get isClosed() {
|
|
13721
|
+
return this._isClosed;
|
|
13722
|
+
}
|
|
13708
13723
|
/**
|
|
13709
|
-
*
|
|
13724
|
+
* Internal method to handle incoming events from the WebSocket channel.
|
|
13725
|
+
* If a handler is attached, it's invoked immediately. Otherwise, the event is buffered.
|
|
13726
|
+
* @internal
|
|
13727
|
+
* @param {T} data - The event data.
|
|
13710
13728
|
*/
|
|
13711
|
-
|
|
13712
|
-
|
|
13729
|
+
_handleEvent(data) {
|
|
13730
|
+
if (this.handler) {
|
|
13731
|
+
this.handler(data);
|
|
13732
|
+
} else {
|
|
13733
|
+
if (this.buffer.length >= this.maxBufferSize) {
|
|
13734
|
+
const droppedEvent = this.buffer.shift();
|
|
13735
|
+
logger.warn(`Subscription ${this.id}: Buffer full. Dropping oldest event:`, droppedEvent);
|
|
13736
|
+
}
|
|
13737
|
+
this.buffer.push(data);
|
|
13738
|
+
}
|
|
13739
|
+
}
|
|
13713
13740
|
/**
|
|
13714
|
-
*
|
|
13741
|
+
* Attaches a handler function to be called for each event.
|
|
13742
|
+
*
|
|
13743
|
+
* When a handler is attached, any buffered events will be passed to it sequentially.
|
|
13744
|
+
* Subsequent events will be passed directly as they arrive.
|
|
13745
|
+
*
|
|
13746
|
+
* @param {(data: T) => void} handler - The function to call with event data.
|
|
13747
|
+
* @throws {Error} If a handler is already attached to this subscription.
|
|
13715
13748
|
*/
|
|
13716
|
-
|
|
13717
|
-
|
|
13749
|
+
on(handler) {
|
|
13750
|
+
if (this.handler) {
|
|
13751
|
+
throw new Error("A handler is already attached to this subscription.");
|
|
13752
|
+
}
|
|
13753
|
+
this.handler = handler;
|
|
13754
|
+
while (this.buffer.length > 0) {
|
|
13755
|
+
const event = this.buffer.shift();
|
|
13756
|
+
if (event) {
|
|
13757
|
+
this.handler(event);
|
|
13758
|
+
}
|
|
13759
|
+
}
|
|
13760
|
+
}
|
|
13718
13761
|
/**
|
|
13719
|
-
*
|
|
13762
|
+
* Sends an unsubscribe request to the node and cleans up local resources.
|
|
13763
|
+
* @returns {Promise<boolean>} A Promise that resolves to `true` if the unsubscription was successful.
|
|
13720
13764
|
*/
|
|
13721
|
-
|
|
13722
|
-
|
|
13765
|
+
async unsubscribe() {
|
|
13766
|
+
if (this._isClosed) {
|
|
13767
|
+
return true;
|
|
13768
|
+
}
|
|
13769
|
+
const success = await this.channel.unsubscribe(this.id);
|
|
13770
|
+
if (success) {
|
|
13771
|
+
this._isClosed = true;
|
|
13772
|
+
this.channel.removeSubscription(this.id);
|
|
13773
|
+
this.events.emit("unsubscribe", void 0);
|
|
13774
|
+
this.events.clear();
|
|
13775
|
+
}
|
|
13776
|
+
return success;
|
|
13777
|
+
}
|
|
13778
|
+
};
|
|
13779
|
+
|
|
13780
|
+
// src/channel/ws/ws_0_8.ts
|
|
13781
|
+
var WebSocketChannel = class {
|
|
13723
13782
|
/**
|
|
13724
|
-
*
|
|
13783
|
+
* The URL of the WebSocket RPC Node.
|
|
13784
|
+
* @example 'wss://starknet-sepolia.public.blastapi.io/rpc/v0_8'
|
|
13725
13785
|
*/
|
|
13726
|
-
|
|
13727
|
-
};
|
|
13786
|
+
nodeUrl;
|
|
13728
13787
|
/**
|
|
13729
|
-
*
|
|
13788
|
+
* The underlying WebSocket instance.
|
|
13730
13789
|
*/
|
|
13731
|
-
|
|
13732
|
-
|
|
13733
|
-
|
|
13734
|
-
|
|
13790
|
+
websocket;
|
|
13791
|
+
// Store the WebSocket implementation class to allow for custom implementations.
|
|
13792
|
+
WsImplementation;
|
|
13793
|
+
// Map of active subscriptions, keyed by their ID.
|
|
13794
|
+
activeSubscriptions = /* @__PURE__ */ new Map();
|
|
13795
|
+
maxBufferSize;
|
|
13796
|
+
autoReconnect;
|
|
13797
|
+
reconnectOptions;
|
|
13798
|
+
requestTimeout;
|
|
13799
|
+
isReconnecting = false;
|
|
13800
|
+
reconnectAttempts = 0;
|
|
13801
|
+
userInitiatedClose = false;
|
|
13802
|
+
reconnectTimeoutId = null;
|
|
13803
|
+
requestQueue = [];
|
|
13804
|
+
events = new EventEmitter();
|
|
13805
|
+
openListener = (ev) => this.events.emit("open", ev);
|
|
13806
|
+
closeListener = this.onCloseProxy.bind(this);
|
|
13807
|
+
messageListener = this.onMessageProxy.bind(this);
|
|
13808
|
+
errorListener = (ev) => this.events.emit("error", ev);
|
|
13735
13809
|
/**
|
|
13736
|
-
* JSON RPC latest sent message
|
|
13737
|
-
*
|
|
13810
|
+
* JSON RPC latest sent message ID.
|
|
13811
|
+
* The receiving message is expected to contain the same ID.
|
|
13738
13812
|
*/
|
|
13739
13813
|
sendId = 0;
|
|
13740
13814
|
/**
|
|
13741
|
-
*
|
|
13742
|
-
*
|
|
13815
|
+
* Creates an instance of WebSocketChannel.
|
|
13816
|
+
* @param {WebSocketOptions} options - The options for configuring the channel.
|
|
13743
13817
|
*/
|
|
13744
|
-
|
|
13745
|
-
|
|
13746
|
-
|
|
13747
|
-
|
|
13748
|
-
|
|
13749
|
-
|
|
13750
|
-
|
|
13751
|
-
|
|
13752
|
-
this.
|
|
13753
|
-
this.websocket.
|
|
13754
|
-
this.websocket
|
|
13755
|
-
this.websocket.addEventListener("
|
|
13756
|
-
this.websocket.addEventListener("
|
|
13818
|
+
constructor(options) {
|
|
13819
|
+
this.nodeUrl = options.nodeUrl;
|
|
13820
|
+
this.maxBufferSize = options.maxBufferSize ?? 1e3;
|
|
13821
|
+
this.autoReconnect = options.autoReconnect ?? true;
|
|
13822
|
+
this.reconnectOptions = {
|
|
13823
|
+
retries: options.reconnectOptions?.retries ?? 5,
|
|
13824
|
+
delay: options.reconnectOptions?.delay ?? 2e3
|
|
13825
|
+
};
|
|
13826
|
+
this.requestTimeout = options.requestTimeout ?? 6e4;
|
|
13827
|
+
this.WsImplementation = options.websocket || config.get("websocket") || ws_default;
|
|
13828
|
+
this.websocket = new this.WsImplementation(this.nodeUrl);
|
|
13829
|
+
this.websocket.addEventListener("open", this.openListener);
|
|
13830
|
+
this.websocket.addEventListener("close", this.closeListener);
|
|
13831
|
+
this.websocket.addEventListener("message", this.messageListener);
|
|
13832
|
+
this.websocket.addEventListener("error", this.errorListener);
|
|
13757
13833
|
}
|
|
13758
13834
|
idResolver(id) {
|
|
13759
13835
|
if (id) return id;
|
|
13760
13836
|
return this.sendId++;
|
|
13761
13837
|
}
|
|
13762
13838
|
/**
|
|
13763
|
-
*
|
|
13764
|
-
*
|
|
13765
|
-
* @
|
|
13766
|
-
*
|
|
13767
|
-
*
|
|
13768
|
-
*
|
|
13839
|
+
* Sends a JSON-RPC request over the WebSocket connection without waiting for a response.
|
|
13840
|
+
* This is a low-level method. Prefer `sendReceive` for most use cases.
|
|
13841
|
+
* @param {string} method - The RPC method name.
|
|
13842
|
+
* @param {object} [params] - The parameters for the RPC method.
|
|
13843
|
+
* @param {number} [id] - A specific request ID. If not provided, an auto-incrementing ID is used.
|
|
13844
|
+
* @returns {number} The ID of the sent request.
|
|
13845
|
+
* @throws {WebSocketNotConnectedError} If the WebSocket is not connected.
|
|
13769
13846
|
*/
|
|
13770
13847
|
send(method, params, id) {
|
|
13771
13848
|
if (!this.isConnected()) {
|
|
13772
|
-
throw
|
|
13849
|
+
throw new WebSocketNotConnectedError(
|
|
13850
|
+
"WebSocketChannel.send() failed due to socket being disconnected"
|
|
13851
|
+
);
|
|
13773
13852
|
}
|
|
13774
13853
|
const usedId = this.idResolver(id);
|
|
13775
13854
|
const rpcRequestBody = {
|
|
@@ -13782,50 +13861,88 @@ ${indent}}` : "}";
|
|
|
13782
13861
|
return usedId;
|
|
13783
13862
|
}
|
|
13784
13863
|
/**
|
|
13785
|
-
*
|
|
13786
|
-
|
|
13787
|
-
|
|
13788
|
-
|
|
13789
|
-
|
|
13790
|
-
|
|
13791
|
-
*
|
|
13792
|
-
*
|
|
13793
|
-
* @
|
|
13794
|
-
* @param params rpc method parameters
|
|
13795
|
-
* @example
|
|
13796
|
-
* ```typescript
|
|
13797
|
-
* const response = await this.sendReceive('starknet_method', params);
|
|
13798
|
-
* ```
|
|
13864
|
+
* Sends a JSON-RPC request and returns a Promise that resolves with the result.
|
|
13865
|
+
* This method abstracts the request/response cycle over WebSockets.
|
|
13866
|
+
* If the connection is lost, it will queue the request and send it upon reconnection.
|
|
13867
|
+
* @template T - The expected type of the result.
|
|
13868
|
+
* @param {string} method - The RPC method name.
|
|
13869
|
+
* @param {object} [params] - The parameters for the RPC method.
|
|
13870
|
+
* @returns {Promise<T>} A Promise that resolves with the RPC response result.
|
|
13871
|
+
* @throws {TimeoutError} If the request does not receive a response within the configured `requestTimeout`.
|
|
13872
|
+
* @throws {WebSocketNotConnectedError} If the WebSocket is not connected and auto-reconnect is disabled.
|
|
13799
13873
|
*/
|
|
13800
13874
|
sendReceive(method, params) {
|
|
13875
|
+
if (this.isReconnecting || !this.isConnected() && this.autoReconnect && !this.userInitiatedClose) {
|
|
13876
|
+
logger.info(`WebSocket: Connection unavailable, queueing request: ${method}`);
|
|
13877
|
+
return new Promise((resolve, reject) => {
|
|
13878
|
+
this.requestQueue.push({ method, params, resolve, reject });
|
|
13879
|
+
});
|
|
13880
|
+
}
|
|
13801
13881
|
const sendId = this.send(method, params);
|
|
13802
13882
|
return new Promise((resolve, reject) => {
|
|
13803
|
-
|
|
13804
|
-
this.websocket
|
|
13805
|
-
|
|
13883
|
+
let timeoutId;
|
|
13884
|
+
if (!this.websocket || this.websocket.readyState !== ws_default.OPEN) {
|
|
13885
|
+
reject(new WebSocketNotConnectedError("WebSocket not available or not connected."));
|
|
13886
|
+
return;
|
|
13887
|
+
}
|
|
13888
|
+
const messageHandler = (event) => {
|
|
13889
|
+
if (!isString(event.data)) {
|
|
13890
|
+
logger.warn("WebSocket received non-string message data:", event.data);
|
|
13891
|
+
return;
|
|
13892
|
+
}
|
|
13893
|
+
const message = JSON.parse(event.data);
|
|
13806
13894
|
if (message.id === sendId) {
|
|
13895
|
+
clearTimeout(timeoutId);
|
|
13896
|
+
this.websocket.removeEventListener("message", messageHandler);
|
|
13897
|
+
this.websocket.removeEventListener("error", errorHandler);
|
|
13807
13898
|
if ("result" in message) {
|
|
13808
13899
|
resolve(message.result);
|
|
13809
13900
|
} else {
|
|
13810
|
-
reject(
|
|
13901
|
+
reject(
|
|
13902
|
+
new Error(`Error on ${method} (id: ${sendId}): ${JSON.stringify(message.error)}`)
|
|
13903
|
+
);
|
|
13811
13904
|
}
|
|
13812
13905
|
}
|
|
13813
13906
|
};
|
|
13814
|
-
|
|
13907
|
+
const errorHandler = (event) => {
|
|
13908
|
+
clearTimeout(timeoutId);
|
|
13909
|
+
this.websocket.removeEventListener("message", messageHandler);
|
|
13910
|
+
this.websocket.removeEventListener("error", errorHandler);
|
|
13911
|
+
reject(
|
|
13912
|
+
new Error(
|
|
13913
|
+
`WebSocket error during ${method} (id: ${sendId}): ${event.type || "Unknown error"}`
|
|
13914
|
+
)
|
|
13915
|
+
);
|
|
13916
|
+
};
|
|
13917
|
+
this.websocket.addEventListener("message", messageHandler);
|
|
13918
|
+
this.websocket.addEventListener("error", errorHandler);
|
|
13919
|
+
timeoutId = setTimeout(() => {
|
|
13920
|
+
this.websocket.removeEventListener("message", messageHandler);
|
|
13921
|
+
this.websocket.removeEventListener("error", errorHandler);
|
|
13922
|
+
reject(
|
|
13923
|
+
new TimeoutError(
|
|
13924
|
+
`Request ${method} (id: ${sendId}) timed out after ${this.requestTimeout}ms`
|
|
13925
|
+
)
|
|
13926
|
+
);
|
|
13927
|
+
}, this.requestTimeout);
|
|
13815
13928
|
});
|
|
13816
13929
|
}
|
|
13817
13930
|
/**
|
|
13818
|
-
*
|
|
13931
|
+
* Checks if the WebSocket connection is currently open.
|
|
13932
|
+
* @returns {boolean} `true` if the connection is open, `false` otherwise.
|
|
13819
13933
|
*/
|
|
13820
13934
|
isConnected() {
|
|
13821
13935
|
return this.websocket.readyState === ws_default.OPEN;
|
|
13822
13936
|
}
|
|
13823
13937
|
/**
|
|
13824
|
-
*
|
|
13825
|
-
*
|
|
13938
|
+
* Returns a Promise that resolves when the WebSocket connection is open.
|
|
13939
|
+
* Can be used to block execution until the connection is established.
|
|
13940
|
+
* @returns {Promise<number>} A Promise that resolves with the WebSocket's `readyState` when connected.
|
|
13826
13941
|
* @example
|
|
13827
13942
|
* ```typescript
|
|
13828
|
-
* const
|
|
13943
|
+
* const channel = new WebSocketChannel({ nodeUrl: '...' });
|
|
13944
|
+
* await channel.waitForConnection();
|
|
13945
|
+
* console.log('Connected!');
|
|
13829
13946
|
* ```
|
|
13830
13947
|
*/
|
|
13831
13948
|
async waitForConnection() {
|
|
@@ -13841,17 +13958,22 @@ ${indent}}` : "}";
|
|
|
13841
13958
|
return this.websocket.readyState;
|
|
13842
13959
|
}
|
|
13843
13960
|
/**
|
|
13844
|
-
*
|
|
13961
|
+
* Closes the WebSocket connection.
|
|
13962
|
+
* This method is user-initiated and will prevent automatic reconnection for this closure.
|
|
13963
|
+
* @param {number} [code] - The WebSocket connection close code.
|
|
13964
|
+
* @param {string} [reason] - The WebSocket connection close reason.
|
|
13845
13965
|
*/
|
|
13846
13966
|
disconnect(code, reason) {
|
|
13967
|
+
if (this.reconnectTimeoutId) {
|
|
13968
|
+
clearTimeout(this.reconnectTimeoutId);
|
|
13969
|
+
this.reconnectTimeoutId = null;
|
|
13970
|
+
}
|
|
13847
13971
|
this.websocket.close(code, reason);
|
|
13972
|
+
this.userInitiatedClose = true;
|
|
13848
13973
|
}
|
|
13849
13974
|
/**
|
|
13850
|
-
*
|
|
13851
|
-
* @
|
|
13852
|
-
* ```typescript
|
|
13853
|
-
* const readyState = await webSocketChannel.waitForDisconnection();
|
|
13854
|
-
* ```
|
|
13975
|
+
* Returns a Promise that resolves when the WebSocket connection is closed.
|
|
13976
|
+
* @returns {Promise<number | Event>} A Promise that resolves with the WebSocket's `readyState` or a `CloseEvent` when disconnected.
|
|
13855
13977
|
*/
|
|
13856
13978
|
async waitForDisconnection() {
|
|
13857
13979
|
if (this.websocket.readyState !== ws_default.CLOSED) {
|
|
@@ -13864,206 +13986,233 @@ ${indent}}` : "}";
|
|
|
13864
13986
|
return this.websocket.readyState;
|
|
13865
13987
|
}
|
|
13866
13988
|
/**
|
|
13867
|
-
*
|
|
13868
|
-
*
|
|
13869
|
-
* @
|
|
13989
|
+
* Unsubscribes from a Starknet subscription.
|
|
13990
|
+
* It is recommended to use the `unsubscribe()` method on the `Subscription` object instead.
|
|
13991
|
+
* @internal
|
|
13992
|
+
* @param {SUBSCRIPTION_ID} subscriptionId - The ID of the subscription to unsubscribe from.
|
|
13993
|
+
* @returns {Promise<boolean>} A Promise that resolves with `true` if the unsubscription was successful.
|
|
13870
13994
|
*/
|
|
13871
|
-
async unsubscribe(subscriptionId
|
|
13995
|
+
async unsubscribe(subscriptionId) {
|
|
13872
13996
|
const status = await this.sendReceive("starknet_unsubscribe", {
|
|
13873
13997
|
subscription_id: subscriptionId
|
|
13874
13998
|
});
|
|
13875
13999
|
if (status) {
|
|
13876
|
-
|
|
13877
|
-
this.subscriptions.delete(ref);
|
|
13878
|
-
}
|
|
13879
|
-
this.onUnsubscribeLocal(subscriptionId);
|
|
13880
|
-
this.onUnsubscribe(subscriptionId);
|
|
14000
|
+
this.events.emit("unsubscribe", subscriptionId);
|
|
13881
14001
|
}
|
|
13882
14002
|
return status;
|
|
13883
14003
|
}
|
|
13884
14004
|
/**
|
|
13885
|
-
*
|
|
13886
|
-
* @param
|
|
13887
|
-
* @returns
|
|
14005
|
+
* Returns a Promise that resolves when a specific subscription is successfully unsubscribed.
|
|
14006
|
+
* @param {SUBSCRIPTION_ID} targetId - The ID of the subscription to wait for.
|
|
14007
|
+
* @returns {Promise<void>}
|
|
13888
14008
|
* @example
|
|
13889
14009
|
* ```typescript
|
|
13890
|
-
*
|
|
14010
|
+
* await channel.waitForUnsubscription(mySubscription.id);
|
|
14011
|
+
* console.log('Successfully unsubscribed.');
|
|
13891
14012
|
* ```
|
|
13892
14013
|
*/
|
|
13893
|
-
|
|
13894
|
-
return new Promise((resolve
|
|
13895
|
-
|
|
13896
|
-
|
|
13897
|
-
|
|
13898
|
-
resolve(
|
|
13899
|
-
} else if (subscriptionId === forSubscriptionId) {
|
|
13900
|
-
resolve(subscriptionId);
|
|
14014
|
+
waitForUnsubscription(targetId) {
|
|
14015
|
+
return new Promise((resolve) => {
|
|
14016
|
+
const listener = (unsubId) => {
|
|
14017
|
+
if (unsubId === targetId) {
|
|
14018
|
+
this.events.off("unsubscribe", listener);
|
|
14019
|
+
resolve();
|
|
13901
14020
|
}
|
|
13902
14021
|
};
|
|
13903
|
-
this.
|
|
14022
|
+
this.events.on("unsubscribe", listener);
|
|
13904
14023
|
});
|
|
13905
14024
|
}
|
|
13906
14025
|
/**
|
|
13907
|
-
*
|
|
14026
|
+
* Manually initiates a reconnection attempt.
|
|
14027
|
+
* This creates a new WebSocket instance and re-establishes listeners.
|
|
13908
14028
|
*/
|
|
13909
14029
|
reconnect() {
|
|
13910
|
-
this.
|
|
13911
|
-
this.websocket
|
|
13912
|
-
this.websocket.addEventListener("
|
|
13913
|
-
this.websocket.addEventListener("
|
|
13914
|
-
this.websocket.addEventListener("
|
|
14030
|
+
this.userInitiatedClose = false;
|
|
14031
|
+
this.websocket = new this.WsImplementation(this.nodeUrl);
|
|
14032
|
+
this.websocket.addEventListener("open", this.openListener);
|
|
14033
|
+
this.websocket.addEventListener("close", this.closeListener);
|
|
14034
|
+
this.websocket.addEventListener("message", this.messageListener);
|
|
14035
|
+
this.websocket.addEventListener("error", this.errorListener);
|
|
14036
|
+
}
|
|
14037
|
+
_processRequestQueue() {
|
|
14038
|
+
logger.info(`WebSocket: Processing ${this.requestQueue.length} queued requests.`);
|
|
14039
|
+
while (this.requestQueue.length > 0) {
|
|
14040
|
+
const { method, params, resolve, reject } = this.requestQueue.shift();
|
|
14041
|
+
this.sendReceive(method, params).then(resolve).catch(reject);
|
|
14042
|
+
}
|
|
14043
|
+
}
|
|
14044
|
+
async _restoreSubscriptions() {
|
|
14045
|
+
const oldSubscriptions = Array.from(this.activeSubscriptions.values());
|
|
14046
|
+
this.activeSubscriptions.clear();
|
|
14047
|
+
const restorePromises = oldSubscriptions.map(async (sub) => {
|
|
14048
|
+
try {
|
|
14049
|
+
const newSubId = await this.sendReceive(sub.method, sub.params);
|
|
14050
|
+
sub.id = newSubId;
|
|
14051
|
+
this.activeSubscriptions.set(newSubId, sub);
|
|
14052
|
+
logger.info(`Subscription ${sub.method} restored with new ID: ${newSubId}`);
|
|
14053
|
+
} catch (error) {
|
|
14054
|
+
logger.error(`Failed to restore subscription ${sub.method}:`, error);
|
|
14055
|
+
}
|
|
14056
|
+
});
|
|
14057
|
+
await Promise.all(restorePromises);
|
|
13915
14058
|
}
|
|
13916
|
-
|
|
13917
|
-
|
|
13918
|
-
|
|
14059
|
+
_startReconnect() {
|
|
14060
|
+
if (this.isReconnecting || !this.autoReconnect) {
|
|
14061
|
+
return;
|
|
14062
|
+
}
|
|
14063
|
+
this.isReconnecting = true;
|
|
14064
|
+
this.reconnectAttempts = 0;
|
|
14065
|
+
const tryReconnect = () => {
|
|
14066
|
+
if (this.reconnectAttempts >= this.reconnectOptions.retries) {
|
|
14067
|
+
logger.error("WebSocket: Maximum reconnection retries reached. Giving up.");
|
|
14068
|
+
this.isReconnecting = false;
|
|
14069
|
+
return;
|
|
14070
|
+
}
|
|
14071
|
+
this.reconnectAttempts += 1;
|
|
14072
|
+
logger.info(
|
|
14073
|
+
`WebSocket: Connection lost. Attempting to reconnect... (${this.reconnectAttempts}/${this.reconnectOptions.retries})`
|
|
14074
|
+
);
|
|
14075
|
+
this.reconnect();
|
|
14076
|
+
this.websocket.onopen = async () => {
|
|
14077
|
+
logger.info("WebSocket: Reconnection successful.");
|
|
14078
|
+
this.isReconnecting = false;
|
|
14079
|
+
this.reconnectAttempts = 0;
|
|
14080
|
+
await this._restoreSubscriptions();
|
|
14081
|
+
this._processRequestQueue();
|
|
14082
|
+
this.events.emit("open", new Event("open"));
|
|
14083
|
+
};
|
|
14084
|
+
this.websocket.onerror = () => {
|
|
14085
|
+
const delay = this.reconnectOptions.delay * 2 ** (this.reconnectAttempts - 1);
|
|
14086
|
+
logger.info(`WebSocket: Reconnect attempt failed. Retrying in ${delay}ms.`);
|
|
14087
|
+
this.reconnectTimeoutId = setTimeout(tryReconnect, delay);
|
|
14088
|
+
};
|
|
14089
|
+
};
|
|
14090
|
+
tryReconnect();
|
|
13919
14091
|
}
|
|
13920
14092
|
onCloseProxy(ev) {
|
|
13921
|
-
this.websocket.removeEventListener("open", this.
|
|
13922
|
-
this.websocket.removeEventListener("close", this.
|
|
13923
|
-
this.websocket.removeEventListener("message", this.
|
|
13924
|
-
this.websocket.removeEventListener("error", this.
|
|
13925
|
-
this.
|
|
14093
|
+
this.websocket.removeEventListener("open", this.openListener);
|
|
14094
|
+
this.websocket.removeEventListener("close", this.closeListener);
|
|
14095
|
+
this.websocket.removeEventListener("message", this.messageListener);
|
|
14096
|
+
this.websocket.removeEventListener("error", this.errorListener);
|
|
14097
|
+
this.events.emit("close", ev);
|
|
14098
|
+
if (!this.userInitiatedClose) {
|
|
14099
|
+
this._startReconnect();
|
|
14100
|
+
}
|
|
13926
14101
|
}
|
|
13927
14102
|
onMessageProxy(event) {
|
|
13928
|
-
|
|
13929
|
-
|
|
13930
|
-
|
|
13931
|
-
|
|
13932
|
-
|
|
13933
|
-
|
|
13934
|
-
|
|
13935
|
-
|
|
13936
|
-
break;
|
|
13937
|
-
case "starknet_subscriptionEvents":
|
|
13938
|
-
this.onEvents(message.params);
|
|
13939
|
-
break;
|
|
13940
|
-
case "starknet_subscriptionTransactionStatus":
|
|
13941
|
-
this.onTransactionStatus(message.params);
|
|
13942
|
-
break;
|
|
13943
|
-
case "starknet_subscriptionPendingTransactions":
|
|
13944
|
-
this.onPendingTransaction(message.params);
|
|
13945
|
-
break;
|
|
13946
|
-
default:
|
|
13947
|
-
break;
|
|
14103
|
+
let message;
|
|
14104
|
+
try {
|
|
14105
|
+
message = JSON.parse(event.data);
|
|
14106
|
+
} catch (error) {
|
|
14107
|
+
logger.error(
|
|
14108
|
+
`WebSocketChannel: Error parsing incoming message: ${event.data}, Error: ${error}`
|
|
14109
|
+
);
|
|
14110
|
+
return;
|
|
13948
14111
|
}
|
|
13949
|
-
|
|
13950
|
-
|
|
13951
|
-
|
|
13952
|
-
|
|
13953
|
-
|
|
13954
|
-
|
|
13955
|
-
|
|
13956
|
-
|
|
13957
|
-
|
|
13958
|
-
|
|
13959
|
-
}
|
|
14112
|
+
if (message.method && isObject2(message.params) && "subscription_id" in message.params) {
|
|
14113
|
+
const { result, subscription_id } = message.params;
|
|
14114
|
+
const subscription = this.activeSubscriptions.get(subscription_id);
|
|
14115
|
+
if (subscription) {
|
|
14116
|
+
subscription._handleEvent(result);
|
|
14117
|
+
} else {
|
|
14118
|
+
logger.warn(
|
|
14119
|
+
`WebSocketChannel: Received event for untracked subscription ID: ${subscription_id}.`
|
|
14120
|
+
);
|
|
14121
|
+
}
|
|
14122
|
+
}
|
|
14123
|
+
logger.debug("onMessageProxy:", event.data);
|
|
14124
|
+
this.events.emit("message", event);
|
|
13960
14125
|
}
|
|
13961
14126
|
/**
|
|
13962
|
-
*
|
|
14127
|
+
* Subscribes to new block headers.
|
|
14128
|
+
* @param {SubscriptionBlockIdentifier} [blockIdentifier] - The block to start receiving notifications from. Defaults to 'latest'.
|
|
14129
|
+
* @returns {Promise<Subscription<BLOCK_HEADER>>} A Promise that resolves with a `Subscription` object for new block headers.
|
|
13963
14130
|
*/
|
|
13964
14131
|
async subscribeNewHeads(blockIdentifier) {
|
|
13965
|
-
|
|
13966
|
-
const
|
|
13967
|
-
|
|
13968
|
-
|
|
13969
|
-
|
|
13970
|
-
|
|
13971
|
-
|
|
13972
|
-
|
|
13973
|
-
async unsubscribeNewHeads() {
|
|
13974
|
-
const subId = this.subscriptions.get(WSSubscriptions.NEW_HEADS);
|
|
13975
|
-
if (!subId) throw Error("There is no subscription on this event");
|
|
13976
|
-
return this.unsubscribe(subId, WSSubscriptions.NEW_HEADS);
|
|
13977
|
-
}
|
|
13978
|
-
/**
|
|
13979
|
-
* subscribe to 'starknet events'
|
|
13980
|
-
* * you can subscribe to this event multiple times and you need to manage subscriptions manually
|
|
13981
|
-
*/
|
|
13982
|
-
subscribeEventsUnmanaged(fromAddress, keys, blockIdentifier) {
|
|
13983
|
-
const block_id = blockIdentifier ? new Block(blockIdentifier).identifier : void 0;
|
|
13984
|
-
return this.sendReceive("starknet_subscribeEvents", {
|
|
13985
|
-
...{ from_address: fromAddress !== void 0 ? toHex(fromAddress) : void 0 },
|
|
13986
|
-
...{ keys },
|
|
13987
|
-
...{ block_id }
|
|
13988
|
-
});
|
|
14132
|
+
const method = "starknet_subscribeNewHeads";
|
|
14133
|
+
const params = {
|
|
14134
|
+
block_id: blockIdentifier ? new Block(blockIdentifier).identifier : void 0
|
|
14135
|
+
};
|
|
14136
|
+
const subId = await this.sendReceive(method, params);
|
|
14137
|
+
const subscription = new Subscription(this, method, params, subId, this.maxBufferSize);
|
|
14138
|
+
this.activeSubscriptions.set(subId, subscription);
|
|
14139
|
+
return subscription;
|
|
13989
14140
|
}
|
|
13990
14141
|
/**
|
|
13991
|
-
*
|
|
14142
|
+
* Subscribes to events matching a given filter.
|
|
14143
|
+
* @param {BigNumberish} [fromAddress] - The contract address to filter by.
|
|
14144
|
+
* @param {string[][]} [keys] - The event keys to filter by.
|
|
14145
|
+
* @param {SubscriptionBlockIdentifier} [blockIdentifier] - The block to start receiving notifications from. Defaults to 'latest'.
|
|
14146
|
+
* @returns {Promise<Subscription<EMITTED_EVENT>>} A Promise that resolves with a `Subscription` object for the specified events.
|
|
13992
14147
|
*/
|
|
13993
14148
|
async subscribeEvents(fromAddress, keys, blockIdentifier) {
|
|
13994
|
-
|
|
13995
|
-
const
|
|
13996
|
-
|
|
13997
|
-
|
|
13998
|
-
|
|
13999
|
-
|
|
14000
|
-
|
|
14001
|
-
|
|
14002
|
-
|
|
14003
|
-
|
|
14004
|
-
if (!subId) throw Error("There is no subscription ID for this event");
|
|
14005
|
-
return this.unsubscribe(subId, WSSubscriptions.EVENTS);
|
|
14006
|
-
}
|
|
14007
|
-
/**
|
|
14008
|
-
* subscribe to transaction status
|
|
14009
|
-
* * you can subscribe to this event multiple times and you need to manage subscriptions manually
|
|
14010
|
-
*/
|
|
14011
|
-
subscribeTransactionStatusUnmanaged(transactionHash, blockIdentifier) {
|
|
14012
|
-
const transaction_hash = toHex(transactionHash);
|
|
14013
|
-
const block_id = blockIdentifier ? new Block(blockIdentifier).identifier : void 0;
|
|
14014
|
-
return this.sendReceive("starknet_subscribeTransactionStatus", {
|
|
14015
|
-
transaction_hash,
|
|
14016
|
-
...{ block_id }
|
|
14017
|
-
});
|
|
14149
|
+
const method = "starknet_subscribeEvents";
|
|
14150
|
+
const params = {
|
|
14151
|
+
from_address: fromAddress !== void 0 ? toHex(fromAddress) : void 0,
|
|
14152
|
+
keys,
|
|
14153
|
+
block_id: blockIdentifier ? new Block(blockIdentifier).identifier : void 0
|
|
14154
|
+
};
|
|
14155
|
+
const subId = await this.sendReceive(method, params);
|
|
14156
|
+
const subscription = new Subscription(this, method, params, subId, this.maxBufferSize);
|
|
14157
|
+
this.activeSubscriptions.set(subId, subscription);
|
|
14158
|
+
return subscription;
|
|
14018
14159
|
}
|
|
14019
14160
|
/**
|
|
14020
|
-
*
|
|
14161
|
+
* Subscribes to status updates for a specific transaction.
|
|
14162
|
+
* @param {BigNumberish} transactionHash - The hash of the transaction to monitor.
|
|
14163
|
+
* @param {SubscriptionBlockIdentifier} [blockIdentifier] - The block context. Not typically required.
|
|
14164
|
+
* @returns {Promise<Subscription<NEW_TXN_STATUS>>} A Promise that resolves with a `Subscription` object for the transaction's status.
|
|
14021
14165
|
*/
|
|
14022
|
-
async subscribeTransactionStatus(transactionHash) {
|
|
14023
|
-
|
|
14024
|
-
const
|
|
14025
|
-
|
|
14026
|
-
|
|
14166
|
+
async subscribeTransactionStatus(transactionHash, blockIdentifier) {
|
|
14167
|
+
const method = "starknet_subscribeTransactionStatus";
|
|
14168
|
+
const params = {
|
|
14169
|
+
transaction_hash: toHex(transactionHash),
|
|
14170
|
+
block_id: blockIdentifier ? new Block(blockIdentifier).identifier : void 0
|
|
14171
|
+
};
|
|
14172
|
+
const subId = await this.sendReceive(method, params);
|
|
14173
|
+
const subscription = new Subscription(this, method, params, subId, this.maxBufferSize);
|
|
14174
|
+
this.activeSubscriptions.set(subId, subscription);
|
|
14175
|
+
return subscription;
|
|
14027
14176
|
}
|
|
14028
14177
|
/**
|
|
14029
|
-
*
|
|
14178
|
+
* Subscribes to pending transactions.
|
|
14179
|
+
* @param {boolean} [transactionDetails] - If `true`, the full transaction details are included. Defaults to `false` (hash only).
|
|
14180
|
+
* @param {BigNumberish[]} [senderAddress] - An array of sender addresses to filter by.
|
|
14181
|
+
* @returns {Promise<Subscription<TXN_HASH | TXN_WITH_HASH>>} A Promise that resolves with a `Subscription` object for pending transactions.
|
|
14030
14182
|
*/
|
|
14031
|
-
async
|
|
14032
|
-
const
|
|
14033
|
-
|
|
14034
|
-
|
|
14183
|
+
async subscribePendingTransaction(transactionDetails, senderAddress) {
|
|
14184
|
+
const method = "starknet_subscribePendingTransactions";
|
|
14185
|
+
const params = {
|
|
14186
|
+
transaction_details: transactionDetails,
|
|
14187
|
+
sender_address: senderAddress && bigNumberishArrayToHexadecimalStringArray(senderAddress)
|
|
14188
|
+
};
|
|
14189
|
+
const subId = await this.sendReceive(method, params);
|
|
14190
|
+
const subscription = new Subscription(this, method, params, subId, this.maxBufferSize);
|
|
14191
|
+
this.activeSubscriptions.set(subId, subscription);
|
|
14192
|
+
return subscription;
|
|
14035
14193
|
}
|
|
14036
14194
|
/**
|
|
14037
|
-
*
|
|
14038
|
-
*
|
|
14195
|
+
* Internal method to remove subscription from active map.
|
|
14196
|
+
* @internal
|
|
14039
14197
|
*/
|
|
14040
|
-
|
|
14041
|
-
|
|
14042
|
-
...{ transaction_details: transactionDetails },
|
|
14043
|
-
...{
|
|
14044
|
-
sender_address: senderAddress && bigNumberishArrayToHexadecimalStringArray(senderAddress)
|
|
14045
|
-
}
|
|
14046
|
-
});
|
|
14198
|
+
removeSubscription(id) {
|
|
14199
|
+
this.activeSubscriptions.delete(id);
|
|
14047
14200
|
}
|
|
14048
14201
|
/**
|
|
14049
|
-
*
|
|
14202
|
+
* Adds a listener for a given event.
|
|
14203
|
+
* @param event The event name.
|
|
14204
|
+
* @param listener The listener function to add.
|
|
14050
14205
|
*/
|
|
14051
|
-
|
|
14052
|
-
|
|
14053
|
-
const subId = await this.subscribePendingTransactionUnmanaged(
|
|
14054
|
-
transactionDetails,
|
|
14055
|
-
senderAddress
|
|
14056
|
-
);
|
|
14057
|
-
this.subscriptions.set(WSSubscriptions.PENDING_TRANSACTION, subId);
|
|
14058
|
-
return subId;
|
|
14206
|
+
on(event, listener) {
|
|
14207
|
+
this.events.on(event, listener);
|
|
14059
14208
|
}
|
|
14060
14209
|
/**
|
|
14061
|
-
*
|
|
14210
|
+
* Removes a listener for a given event.
|
|
14211
|
+
* @param event The event name.
|
|
14212
|
+
* @param listener The listener function to remove.
|
|
14062
14213
|
*/
|
|
14063
|
-
|
|
14064
|
-
|
|
14065
|
-
if (!subId) throw Error("There is no subscription ID for this event");
|
|
14066
|
-
return this.unsubscribe(subId, WSSubscriptions.PENDING_TRANSACTION);
|
|
14214
|
+
off(event, listener) {
|
|
14215
|
+
this.events.off(event, listener);
|
|
14067
14216
|
}
|
|
14068
14217
|
};
|
|
14069
14218
|
|