icepick workflow cosmos transfer

This commit is contained in:
Ryan Heywood 2025-01-22 04:09:43 -05:00
parent db5ca73d10
commit d00a67e0b7
Signed by: ryan
GPG Key ID: 8E401478A3FBEF72
3 changed files with 115 additions and 22 deletions

View File

@ -161,11 +161,10 @@ pub fn default_chains() -> Vec<Blockchain> {
.coin_decimals(6)
.coin_gecko_id("unknown")
.build();
// NOTE: high is listed as 0.03 on devnet, but simulating tx actually cost 30915 tkyve.
let tkyve_gas = GasPriceStep::builder()
.low(0.01)
.average(0.05)
.high(0.1)
.average(0.025)
.high(0.03)
.build();
chains.push(

View File

@ -32,7 +32,7 @@ pub struct GetWalletAddress {
}
#[derive(Serialize, Deserialize, Debug)]
pub struct GetAccountInfo {
pub struct GetAccountData {
account_id: String,
blockchain_config: coin_denoms::Blockchain,
@ -57,7 +57,7 @@ pub struct Transfer {
// TODO: find a way to simulate transaction and calculate gas necessary
// for now, 0.01KYVE seems to be a reasonable mainnet number?
// for testing purposes, i'm gonna go much lower. 0.0001.
gas: Option<String>,
gas_factor: Option<String>,
blockchain_config: coin_denoms::Blockchain,
}
@ -66,8 +66,8 @@ pub struct Transfer {
pub struct Sign {
fee: remote_serde::Fee,
tx_messages: Vec<Any>,
account_number: String,
sequence_number: String,
account_number: u64,
sequence_number: u64,
blockchain_config: coin_denoms::Blockchain,
}
@ -94,7 +94,7 @@ pub enum Operation {
GetChainInfo(GetChainInfo),
GenerateWallet(GenerateWallet),
GetWalletAddress(GetWalletAddress),
GetAccountInfo(GetAccountInfo),
GetAccountData(GetAccountData),
AwaitFunds(AwaitFunds),
Transfer(Transfer),
Sign(Sign),
@ -188,7 +188,7 @@ impl Module for Cosmos {
.argument(&address_prefix);
let get_account_info = Operation::builder()
.name("get-account-info")
.name("get-account-data")
.description("Get the account number and sequence number for an account.")
.build()
.argument(
@ -255,8 +255,8 @@ impl Module for Cosmos {
)
.argument(
&Argument::builder()
.name("gas")
.description("The amount of gas to supply.")
.name("gas_factor")
.description("The factor to multiply the default gas amount by.")
.r#type(ArgumentType::Optional)
.build(),
);
@ -336,7 +336,7 @@ impl Module for Cosmos {
}
}))
}
Operation::GetAccountInfo(GetAccountInfo {
Operation::GetAccountData(GetAccountData {
account_id,
blockchain_config,
}) => {
@ -437,7 +437,7 @@ impl Module for Cosmos {
to_address,
from_account: _,
from_address,
gas: _,
gas_factor,
blockchain_config,
}) => {
// Check if given denom is min denom or normal and adjust accordingly
@ -449,6 +449,13 @@ impl Module for Cosmos {
panic!("{denom} not in {blockchain_config:?}");
};
let gas_factor = gas_factor
.as_deref()
.map(f64::from_str)
.transpose()
.unwrap()
.unwrap_or(1.0);
let amount = f64::from_str(&amount).unwrap();
let adjusted_amount = if relevant_denom.coin_denom == denom {
amount * 10f64.powi(i32::from(relevant_denom.coin_decimals))
@ -474,11 +481,23 @@ impl Module for Cosmos {
.to_any()
.unwrap();
let expected_gas = 100_000u64;
// convert gas "price" to minimum denom,
// multiply by amount of gas required,
// multiply by gas factor if necessary.
let expected_fee = blockchain_config.gas_price_step.high
// * dbg!(10f64.powi(relevant_denom.coin_decimals as i32))
* expected_gas as f64
* gas_factor;
let fee_coin = cosmrs::Coin {
denom: relevant_denom.coin_minimal_denom.parse().unwrap(),
amount: expected_fee as u128,
};
let fee = Fee::from_amount_and_gas(
coin,
(blockchain_config.gas_price_step.high
* 10f64.powi(relevant_denom.coin_decimals as i32))
as u64,
fee_coin,
expected_gas,
);
#[allow(clippy::identity_op)]
@ -508,11 +527,6 @@ impl Module for Cosmos {
let fee = cosmrs::tx::Fee::from(&fee);
let tx_body = BodyBuilder::new().msgs(tx_messages).finish();
// TODO: these should be gained by the `broadcast` workflow, similar to
// how nonce data is acquired in Solana
let account_number: u64 = account_number.parse().unwrap();
let sequence_number: u64 = sequence_number.parse().unwrap();
let auth_info =
SignerInfo::single_direct(Some(privkey.public_key()), sequence_number)
.auth_info(fee);

View File

@ -225,3 +225,83 @@ inputs = { transaction = "signed_transaction" }
name = "cosmos"
derivation_prefix = "m/44'/118'/0'"
algorithm = "Secp256k1"
[[module.workflow]]
name = "transfer"
inputs = ["from_address", "to_address", "asset_name", "chain_name", "asset_amount"]
[[module.workflow.step]]
# NOTE: chain_name can't be discoverable by filtering from asset_name, since
# some asset devnets reuse the name. There's no difference between KYVE on Kyve
# or Korellia (devnet).
type = "cosmos-get-chain-info"
inputs = { chain_name = "chain_name" }
outputs = { blockchain_config = "blockchain_config" }
[[module.workflow.step]]
type = "internal-load-file"
values = { filename = "account_info.json" }
outputs = { account_number = "account_number", sequence_number = "sequence_number" }
[[module.workflow.step]]
type = "cosmos-transfer"
[module.workflow.step.inputs]
from_address = "from_address"
to_address = "to_address"
amount = "asset_amount"
denom = "asset_name"
blockchain_config = "blockchain_config"
[module.workflow.step.outputs]
fee = "fee"
tx_messages = "tx_messages"
[[module.workflow.step]]
type = "cosmos-sign"
[module.workflow.step.inputs]
fee = "fee"
tx_messages = "tx_messages"
account_number = "account_number"
sequence_number = "sequence_number"
blockchain_config = "blockchain_config"
[module.workflow.step.outputs]
transaction = "signed_transaction"
[[module.workflow.step]]
type = "internal-save-file"
values = { filename = "transaction.json" }
inputs = { transaction = "signed_transaction" }
[[module.workflow]]
name = "broadcast"
# NOTE: For the purpose of Cosmos, the nonce is a direct part of the signer's
# account.
inputs = ["nonce_address", "chain_name"]
[[module.workflow.step]]
type = "cosmos-get-chain-info"
inputs = { chain_name = "chain_name" }
outputs = { blockchain_config = "blockchain_config" }
[[module.workflow.step]]
type = "cosmos-get-account-data"
inputs = { account_id = "nonce_address", blockchain_config = "blockchain_config" }
outputs = { account_number = "account_number", sequence_number = "sequence_number" }
[[module.workflow.step]]
type = "internal-save-file"
values = { filename = "account_info.json" }
inputs = { account_number = "account_number", sequence_number = "sequence_number" }
[[module.workflow.step]]
type = "internal-load-file"
values = { filename = "transaction.json" }
outputs = { transaction = "transaction" }
[[module.workflow.step]]
type = "cosmos-broadcast"
inputs = { blockchain_config = "blockchain_config", transaction = "transaction" }
outputs = { status = "status", url = "url", error = "error", error_code = "error_code" }