@pushchain/core
Version:
## Overview
165 lines • 7.92 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PushClient = void 0;
const tslib_1 = require("tslib");
const viem_1 = require("viem");
const tx_1 = require("../generated/v1/tx");
const tx_2 = require("cosmjs-types/cosmos/tx/v1beta1/tx");
const protobufjs_1 = require("protobufjs");
const proto_signing_1 = require("@cosmjs/proto-signing");
const stargate_1 = require("@cosmjs/stargate");
const crypto_1 = require("@cosmjs/crypto");
const tendermint_rpc_1 = require("@cosmjs/tendermint-rpc");
const auth_1 = require("cosmjs-types/cosmos/auth/v1beta1/auth");
const accounts_1 = require("viem/accounts");
const encoding_1 = require("@cosmjs/encoding");
const evm_client_1 = require("../vm-client/evm-client");
const chain_1 = require("../constants/chain");
const enums_1 = require("../constants/enums");
class PushClient extends evm_client_1.EvmClient {
constructor(clientOptions) {
super(clientOptions);
this.pushChainInfo =
clientOptions.network === enums_1.PUSH_NETWORK.MAINNET
? chain_1.PUSH_CHAIN_INFO[enums_1.CHAIN.PUSH_MAINNET]
: clientOptions.network === enums_1.PUSH_NETWORK.TESTNET_DONUT
? chain_1.PUSH_CHAIN_INFO[enums_1.CHAIN.PUSH_TESTNET_DONUT]
: chain_1.PUSH_CHAIN_INFO[enums_1.CHAIN.PUSH_LOCALNET];
if (clientOptions.network === enums_1.PUSH_NETWORK.MAINNET) {
this.pushChainInfo = chain_1.PUSH_CHAIN_INFO[enums_1.CHAIN.PUSH_MAINNET];
}
else if (clientOptions.network === enums_1.PUSH_NETWORK.TESTNET_DONUT ||
clientOptions.network === enums_1.PUSH_NETWORK.TESTNET) {
this.pushChainInfo = chain_1.PUSH_CHAIN_INFO[enums_1.CHAIN.PUSH_TESTNET_DONUT];
}
else {
this.pushChainInfo = chain_1.PUSH_CHAIN_INFO[enums_1.CHAIN.PUSH_LOCALNET];
}
this.ephemeralKey = (0, accounts_1.generatePrivateKey)();
}
/**
* Converts nPUSH (1e18) to USDC (1e8), fixed rate: 1 PUSH = 0.1 USDC
*/
pushToUSDC(amount) {
return ((amount * this.pushChainInfo.pushToUsdcNumerator) /
this.pushChainInfo.pushToUsdcDenominator);
}
/**
* Converts USDC (1e8) to nPUSH (1e18), fixed rate: 1 PUSH = 0.1 USDC
*/
usdcToPush(amount) {
return ((amount * this.pushChainInfo.pushToUsdcDenominator) /
this.pushChainInfo.pushToUsdcNumerator);
}
// --- Msg Creators ---
createMsgDeployUEA(input) {
return {
typeUrl: '/uexecutor.v1.MsgDeployUEA',
value: tx_1.MsgDeployUEA.encode(tx_1.MsgDeployUEA.fromPartial(input)).finish(),
};
}
createMsgMintPC(input) {
return {
typeUrl: '/uexecutor.v1.MsgMintPC',
value: tx_1.MsgMintPC.encode(tx_1.MsgMintPC.fromPartial(input)).finish(),
};
}
createMsgExecutePayload(input) {
return {
typeUrl: '/uexecutor.v1.MsgExecutePayload',
value: tx_1.MsgExecutePayload.encode(tx_1.MsgExecutePayload.fromPartial(input)).finish(),
};
}
// --- Tx Builder ---
createCosmosTxBody(messages, memo) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
return tx_2.TxBody.fromPartial({ messages, memo });
});
}
// --- Tx Signer ---
getSignerAddress() {
const account = (0, accounts_1.privateKeyToAccount)(this.ephemeralKey);
return {
evmAddress: account.address,
cosmosAddress: (0, encoding_1.toBech32)(this.pushChainInfo.prefix, (0, viem_1.hexToBytes)(account.address)),
};
}
/**
* Signs a Cosmos tx using a temporary account.
* In prod, signer should be passed in instead.
*/
signCosmosTx(txBody) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const account = (0, accounts_1.privateKeyToAccount)(this.ephemeralKey);
const sender = (0, encoding_1.toBech32)(this.pushChainInfo.prefix, (0, viem_1.hexToBytes)(account.address));
// 🔍 Get on-chain account info
const tmClient = yield tendermint_rpc_1.Tendermint34Client.connect(this.pushChainInfo.tendermintRpc);
const status = yield tmClient.status();
const chainId = status.nodeInfo.network;
const queryClient = stargate_1.QueryClient.withExtensions(tmClient, stargate_1.setupAuthExtension);
let baseAccount = null;
try {
const accountResp = yield queryClient.auth.account(sender);
baseAccount = auth_1.BaseAccount.decode(accountResp.value);
}
catch (err) {
// Ignore
}
// 📦 Encode pubkey
const uncompressedPubKey = (0, viem_1.hexToBytes)(account.publicKey);
const compressedPubKey = crypto_1.Secp256k1.compressPubkey(uncompressedPubKey);
const pubkeyEncoded = {
typeUrl: '/cosmos.evm.crypto.v1.ethsecp256k1.PubKey',
value: protobufjs_1.Writer.create().uint32(10).bytes(compressedPubKey).finish(),
};
const authInfoBytes = (0, proto_signing_1.makeAuthInfoBytes)([
{
pubkey: pubkeyEncoded,
sequence: baseAccount ? Number(baseAccount.sequence) : 0,
},
], [], 100000000000, // gas
undefined, undefined);
const txBodyBytes = tx_2.TxBody.encode(txBody).finish();
const signDoc = (0, proto_signing_1.makeSignDoc)(txBodyBytes, authInfoBytes, chainId, baseAccount ? Number(baseAccount.accountNumber) : 0);
const digest = (0, viem_1.keccak256)(tx_2.SignDoc.encode(signDoc).finish());
const signature = yield account.sign({ hash: digest });
return tx_2.TxRaw.fromPartial({
bodyBytes: txBodyBytes,
authInfoBytes,
signatures: [(0, viem_1.hexToBytes)(signature)],
});
});
}
broadcastCosmosTx(txRaw) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const client = yield stargate_1.StargateClient.connect(this.pushChainInfo.tendermintRpc);
const result = yield client.broadcastTx(tx_2.TxRaw.encode(txRaw).finish());
return result;
});
}
/**
* Fetches a Cosmos transaction by its hash.
* @param txHash The hex‐encoded transaction hash (without “0x” or with—both work).
* @returns The indexed transaction (height, logs, events, etc.).
* @throws If the tx isn’t found.
*/
getCosmosTx(txHash) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
// 1. Connect to the Tendermint RPC
const client = yield stargate_1.StargateClient.connect(this.pushChainInfo.tendermintRpc);
// Raw string query—must be one string, not a KV array:
const query = `ethereum_tx.ethereumTxHash='${txHash}'`;
const results = yield client.searchTx(query);
// Convert bigint values to strings in the results. This is done to avoid JSON.stringify()
// from converting bigint to string when on the client side.
// On documentation, one thing very common was to use JSON.stringify() to log the results, then we would get an error.
const convertedResults = results.map((result) => JSON.parse(JSON.stringify(result, (key, value) => typeof value === 'bigint' ? value.toString() : value)));
if (convertedResults.length === 0) {
throw new Error(`No Cosmos-indexed tx for EVM hash ${txHash}`);
}
return Object.assign(Object.assign({}, convertedResults[0]), { transactionHash: txHash });
});
}
}
exports.PushClient = PushClient;
//# sourceMappingURL=push-client.js.map