@keplr-ewallet/ewallet-sdk-cosmos
Version:
110 lines (94 loc) • 2.63 kB
text/typescript
import { Buffer } from "buffer";
import {
retry,
simpleFetch,
TendermintTxTracer,
} from "@keplr-ewallet-sdk-cosmos/utils";
import type { CosmosEWalletInterface } from "@keplr-ewallet-sdk-cosmos/types";
export async function sendTx(
this: CosmosEWalletInterface,
chainId: string,
tx: unknown,
mode: "async" | "sync" | "block",
options: {
silent?: boolean;
onFulfill?: (tx: any) => void;
},
): Promise<Uint8Array> {
const chainInfoList = await this.getCosmosChainInfo();
const chainInfo = chainInfoList.find((info) => info.chainId === chainId);
if (!chainInfo) {
throw new Error(`Chain info not found for chainId: ${chainId}`);
}
const isProtoTx = Buffer.isBuffer(tx) || tx instanceof Uint8Array;
let _mode;
switch (mode) {
case "async":
_mode = "BROADCAST_MODE_ASYNC";
break;
case "block":
_mode = "BROADCAST_MODE_BLOCK";
break;
case "sync":
_mode = "BROADCAST_MODE_SYNC";
break;
default:
_mode = "BROADCAST_MODE_UNSPECIFIED";
}
const params = {
tx_bytes: Buffer.from(tx as any).toString("base64"),
mode: _mode,
};
try {
const result = await simpleFetch<any>(
chainInfo.rest,
"/cosmos/tx/v1beta1/txs",
{
method: "POST",
headers: {
"content-type": "application/json",
},
body: JSON.stringify(params),
},
);
const txResponse = isProtoTx ? result.data["tx_response"] : result.data;
if (txResponse.code != null && txResponse.code !== 0) {
throw new Error(txResponse["raw_log"]);
}
const txHash = Buffer.from(txResponse.txhash, "hex");
retry(
() => {
return new Promise<void>((resolve, reject) => {
const txTracer = new TendermintTxTracer(chainInfo.rpc, "/websocket");
txTracer.addEventListener("close", () => {
setTimeout(() => {
reject();
}, 500);
});
txTracer.addEventListener("error", () => {
reject();
});
txTracer.traceTx(txHash).then((tx) => {
txTracer.close();
if (options.onFulfill) {
if (!tx.hash) {
tx.hash = txHash;
}
options.onFulfill(tx);
}
resolve();
});
});
},
{
maxRetries: 10,
waitMsAfterError: 10 * 1000, // 10sec
maxWaitMsAfterError: 5 * 60 * 1000, // 5min
},
);
return txHash;
} catch (err: any) {
console.error("Error sending tx, err: %s", err.toString());
throw err;
}
}