Skip to content

Commit

Permalink
feat: gin indexable tx functions #28
Browse files Browse the repository at this point in the history
  • Loading branch information
Mercurial authored Jul 2, 2024
1 parent 758ecd1 commit ea1ee00
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 56 deletions.
2 changes: 1 addition & 1 deletion extension/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mumak"
version = "0.0.2"
version = "0.0.3"
edition = "2021"

[lib]
Expand Down
158 changes: 103 additions & 55 deletions extension/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,24 @@ fn tx_inputs(tx_cbor: &[u8]) -> TableIterator<'static, (name!(hash, String), nam
TableIterator::new(inputs_data.into_iter())
}

#[pg_extern(immutable)]
fn tx_inputs_json(tx_cbor: &[u8]) -> pgrx::JsonB {
let tx = match MultiEraTx::decode(tx_cbor) {
Ok(x) => x,
Err(_) => return pgrx::JsonB(serde_json::json!([])),
};

let inputs: Vec<serde_json::Value> = tx.inputs()
.iter()
.map(|i| serde_json::json!({
"hash": i.hash().to_string(),
"index": i.index()
}))
.collect();

pgrx::JsonB(serde_json::to_value(inputs).unwrap())
}

#[pg_extern(immutable)]
fn tx_outputs(
tx_cbor: &[u8],
Expand Down Expand Up @@ -237,8 +255,8 @@ fn tx_outputs(
),
match o.datum() {
Some(d) => match d {
pallas::ledger::primitives::conway::PseudoDatumOption::Hash(_) => {
pgrx::Json(serde_json::json!(null))
pallas::ledger::primitives::conway::PseudoDatumOption::Hash(h) => {
pgrx::Json(serde_json::json!(h))
}
pallas::ledger::primitives::conway::PseudoDatumOption::Data(d) => {
pgrx::Json(d.unwrap().deref().to_json())
Expand All @@ -254,38 +272,51 @@ fn tx_outputs(
}

#[pg_extern(immutable)]
fn tx_inputs_json(tx_cbor: &[u8]) -> pgrx::Json {
fn tx_outputs_json(tx_cbor: &[u8]) -> pgrx::JsonB {
let tx = match MultiEraTx::decode(tx_cbor) {
Ok(x) => x,
Err(_) => return pgrx::Json(serde_json::to_value(vec![""]).unwrap()),
Err(_) => return pgrx::JsonB(serde_json::json!([])),
};

pgrx::Json(
serde_json::to_value(
tx.inputs()
.iter()
.map(|i| (i.hash().to_string(), i.index()))
.collect::<Vec<(String, u64)>>(),
)
.unwrap(),
)
}
let outputs_data: Vec<serde_json::Value> = tx
.outputs()
.iter()
.enumerate()
.map(|(i, o)| {
serde_json::json!({
"output_index": i as i32,
"address": match o.address().unwrap().to_bech32() {
Ok(address) => address,
Err(_) => ByronAddress::from_bytes(&o.address().unwrap().to_vec()).unwrap().to_base58(),
},
"lovelace": o.lovelace_amount().to_string(),
"assets": o.non_ada_assets()
.iter()
.map(|asset| {
let policy_id = hex::encode(asset.policy().as_ref());
let assets: HashMap<String, String> = asset
.assets()
.iter()
.map(|a| (hex::encode(a.name()), a.any_coin().to_string()))
.collect();

#[pg_extern(immutable)]
fn tx_inputs_cbor(tx_cbor: &[u8]) -> Vec<u8> {
let tx = match MultiEraTx::decode(tx_cbor) {
Ok(x) => x,
Err(_) => return vec![],
};
(policy_id, assets)
})
.collect::<HashMap<_, _>>(),
"datum": match o.datum() {
Some(d) => match d {
pallas::ledger::primitives::conway::PseudoDatumOption::Hash(h) =>
serde_json::json!(h),
pallas::ledger::primitives::conway::PseudoDatumOption::Data(d) =>
d.unwrap().deref().to_json(),
},
None => serde_json::json!(null),
},
})
})
.collect();

let inputs = tx
.inputs()
.iter()
.map(|i| (i.hash().to_string(), i.index()))
.collect::<Vec<_>>();
let mut encoded_inputs: Vec<u8> = Vec::new();
pallas::codec::minicbor::encode(&inputs, &mut encoded_inputs).unwrap();
encoded_inputs
pgrx::JsonB(serde_json::json!(outputs_data))
}

#[pg_extern(immutable)]
Expand All @@ -305,13 +336,13 @@ fn tx_addresses(tx_cbor: &[u8]) -> SetOfIterator<'static, Vec<u8>> {
}

#[pg_extern(immutable)]
fn tx_addresses_json(tx_cbor: &[u8]) -> pgrx::Json {
fn tx_addresses_json(tx_cbor: &[u8]) -> pgrx::JsonB {
let tx = match MultiEraTx::decode(tx_cbor) {
Ok(x) => x,
Err(_) => return pgrx::Json(serde_json::to_value(vec![""]).unwrap()),
Err(_) => return pgrx::JsonB(serde_json::json!([])),
};

pgrx::Json(
pgrx::JsonB(
serde_json::to_value(
tx.outputs()
.iter()
Expand All @@ -328,20 +359,22 @@ fn tx_addresses_json(tx_cbor: &[u8]) -> pgrx::Json {
}

#[pg_extern(immutable)]
fn tx_plutus_data(tx_cbor: &[u8]) -> Vec<pgrx::Json> {
fn tx_plutus_data(tx_cbor: &[u8]) -> pgrx::JsonB {
let tx = match MultiEraTx::decode(tx_cbor) {
Ok(x) => x,
Err(_) => return vec![],
Err(_) => return pgrx::JsonB(serde_json::json!([])),
};

tx.plutus_data()
let plutus_data: Vec<serde_json::Value> = tx.plutus_data()
.iter()
.map(|x| pgrx::Json(x.to_json()))
.collect()
.map(|x| x.to_json())
.collect();

pgrx::JsonB(serde_json::json!(plutus_data))
}

#[pg_extern(immutable)]
fn tx_total_lovelace(tx_cbor: &[u8]) -> pgrx::AnyNumeric {
fn tx_lovelace(tx_cbor: &[u8]) -> pgrx::AnyNumeric {
let tx = match MultiEraTx::decode(tx_cbor) {
Ok(x) => x,
Err(_) => return AnyNumeric::from(0),
Expand Down Expand Up @@ -369,32 +402,29 @@ fn tx_fee(tx_cbor: &[u8]) -> pgrx::AnyNumeric {
}

#[pg_extern(immutable)]
fn tx_mint(tx_cbor: &[u8]) -> pgrx::Json {
fn tx_mint(tx_cbor: &[u8]) -> pgrx::JsonB {
let tx = match MultiEraTx::decode(tx_cbor) {
Ok(x) => x,
Err(_) => return pgrx::Json(serde_json::json!(null)),
Err(_) => return pgrx::JsonB(serde_json::json!(null)),
};

let mints = tx.mints();

pgrx::Json(
serde_json::to_value(
mints
let mint_data: HashMap<String, HashMap<String, String>> = mints
.iter()
.map(|m| {
let policy_id = hex::encode(m.policy().as_ref());
let assets: HashMap<String, String> = m
.assets()
.iter()
.map(|m| {
let policy_id = hex::encode(m.policy().as_ref());
let assets: HashMap<String, i128> = m
.assets()
.iter()
.map(|a| (hex::encode(a.name()), a.any_coin()))
.collect();
.map(|a| (hex::encode(a.name()), a.any_coin().to_string()))
.collect();

(policy_id, assets)
})
.collect::<HashMap<_, _>>(),
)
.unwrap(),
)
(policy_id, assets)
})
.collect();

pgrx::JsonB(serde_json::json!(mint_data))
}

#[pg_extern(immutable)]
Expand Down Expand Up @@ -476,6 +506,24 @@ fn tx_withdrawals(tx_cbor: &[u8]) -> TableIterator<'static, (name!(stake_address
TableIterator::new(withdrawals_data.into_iter())
}

#[pg_extern(immutable)]
fn tx_withdrawals_json(tx_cbor: &[u8]) -> pgrx::JsonB {
let tx = match MultiEraTx::decode(tx_cbor) {
Ok(x) => x,
Err(_) => return pgrx::JsonB(serde_json::json!({})),
};

let withdrawals_data: HashMap<String, String> = match tx.withdrawals() {
MultiEraWithdrawals::AlonzoCompatible(w) => w
.iter()
.map(|(k, v)| (hex::encode(k.to_vec()), v.to_string()))
.collect(),
_ => HashMap::new(),
};

pgrx::JsonB(serde_json::json!(withdrawals_data))
}

#[pg_extern(immutable)]
fn tx_hash_is(tx_cbor: &[u8], hash: &[u8]) -> bool {
let tx = match MultiEraTx::decode(tx_cbor) {
Expand Down

0 comments on commit ea1ee00

Please sign in to comment.