Skip to content

Commit

Permalink
added drep deleg
Browse files Browse the repository at this point in the history
  • Loading branch information
alessandrokonrad committed Jan 31, 2025
1 parent 524f79e commit e13206b
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 21 deletions.
2 changes: 1 addition & 1 deletion docs/docs/getting-started/delegate.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const txHash = await signedTx.submit();
const rewardAddress = await lucid.wallet.rewardAddress();

const tx = await lucid.newTx()
.delegateTo(rewardAddress, "poolabc...")
.delegateTo(rewardAddress, { Pool: "poolabc..." })
.commit();

const signedTx = await tx.sign().commit();
Expand Down
4 changes: 3 additions & 1 deletion src/core/libs/lucid_core/pkg/lucid_core.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,11 @@ export type Certificate = ({ type: "Delegation" } & Delegation) | { type: "Stake

export interface Delegation {
rewardAddress: string;
poolId: string;
variant: DelegVariant;
}

export type DelegVariant = "Abstain" | "NoConfidence" | { DRep: string } | { Pool: string };

export interface PoolRegistration {
poolId: string;
vrfKeyHash: string;
Expand Down
Binary file modified src/core/libs/lucid_core/pkg/lucid_core_bg.wasm
Binary file not shown.
48 changes: 41 additions & 7 deletions src/core/libs/lucid_core/src/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -868,7 +868,16 @@ pub enum Certificate {
#[serde(rename_all = "camelCase")]
pub struct Delegation {
pub reward_address: String,
pub pool_id: String,
pub variant: DelegVariant,
}

#[derive(Tsify, Serialize, Deserialize, Debug, Clone)]
#[tsify(into_wasm_abi, from_wasm_abi)]
pub enum DelegVariant {
Abstain,
NoConfidence,
DRep(String),
Pool(String),
}

impl TryFrom<Certificate> for pallas_primitives::conway::Certificate {
Expand All @@ -878,12 +887,37 @@ impl TryFrom<Certificate> for pallas_primitives::conway::Certificate {
Certificate::Delegation(delegation) => {
let credential =
Addresses::reward_address_to_credential(&delegation.reward_address)?;
let (_, pool_id_raw) =
bech32::decode(&delegation.pool_id).map_err(CoreError::msg)?;
pallas_primitives::conway::Certificate::StakeDelegation(
credential.try_into()?,
pool_id_raw.as_slice().into(),
)
match delegation.variant {
DelegVariant::Pool(id) => {
let (_, id_raw) = bech32::decode(&id).map_err(CoreError::msg)?;
pallas_primitives::conway::Certificate::StakeDelegation(
credential.try_into()?,
id_raw.as_slice().into(),
)
}
variant => pallas_primitives::conway::Certificate::VoteDeleg(
credential.try_into()?,
match variant {
DelegVariant::Abstain => pallas_primitives::conway::DRep::Abstain,
DelegVariant::NoConfidence => {
pallas_primitives::conway::DRep::NoConfidence
}
DelegVariant::DRep(id) => {
let (_, id_raw) = bech32::decode(&id).map_err(CoreError::msg)?;
match id_raw[0] {
0b0010_0010 => {
pallas_primitives::conway::DRep::Key(id_raw[1..].into())
}
0b0010_0011 => {
pallas_primitives::conway::DRep::Script(id_raw[1..].into())
}
_ => return Err(CoreError::msg("Invalid DRep id")),
}
}
_ => unreachable!(),
},
),
}
}
Certificate::StakeRegistration { reward_address } => {
let credential = Addresses::reward_address_to_credential(&reward_address)?;
Expand Down
6 changes: 3 additions & 3 deletions src/core/libs/lucid_core/src/emulator_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use super::codec::{Certificate, Delegation, Script, Utxos};
use super::error::{CoreError, CoreResult};
use super::instruction_builder::BuilderInput;
use crate::addresses::Network;
use crate::codec::Utxo;
use crate::codec::{DelegVariant, Utxo};
use crate::hasher::Hasher;
use bech32::Hrp;
use pallas_crypto::key::ed25519::{PublicKey, Signature};
Expand Down Expand Up @@ -623,7 +623,7 @@ impl EmulatorState {

certificate_requests.push(Certificate::Delegation(Delegation {
reward_address,
pool_id,
variant: DelegVariant::Pool(pool_id),
}));
}
_ => {}
Expand Down Expand Up @@ -757,7 +757,7 @@ impl EmulatorState {
}
Certificate::Delegation(Delegation {
reward_address,
pool_id,
variant: DelegVariant::Pool(pool_id),
}) => {
if let Some(staking) = self.staking.get_mut(&reward_address) {
staking.pool_id = Some(pool_id);
Expand Down
33 changes: 28 additions & 5 deletions src/core/libs/lucid_core/src/instruction_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ impl InstructionBuilder {
self.add_input(utxo, redeemer.clone())?;
}
}

Instruction::ReadFrom { utxos } => {
for utxo in utxos {
if let (Some(_), Some(data)) = (&utxo.datum_hash, &utxo.datum) {
Expand All @@ -238,6 +239,7 @@ impl InstructionBuilder {
});
}
}

Instruction::Mint { assets, redeemer } => {
let policy_id = assets.get_policy_id()?;

Expand Down Expand Up @@ -268,6 +270,7 @@ impl InstructionBuilder {
self.mint = None;
}
}

Instruction::PayTo {
assets,
address,
Expand Down Expand Up @@ -315,6 +318,7 @@ impl InstructionBuilder {

self.outputs.push(utxo);
}

Instruction::PayToContract {
assets,
address,
Expand Down Expand Up @@ -361,6 +365,7 @@ impl InstructionBuilder {

self.outputs.push(utxo);
}

Instruction::DelegateTo {
delegation,
redeemer,
Expand All @@ -384,6 +389,7 @@ impl InstructionBuilder {
redeemer,
})
}

Instruction::RegisterStake { reward_address } => {
validate_network(&reward_address, &self.network)?;

Expand All @@ -397,6 +403,7 @@ impl InstructionBuilder {
redeemer: None,
})
}

Instruction::DeregisterStake {
reward_address,
redeemer,
Expand All @@ -423,6 +430,7 @@ impl InstructionBuilder {
redeemer,
})
}

Instruction::RegisterPool(pool_registration) => {
validate_network(&pool_registration.reward_address, &self.network)?;

Expand Down Expand Up @@ -453,6 +461,7 @@ impl InstructionBuilder {
redeemer: None,
})
}

Instruction::UpdatePool(pool_registration) => {
validate_network(&pool_registration.reward_address, &self.network)?;

Expand Down Expand Up @@ -480,6 +489,7 @@ impl InstructionBuilder {
redeemer: None,
})
}

Instruction::RetirePool(pool_retirement) => {
let (_, pool_id_raw) =
bech32::decode(&pool_retirement.pool_id).map_err(CoreError::msg)?;
Expand All @@ -492,6 +502,7 @@ impl InstructionBuilder {
redeemer: None,
})
}

Instruction::Withdraw {
withdrawal,
redeemer,
Expand All @@ -518,41 +529,48 @@ impl InstructionBuilder {
},
);
}

Instruction::AddSigner { key_hash } => {
self.used_keys
.insert(key_hash.parse().map_err(CoreError::msg)?);
self.signers
.get_or_insert_with(BTreeSet::new)
.insert(AddrKeyhash::from_str(&key_hash).map_err(CoreError::msg)?);
}

Instruction::AddNetworkId { id } => {
self.tx.transaction_body.network_id = Some(
id.try_into()
.map_err(|_| CoreError::msg("Casting network id failed"))?,
)
}

Instruction::ValidFrom { unix_time } => {
let slots = unix_time_to_slots(unix_time, &self.slot_config);
self.tx.transaction_body.validity_interval_start = Some(slots);
}

Instruction::ValidTo { unix_time } => {
let slots = unix_time_to_slots(unix_time, &self.slot_config);
self.tx.transaction_body.ttl = Some(slots);
}

Instruction::AttachMetadata {
metadata: (label, value),
} => {
self.aux_metadata
.get_or_insert_with(BTreeMap::new)
.insert(label, Either::Left(value));
}

Instruction::AttachMetadataWithConversion {
metadata: (label, value),
} => {
self.aux_metadata
.get_or_insert_with(BTreeMap::new)
.insert(label, Either::Right(value));
}

Instruction::AttachScript { script } => {
let script = script.try_double_cbor()?;

Expand All @@ -564,9 +582,11 @@ impl InstructionBuilder {
.get_or_insert_with(HashMap::new)
.insert(hash, script);
}

Instruction::WithChangeTo(change) => {
self.change = change;
}

Instruction::WithoutCoinSelection => {
self.without_coin_selection = true;
}
Expand Down Expand Up @@ -1927,7 +1947,8 @@ mod tests {
use crate::{
addresses::{Addresses, Network},
codec::{
Assets, AuxMetadata, ConstrConversion, Delegation, Script, Utxo, Utxos, Withdrawal,
Assets, AuxMetadata, ConstrConversion, DelegVariant, Delegation, Script, Utxo, Utxos,
Withdrawal,
},
hasher::Hasher,
instruction_builder::DatumVariant,
Expand Down Expand Up @@ -2132,8 +2153,9 @@ mod tests {
reward_address:
"stake1uxk96skvmq8sx5gezj4jwh0pakswf8thnrw5musz2rja48c0sfdmh"
.to_string(),
pool_id: "pool19f6guwy97mmnxg9dz65rxyj8hq07qxud886hamyu4fgfz7dj9gl"
.to_string(),
variant: DelegVariant::Pool(
"pool19f6guwy97mmnxg9dz65rxyj8hq07qxud886hamyu4fgfz7dj9gl".to_string(),
),
},
redeemer: None,
},
Expand Down Expand Up @@ -2327,8 +2349,9 @@ mod tests {
Instruction::DelegateTo {
delegation: Delegation {
reward_address: reward_address.clone(),
pool_id: "pool19f6guwy97mmnxg9dz65rxyj8hq07qxud886hamyu4fgfz7dj9gl"
.to_string(),
variant: DelegVariant::Pool(
"pool19f6guwy97mmnxg9dz65rxyj8hq07qxud886hamyu4fgfz7dj9gl".to_string(),
),
},
redeemer: Some(redeemer.clone()),
},
Expand Down
7 changes: 4 additions & 3 deletions src/lucid/tx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
type Change,
Data,
type DatumVariant,
type DelegVariant,
Hasher,
type Instruction,
InstructionBuilder,
Expand Down Expand Up @@ -126,17 +127,17 @@ export class Tx {
return this;
}

/** Delegate to a stake pool. */
/** Delegate to a stake pool or drep. */
delegateTo(
rewardAddress: string | "{{own}}",
poolId: string,
variant: DelegVariant,
redeemer?: string,
): Tx {
this.tasks.push(() => ({
type: "DelegateTo",
delegation: {
rewardAddress,
poolId,
variant,
},
redeemer,
}));
Expand Down
4 changes: 3 additions & 1 deletion tests/emulator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,9 @@ Deno.test("Reward withdrawal", async () => {
});
// Delegation
await lucid.awaitTx(
await (await (await lucid.newTx().delegateTo(rewardAddress!, poolId)
await (await (await lucid.newTx().delegateTo(rewardAddress!, {
Pool: poolId,
})
.commit())
.sign().commit()).submit(),
);
Expand Down

0 comments on commit e13206b

Please sign in to comment.