@keplr-ewallet/ewallet-sdk-cosmos
Version:
110 lines (96 loc) • 2.71 kB
text/typescript
import { Buffer } from "buffer";
import { type CosmosEWallet } from "@keplr-ewallet-sdk-cosmos/cosmos_ewallet";
import {
retry,
simpleFetch,
TendermintTxTracer,
} from "@keplr-ewallet-sdk-cosmos/utils";
export async function sendTx(
this: CosmosEWallet,
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;
const params = isProtoTx
? {
tx_bytes: Buffer.from(tx as any).toString("base64"),
mode: (() => {
switch (mode) {
case "async":
return "BROADCAST_MODE_ASYNC";
case "block":
return "BROADCAST_MODE_BLOCK";
case "sync":
return "BROADCAST_MODE_SYNC";
default:
return "BROADCAST_MODE_UNSPECIFIED";
}
})(),
}
: {
tx,
mode: mode,
};
try {
const result = await simpleFetch<any>(
chainInfo.rest,
isProtoTx ? "/cosmos/tx/v1beta1/txs" : "/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 (e) {
console.log(e);
throw e;
}
}