@hardkas/kaspa-rpc 0.8.4-alpha → 0.8.9-alpha
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 +8 -5
- package/dist/index.js +120 -96
- package/package.json +8 -4
package/dist/index.d.ts
CHANGED
|
@@ -275,7 +275,7 @@ interface KaspaRpcClient {
|
|
|
275
275
|
healthCheck(): Promise<KaspaRpcHealth>;
|
|
276
276
|
getBalanceByAddress(address: string): Promise<KaspaAddressBalance>;
|
|
277
277
|
getUtxosByAddress(address: string): Promise<KaspaRpcUtxo[]>;
|
|
278
|
-
submitTransaction(rawTransaction:
|
|
278
|
+
submitTransaction(rawTransaction: unknown): Promise<KaspaSubmitTransactionResult>;
|
|
279
279
|
getMempoolEntry(txId: string): Promise<MempoolEntry | null>;
|
|
280
280
|
getTransaction(txId: string): Promise<unknown | null>;
|
|
281
281
|
getBlockDagInfo(): Promise<BlockDagInfo>;
|
|
@@ -288,18 +288,21 @@ declare class JsonWrpcKaspaClient implements KaspaRpcClient {
|
|
|
288
288
|
private readonly timeoutMs;
|
|
289
289
|
private requestId;
|
|
290
290
|
constructor(options: JsonWrpcKaspaClientOptions);
|
|
291
|
+
private rpcFlavor;
|
|
292
|
+
private preflightPromise;
|
|
293
|
+
private detectFlavor;
|
|
294
|
+
private callMethod;
|
|
291
295
|
getInfo(): Promise<KaspaNodeInfo>;
|
|
292
296
|
healthCheck(): Promise<KaspaRpcHealth>;
|
|
293
297
|
getBalanceByAddress(address: string): Promise<KaspaAddressBalance>;
|
|
294
298
|
getUtxosByAddress(address: string): Promise<KaspaRpcUtxo[]>;
|
|
295
|
-
submitTransaction(rawTransaction:
|
|
299
|
+
submitTransaction(rawTransaction: unknown): Promise<KaspaSubmitTransactionResult>;
|
|
296
300
|
getMempoolEntry(txId: string): Promise<MempoolEntry | null>;
|
|
297
301
|
getTransaction(txId: string): Promise<unknown | null>;
|
|
298
302
|
getBlockDagInfo(): Promise<BlockDagInfo>;
|
|
299
303
|
getServerInfo(): Promise<ServerInfo>;
|
|
300
304
|
close(): Promise<void>;
|
|
301
|
-
private
|
|
302
|
-
private request;
|
|
305
|
+
private requestRaw;
|
|
303
306
|
private connect;
|
|
304
307
|
}
|
|
305
308
|
declare function mapKaspaNodeInfo(result: any): KaspaNodeInfo;
|
|
@@ -315,7 +318,7 @@ declare class MockKaspaRpcClient implements KaspaRpcClient {
|
|
|
315
318
|
getBalanceByAddress(address: string): Promise<KaspaAddressBalance>;
|
|
316
319
|
getUtxosByAddress(address: string): Promise<KaspaRpcUtxo[]>;
|
|
317
320
|
setUtxos(address: string, utxos: KaspaRpcUtxo[]): void;
|
|
318
|
-
submitTransaction(rawTransaction:
|
|
321
|
+
submitTransaction(rawTransaction: unknown): Promise<KaspaSubmitTransactionResult>;
|
|
319
322
|
getMempoolEntry(_txId: string): Promise<MempoolEntry | null>;
|
|
320
323
|
getTransaction(_txId: string): Promise<unknown | null>;
|
|
321
324
|
getBlockDagInfo(): Promise<BlockDagInfo>;
|
package/dist/index.js
CHANGED
|
@@ -310,8 +310,51 @@ var KaspaJsonRpcClient = class {
|
|
|
310
310
|
}
|
|
311
311
|
}
|
|
312
312
|
async submitTransaction(rawTx) {
|
|
313
|
+
let txObj = rawTx;
|
|
314
|
+
try {
|
|
315
|
+
while (typeof txObj === "string" && txObj.startsWith("{")) {
|
|
316
|
+
const parsed = JSON.parse(txObj);
|
|
317
|
+
if (parsed && typeof parsed === "object") {
|
|
318
|
+
if ("tx" in parsed) txObj = parsed.tx;
|
|
319
|
+
else if ("inner" in parsed) txObj = parsed.inner;
|
|
320
|
+
else txObj = parsed;
|
|
321
|
+
} else {
|
|
322
|
+
txObj = parsed;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
while (txObj && typeof txObj === "object" && !Array.isArray(txObj) && ("tx" in txObj || "inner" in txObj)) {
|
|
326
|
+
if ("tx" in txObj) txObj = txObj.tx;
|
|
327
|
+
else if ("inner" in txObj) txObj = txObj.inner;
|
|
328
|
+
}
|
|
329
|
+
const txAny = txObj;
|
|
330
|
+
if (txAny && typeof txAny === "object") {
|
|
331
|
+
txAny.mass = txAny.mass || 0;
|
|
332
|
+
if (txAny.payload === void 0) txAny.payload = "";
|
|
333
|
+
if (txAny.outputs && Array.isArray(txAny.outputs)) {
|
|
334
|
+
txAny.outputs.forEach((output) => {
|
|
335
|
+
const amount = output.amount !== void 0 ? output.amount : output.value;
|
|
336
|
+
output.value = typeof amount === "string" ? Number(amount) : amount;
|
|
337
|
+
delete output.amount;
|
|
338
|
+
if (output.scriptPublicKey && typeof output.scriptPublicKey === "object") {
|
|
339
|
+
const spk = output.scriptPublicKey;
|
|
340
|
+
const versionHex = (spk.version || 0).toString(16).padStart(4, "0");
|
|
341
|
+
const scriptHex = spk.script || spk.scriptPublicKey || "";
|
|
342
|
+
output.scriptPublicKey = versionHex + scriptHex;
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
if (txAny.inputs && Array.isArray(txAny.inputs)) {
|
|
347
|
+
txAny.inputs.forEach((input) => {
|
|
348
|
+
if (typeof input.sequence === "string") input.sequence = Number(input.sequence);
|
|
349
|
+
if (typeof input.sigOpCount === "string") input.sigOpCount = Number(input.sigOpCount);
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
} catch (e) {
|
|
354
|
+
}
|
|
313
355
|
const result = await this.callRpc("submitTransactionRequest", {
|
|
314
|
-
transaction:
|
|
356
|
+
transaction: txObj,
|
|
357
|
+
allowOrphan: false
|
|
315
358
|
});
|
|
316
359
|
return { transactionId: result.transactionId };
|
|
317
360
|
}
|
|
@@ -778,27 +821,40 @@ var JsonWrpcKaspaClient = class {
|
|
|
778
821
|
this.rpcUrl = options.rpcUrl;
|
|
779
822
|
this.timeoutMs = options.timeoutMs ?? 1e4;
|
|
780
823
|
}
|
|
824
|
+
rpcFlavor = null;
|
|
825
|
+
preflightPromise = null;
|
|
826
|
+
async detectFlavor() {
|
|
827
|
+
if (this.rpcFlavor) return;
|
|
828
|
+
if (this.preflightPromise) return this.preflightPromise;
|
|
829
|
+
this.preflightPromise = (async () => {
|
|
830
|
+
try {
|
|
831
|
+
const ws = await this.connect();
|
|
832
|
+
const res = await this.requestRaw("getServerInfo", {});
|
|
833
|
+
this.rpcFlavor = "wrpc";
|
|
834
|
+
} catch (e) {
|
|
835
|
+
if (e.message && e.message.includes("Method not found")) {
|
|
836
|
+
this.rpcFlavor = "legacy";
|
|
837
|
+
} else {
|
|
838
|
+
this.rpcFlavor = "wrpc";
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
})();
|
|
842
|
+
return this.preflightPromise;
|
|
843
|
+
}
|
|
844
|
+
async callMethod(wrpcName, legacyName, params = {}) {
|
|
845
|
+
await this.detectFlavor();
|
|
846
|
+
const method = this.rpcFlavor === "legacy" ? legacyName : wrpcName;
|
|
847
|
+
return this.requestRaw(method, params);
|
|
848
|
+
}
|
|
781
849
|
async getInfo() {
|
|
782
|
-
const response = await this.
|
|
783
|
-
"getInfo",
|
|
784
|
-
"getInfoRequest",
|
|
785
|
-
"GetInfo",
|
|
786
|
-
"get_info"
|
|
787
|
-
]);
|
|
850
|
+
const response = await this.callMethod("getInfo", "getInfoRequest");
|
|
788
851
|
const info = mapKaspaNodeInfo(response);
|
|
789
852
|
if (info.virtualDaaScore === void 0) {
|
|
790
853
|
try {
|
|
791
|
-
const dagResponse = await this.
|
|
792
|
-
"getBlockDagInfo",
|
|
793
|
-
"getBlockDagInfoRequest",
|
|
794
|
-
"GetBlockDagInfo",
|
|
795
|
-
"get_block_dag_info"
|
|
796
|
-
]);
|
|
854
|
+
const dagResponse = await this.callMethod("getBlockDagInfo", "getBlockDagInfoRequest");
|
|
797
855
|
const dagData = dagResponse?.params || dagResponse;
|
|
798
856
|
if (dagData && typeof dagData === "object" && "virtualDaaScore" in dagData) {
|
|
799
|
-
info.virtualDaaScore = BigInt(
|
|
800
|
-
dagData.virtualDaaScore
|
|
801
|
-
);
|
|
857
|
+
info.virtualDaaScore = BigInt(dagData.virtualDaaScore);
|
|
802
858
|
}
|
|
803
859
|
} catch (e) {
|
|
804
860
|
}
|
|
@@ -824,55 +880,61 @@ var JsonWrpcKaspaClient = class {
|
|
|
824
880
|
}
|
|
825
881
|
}
|
|
826
882
|
async getBalanceByAddress(address) {
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
"GetBalanceByAddress",
|
|
835
|
-
"getBalanceByAddress",
|
|
836
|
-
"get_balance_by_address"
|
|
837
|
-
],
|
|
838
|
-
{ addresses: [address], address }
|
|
839
|
-
);
|
|
883
|
+
await this.detectFlavor();
|
|
884
|
+
let response;
|
|
885
|
+
if (this.rpcFlavor === "legacy") {
|
|
886
|
+
response = await this.callMethod("getBalanceByAddress", "getBalanceByAddressRequest", { address });
|
|
887
|
+
} else {
|
|
888
|
+
response = await this.callMethod("getBalancesByAddresses", "getBalancesByAddressesRequest", { addresses: [address] });
|
|
889
|
+
}
|
|
840
890
|
return mapKaspaAddressBalance(response, address);
|
|
841
891
|
}
|
|
842
892
|
async getUtxosByAddress(address) {
|
|
843
|
-
const response = await this.
|
|
844
|
-
[
|
|
845
|
-
"getUtxosByAddresses",
|
|
846
|
-
"getUtxosByAddressesRequest",
|
|
847
|
-
"getUtxosByAddressRequest",
|
|
848
|
-
"GetUtxosByAddresses",
|
|
849
|
-
"get_utxos_by_addresses",
|
|
850
|
-
"GetUtxosByAddress",
|
|
851
|
-
"getUtxosByAddress",
|
|
852
|
-
"get_utxos_by_address"
|
|
853
|
-
],
|
|
854
|
-
{ addresses: [address], address }
|
|
855
|
-
);
|
|
893
|
+
const response = await this.callMethod("getUtxosByAddresses", "getUtxosByAddressesRequest", { addresses: [address] });
|
|
856
894
|
return mapKaspaRpcUtxos(response, address);
|
|
857
895
|
}
|
|
858
896
|
async submitTransaction(rawTransaction) {
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
"
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
897
|
+
let txObj = rawTransaction;
|
|
898
|
+
try {
|
|
899
|
+
while (typeof txObj === "string" && txObj.startsWith("{")) {
|
|
900
|
+
const parsed = JSON.parse(txObj);
|
|
901
|
+
if (parsed && typeof parsed === "object") {
|
|
902
|
+
if ("tx" in parsed) txObj = parsed.tx;
|
|
903
|
+
else if ("inner" in parsed) txObj = parsed.inner;
|
|
904
|
+
else txObj = parsed;
|
|
905
|
+
} else {
|
|
906
|
+
txObj = parsed;
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
while (txObj && typeof txObj === "object" && !Array.isArray(txObj) && ("tx" in txObj || "inner" in txObj)) {
|
|
910
|
+
if ("tx" in txObj) txObj = txObj.tx;
|
|
911
|
+
else if ("inner" in txObj) txObj = txObj.inner;
|
|
912
|
+
}
|
|
913
|
+
const txAny = txObj;
|
|
914
|
+
if (txAny && typeof txAny === "object" && txAny.outputs && Array.isArray(txAny.outputs)) {
|
|
915
|
+
txAny.outputs.forEach((output) => {
|
|
916
|
+
if (typeof output.amount === "string") {
|
|
917
|
+
output.amount = Number(output.amount);
|
|
918
|
+
}
|
|
919
|
+
if (typeof output.value === "string") {
|
|
920
|
+
output.value = Number(output.value);
|
|
921
|
+
}
|
|
922
|
+
});
|
|
923
|
+
}
|
|
924
|
+
if (txAny && typeof txAny === "object" && txAny.inputs && Array.isArray(txAny.inputs)) {
|
|
925
|
+
txAny.inputs.forEach((input) => {
|
|
926
|
+
if (typeof input.sequence === "string") input.sequence = Number(input.sequence);
|
|
927
|
+
if (typeof input.sigOpCount === "string") input.sigOpCount = Number(input.sigOpCount);
|
|
928
|
+
});
|
|
929
|
+
}
|
|
930
|
+
} catch (e) {
|
|
931
|
+
}
|
|
932
|
+
const response = await this.callMethod("submitTransaction", "submitTransactionRequest", { transaction: txObj, allowOrphan: false });
|
|
868
933
|
return mapKaspaSubmitTransactionResult(response);
|
|
869
934
|
}
|
|
870
935
|
async getMempoolEntry(txId) {
|
|
871
936
|
try {
|
|
872
|
-
const response = await this.
|
|
873
|
-
["getMempoolEntryRequest", "getMempoolEntry"],
|
|
874
|
-
{ txId, transactionId: txId }
|
|
875
|
-
);
|
|
937
|
+
const response = await this.callMethod("getMempoolEntry", "getMempoolEntryRequest", { transactionId: txId, includeOrphanPool: true, filterTransactionPool: false });
|
|
876
938
|
if (!response) return null;
|
|
877
939
|
const resObj = response;
|
|
878
940
|
return {
|
|
@@ -885,11 +947,7 @@ var JsonWrpcKaspaClient = class {
|
|
|
885
947
|
}
|
|
886
948
|
async getTransaction(txId) {
|
|
887
949
|
try {
|
|
888
|
-
|
|
889
|
-
["getTransactionRequest", "getTransaction"],
|
|
890
|
-
{ txId, transactionId: txId }
|
|
891
|
-
);
|
|
892
|
-
return response;
|
|
950
|
+
return await this.callMethod("getTransaction", "getTransactionRequest", { transactionId: txId });
|
|
893
951
|
} catch (e) {
|
|
894
952
|
return null;
|
|
895
953
|
}
|
|
@@ -920,41 +978,7 @@ var JsonWrpcKaspaClient = class {
|
|
|
920
978
|
this.socket = null;
|
|
921
979
|
}
|
|
922
980
|
}
|
|
923
|
-
async
|
|
924
|
-
let lastError = null;
|
|
925
|
-
for (const method of methods) {
|
|
926
|
-
try {
|
|
927
|
-
let actualParams = params;
|
|
928
|
-
const lowerMethod = method.toLowerCase();
|
|
929
|
-
const pObj = params;
|
|
930
|
-
if (lowerMethod.includes("addresses") || lowerMethod.endsWith("s")) {
|
|
931
|
-
if (pObj.address && !pObj.addresses) {
|
|
932
|
-
actualParams = { addresses: [pObj.address] };
|
|
933
|
-
} else if (pObj.addresses) {
|
|
934
|
-
actualParams = { addresses: pObj.addresses };
|
|
935
|
-
}
|
|
936
|
-
} else if (pObj.addresses && !pObj.address) {
|
|
937
|
-
actualParams = { address: pObj.addresses[0] };
|
|
938
|
-
} else if (pObj.address) {
|
|
939
|
-
actualParams = { address: pObj.address };
|
|
940
|
-
}
|
|
941
|
-
try {
|
|
942
|
-
return await this.request(method, actualParams);
|
|
943
|
-
} catch (e) {
|
|
944
|
-
if (e.message?.includes("deserialization")) {
|
|
945
|
-
const arrayParams = Object.values(actualParams);
|
|
946
|
-
return await this.request(method, arrayParams);
|
|
947
|
-
}
|
|
948
|
-
throw e;
|
|
949
|
-
}
|
|
950
|
-
} catch (error) {
|
|
951
|
-
lastError = error;
|
|
952
|
-
continue;
|
|
953
|
-
}
|
|
954
|
-
}
|
|
955
|
-
throw lastError ?? new Error(`Methods failed: ${methods.join(", ")}`);
|
|
956
|
-
}
|
|
957
|
-
async request(method, params = {}) {
|
|
981
|
+
async requestRaw(method, params = {}) {
|
|
958
982
|
const ws = await this.connect();
|
|
959
983
|
const id = this.requestId++;
|
|
960
984
|
const payload = JSON.stringify({
|
|
@@ -1112,7 +1136,7 @@ function mapKaspaSubmitTransactionResult(result) {
|
|
|
1112
1136
|
if (!result) return { raw: result };
|
|
1113
1137
|
return {
|
|
1114
1138
|
transactionId: result.transactionId || result.transaction_id || result.txId || result.tx_id,
|
|
1115
|
-
accepted: result.accepted !== void 0 ? result.accepted : result.isAccepted || result.
|
|
1139
|
+
accepted: result.accepted !== void 0 ? result.accepted : result.isAccepted !== void 0 ? result.isAccepted : result.success !== void 0 ? result.success : !!(result.transactionId || result.transaction_id || result.txId || result.tx_id),
|
|
1116
1140
|
raw: result
|
|
1117
1141
|
};
|
|
1118
1142
|
}
|
package/package.json
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hardkas/kaspa-rpc",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.9-alpha",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
7
|
"exports": {
|
|
8
|
-
".":
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
}
|
|
9
13
|
},
|
|
10
14
|
"dependencies": {
|
|
11
15
|
"ws": "^8.18.0",
|
|
12
|
-
"@hardkas/core": "0.8.
|
|
13
|
-
"@hardkas/tx-builder": "0.8.
|
|
16
|
+
"@hardkas/core": "0.8.9-alpha",
|
|
17
|
+
"@hardkas/tx-builder": "0.8.9-alpha"
|
|
14
18
|
},
|
|
15
19
|
"devDependencies": {
|
|
16
20
|
"@types/ws": "^8.5.13",
|