@bronlabs/intents-sdk
Version:
SDK for Intents DeFi smart contracts
104 lines • 4.05 kB
JavaScript
import { log } from '../utils.js';
import { decodeTxRaw, DirectSecp256k1Wallet } from '@cosmjs/proto-signing';
import { GasPrice, SigningStargateClient, StargateClient } from '@cosmjs/stargate';
import { MsgSend } from 'cosmjs-types/cosmos/bank/v1beta1/tx';
export class CosmosNetwork {
constructor(rpcUrl, nativeDenom, bech32, gasPrice, confirmations = 1) {
this.retryDelay = 15000;
this.rpcUrl = rpcUrl;
this.confirmations = confirmations;
this.gasPrice = gasPrice;
this.nativeDenom = nativeDenom;
this.bech32 = bech32;
}
async getDecimals(tokenAddress) {
let denom = tokenAddress;
if (tokenAddress === "0x0") {
denom = this.nativeDenom;
}
const firstLetter = denom[0];
if (firstLetter === 'u') {
// micro
return 6;
}
if (firstLetter === 'a') {
// atto
return 18;
}
if (firstLetter === 'n') {
// nano
return 9;
}
return 0;
}
async getTxData(txHash, tokenAddress) {
const client = await StargateClient.connect(this.rpcUrl);
const resp = await client.getTx(txHash);
if (!resp) {
return;
}
if (resp.code !== 0) {
log.warn(`Transaction ${txHash} failed on blockchain: ${JSON.stringify(resp)}`);
return {
to: "",
token: "",
amount: 0n,
confirmed: false
};
}
const decodedTx = decodeTxRaw(resp.tx);
const txMessage = decodedTx.body.messages.find((message) => message.typeUrl === '/cosmos.bank.v1beta1.MsgSend');
if (!txMessage) {
log.warn(`Transaction ${txHash} has no MsgSend message: ${JSON.stringify(resp)}`);
return {
to: "",
token: "",
amount: 0n,
confirmed: false
};
}
const decodedMsg = MsgSend.decode(txMessage.value);
let denom = tokenAddress;
// Native token - specified denom
if (tokenAddress === "0x0") {
denom = this.nativeDenom;
}
const messageAmount = decodedMsg.amount.find((a) => a.denom === denom);
if (!messageAmount) {
log.warn(`Transaction ${txHash} has no amount for denom ${denom}: ${JSON.stringify(resp)}`);
return {
to: "",
token: "",
amount: 0n,
confirmed: false
};
}
const currentBlockResp = await client.getBlock();
const currentBlock = currentBlockResp.header.height;
const txBlock = resp.height;
const confirmed = (currentBlock - txBlock) >= this.confirmations;
log.info(`Confirmations ${txHash}: ${currentBlock}, confirmed: ${confirmed}`);
return {
to: decodedMsg.toAddress,
token: tokenAddress,
amount: BigInt(messageAmount.amount),
confirmed: confirmed
};
}
async transfer(privateKey, to, value, tokenAddress) {
// 1) Create wallet/signer
const wallet = await DirectSecp256k1Wallet.fromKey(Buffer.from(privateKey, 'hex'), this.bech32);
const [account] = await wallet.getAccounts();
const sender = account.address;
// 2) Connect signing client
const gasPrice = GasPrice.fromString(`${this.gasPrice}${this.nativeDenom}`); // chain-specific denom + price
const client = await SigningStargateClient.connectWithSigner(this.rpcUrl, wallet, { gasPrice });
const denom = tokenAddress === "0x0" ? this.nativeDenom : tokenAddress;
// 3) Build amount (in *base* denom)
const amount = [{ denom, amount: value.toString() }];
// CosmosJs simulates tx and do transfer
const resultAuto = await client.sendTokens(sender, to, amount, "auto");
return resultAuto.transactionHash;
}
}
//# sourceMappingURL=cosmos.js.map