Skip to content

Commit

Permalink
Merge pull request #7 from Datalayer-Storage/updates
Browse files Browse the repository at this point in the history
Add spend xch and fix spend server coins
  • Loading branch information
MichaelTaylor3D authored Sep 4, 2024
2 parents 8432848 + d620613 commit b50a7ad
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 50 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ A collection of functions that can be used to interact with datastores on the Ch
cd
This library offers the following functions:

- wallet: `selectCoins`, `addFee`, `signCoinSpends`
- wallet: `selectCoins`, `addFee`, `signCoinSpends`, `sendXch`
- drivers: `mintStore`, `adminDelegatedPuzzleFromKey`, `writerDelegatedPuzzleFromKey`, `oracleDelegatedPuzzle`, `oracleSpend`, `updateStoreMetadata`, `updateStoreOwnership`, `meltStore`, `getCost`, `createServerCoin`, `lookupAndSpendServerCoins`
- utils: `getCoinId`, `masterPublicKeyToWalletSyntheticKey`, `masterPublicKeyToFirstPuzzleHash`, `masterSecretKeyToWalletSyntheticSecretKey`, `secretKeyToPublicKey`, `puzzleHashToAddress`, `addressToPuzzleHash`, `newLineageProof`, `newEveProof`, `signMessage`, `verifySignedMessage`, `syntheticKeyToPuzzleHash`, `morphLauncherId`

Expand Down
29 changes: 19 additions & 10 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,16 @@ export interface UnspentCoinsResponse {
* @returns {Vec<Coin>} Array of selected coins.
*/
export declare function selectCoins(allCoins: Array<Coin>, totalAmount: bigint): Array<Coin>
/**
* Sends XCH to a given puzzle hash.
*
* @param {Buffer} syntheticKey - The synthetic key used by the wallet.
* @param {Vec<Coin>} selectedCoins - Coins to be spent, as retured by `select_coins`.
* @param {Buffer} puzzleHash - The puzzle hash to send to.
* @param {BigInt} amount - The amount to use for the created coin.
* @param {BigInt} fee - The fee to use for the transaction.
*/
export declare function sendXch(syntheticKey: Buffer, selectedCoins: Array<Coin>, puzzleHash: Buffer, amount: bigint, fee: bigint): Array<CoinSpend>
/**
* Adds an offset to a launcher id to make it deterministically unique from the original.
*
Expand All @@ -209,16 +219,6 @@ export interface NewServerCoin {
* @param {BigInt} fee - The fee to use for the transaction.
*/
export declare function createServerCoin(syntheticKey: Buffer, selectedCoins: Array<Coin>, hint: Buffer, uris: Array<string>, amount: bigint, fee: bigint): NewServerCoin
/**
* Spends the mirror coins to make them unusable in the future.
*
* @param {Peer} peer - The peer connection to the Chia node.
* @param {Buffer} syntheticKey - The synthetic key used by the wallet.
* @param {Vec<Coin>} selectedCoins - Coins to be used for minting, as retured by `select_coins`. Note that the server coins will count towards the fee.
* @param {BigInt} fee - The fee to use for the transaction.
* @param {bool} forTestnet - True for testnet, false for mainnet.
*/
export declare function lookupAndSpendServerCoins(peer: Peer, syntheticKey: Buffer, selectedCoins: Array<Coin>, fee: bigint, forTestnet: boolean): Promise<Array<CoinSpend>>
/**
* Mints a new datastore.
*
Expand Down Expand Up @@ -492,4 +492,13 @@ export declare class Peer {
* @returns {Option<u32>} A tuple consiting of the latest synced block's height, as reported by the peer. Null if the peer has not yet reported a peak.
*/
getPeak(): Promise<number | null>
/**
* Spends the mirror coins to make them unusable in the future.
*
* @param {Buffer} syntheticKey - The synthetic key used by the wallet.
* @param {Vec<Coin>} selectedCoins - Coins to be used for minting, as retured by `select_coins`. Note that the server coins will count towards the fee.
* @param {BigInt} fee - The fee to use for the transaction.
* @param {bool} forTestnet - True for testnet, false for mainnet.
*/
lookupAndSpendServerCoins(syntheticKey: Buffer, selectedCoins: Array<Coin>, fee: bigint, forTestnet: boolean): Promise<Array<CoinSpend>>
}
4 changes: 2 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -310,15 +310,15 @@ if (!nativeBinding) {
throw new Error(`Failed to load native binding`)
}

const { newLineageProof, newEveProof, Peer, selectCoins, morphLauncherId, createServerCoin, lookupAndSpendServerCoins, mintStore, oracleSpend, addFee, masterPublicKeyToWalletSyntheticKey, masterPublicKeyToFirstPuzzleHash, masterSecretKeyToWalletSyntheticSecretKey, secretKeyToPublicKey, puzzleHashToAddress, addressToPuzzleHash, adminDelegatedPuzzleFromKey, writerDelegatedPuzzleFromKey, oracleDelegatedPuzzle, signCoinSpends, getCoinId, updateStoreMetadata, updateStoreOwnership, meltStore, signMessage, verifySignedMessage, syntheticKeyToPuzzleHash, getCost } = nativeBinding
const { newLineageProof, newEveProof, Peer, selectCoins, sendXch, morphLauncherId, createServerCoin, mintStore, oracleSpend, addFee, masterPublicKeyToWalletSyntheticKey, masterPublicKeyToFirstPuzzleHash, masterSecretKeyToWalletSyntheticSecretKey, secretKeyToPublicKey, puzzleHashToAddress, addressToPuzzleHash, adminDelegatedPuzzleFromKey, writerDelegatedPuzzleFromKey, oracleDelegatedPuzzle, signCoinSpends, getCoinId, updateStoreMetadata, updateStoreOwnership, meltStore, signMessage, verifySignedMessage, syntheticKeyToPuzzleHash, getCost } = nativeBinding

module.exports.newLineageProof = newLineageProof
module.exports.newEveProof = newEveProof
module.exports.Peer = Peer
module.exports.selectCoins = selectCoins
module.exports.sendXch = sendXch
module.exports.morphLauncherId = morphLauncherId
module.exports.createServerCoin = createServerCoin
module.exports.lookupAndSpendServerCoins = lookupAndSpendServerCoins
module.exports.mintStore = mintStore
module.exports.oracleSpend = oracleSpend
module.exports.addFee = addFee
Expand Down
106 changes: 69 additions & 37 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,42 @@ impl Peer {
let peak: Option<NewPeakWallet> = peak_guard.clone();
Ok(peak.map(|p| p.height))
}

/// Spends the mirror coins to make them unusable in the future.
///
/// @param {Buffer} syntheticKey - The synthetic key used by the wallet.
/// @param {Vec<Coin>} selectedCoins - Coins to be used for minting, as retured by `select_coins`. Note that the server coins will count towards the fee.
/// @param {BigInt} fee - The fee to use for the transaction.
/// @param {bool} forTestnet - True for testnet, false for mainnet.
#[napi]
pub async fn lookup_and_spend_server_coins(
&self,
synthetic_key: Buffer,
selected_coins: Vec<Coin>,
fee: BigInt,
for_testnet: bool,
) -> napi::Result<Vec<CoinSpend>> {
let coin = wallet::spend_server_coins(
&self.inner,
RustPublicKey::from_js(synthetic_key)?,
selected_coins
.into_iter()
.map(RustCoin::from_js)
.collect::<Result<Vec<RustCoin>>>()?,
u64::from_js(fee)?,
if for_testnet {
TargetNetwork::Testnet11
} else {
TargetNetwork::Mainnet
},
)
.await
.map_err(js::err)?;

coin.into_iter()
.map(|c| c.to_js())
.collect::<Result<Vec<CoinSpend>>>()
}
}

/// Selects coins using the knapsack algorithm.
Expand All @@ -690,6 +726,39 @@ pub fn select_coins(all_coins: Vec<Coin>, total_amount: BigInt) -> napi::Result<
.collect::<Result<Vec<Coin>>>()
}

/// Sends XCH to a given puzzle hash.
///
/// @param {Buffer} syntheticKey - The synthetic key used by the wallet.
/// @param {Vec<Coin>} selectedCoins - Coins to be spent, as retured by `select_coins`.
/// @param {Buffer} puzzleHash - The puzzle hash to send to.
/// @param {BigInt} amount - The amount to use for the created coin.
/// @param {BigInt} fee - The fee to use for the transaction.
#[napi]
pub fn send_xch(
synthetic_key: Buffer,
selected_coins: Vec<Coin>,
puzzle_hash: Buffer,
amount: BigInt,
fee: BigInt,
) -> napi::Result<Vec<CoinSpend>> {
let coin_spends = wallet::send_xch(
RustPublicKey::from_js(synthetic_key)?,
&selected_coins
.into_iter()
.map(RustCoin::from_js)
.collect::<Result<Vec<RustCoin>>>()?,
RustBytes32::from_js(puzzle_hash)?,
u64::from_js(amount)?,
u64::from_js(fee)?,
)
.map_err(js::err)?;

coin_spends
.into_iter()
.map(|c| c.to_js())
.collect::<Result<Vec<CoinSpend>>>()
}

/// Adds an offset to a launcher id to make it deterministically unique from the original.
///
/// @param {Buffer} launcherId - The original launcher id.
Expand Down Expand Up @@ -749,43 +818,6 @@ pub fn create_server_coin(
})
}

/// Spends the mirror coins to make them unusable in the future.
///
/// @param {Peer} peer - The peer connection to the Chia node.
/// @param {Buffer} syntheticKey - The synthetic key used by the wallet.
/// @param {Vec<Coin>} selectedCoins - Coins to be used for minting, as retured by `select_coins`. Note that the server coins will count towards the fee.
/// @param {BigInt} fee - The fee to use for the transaction.
/// @param {bool} forTestnet - True for testnet, false for mainnet.
#[napi]
pub async fn lookup_and_spend_server_coins(
peer: &Peer,
synthetic_key: Buffer,
selected_coins: Vec<Coin>,
fee: BigInt,
for_testnet: bool,
) -> napi::Result<Vec<CoinSpend>> {
let coin = wallet::spend_server_coins(
&peer.inner,
RustPublicKey::from_js(synthetic_key)?,
selected_coins
.into_iter()
.map(RustCoin::from_js)
.collect::<Result<Vec<RustCoin>>>()?,
u64::from_js(fee)?,
if for_testnet {
TargetNetwork::Testnet11
} else {
TargetNetwork::Mainnet
},
)
.await
.map_err(js::err)?;

coin.into_iter()
.map(|c| c.to_js())
.collect::<Result<Vec<CoinSpend>>>()
}

#[allow(clippy::too_many_arguments)]
#[napi]
/// Mints a new datastore.
Expand Down
23 changes: 23 additions & 0 deletions src/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,29 @@ fn spend_coins_together(
Ok(())
}

pub fn send_xch(
synthetic_key: PublicKey,
coins: &[Coin],
puzzle_hash: Bytes32,
amount: u64,
fee: u64,
) -> Result<Vec<CoinSpend>, WalletError> {
let mut ctx = SpendContext::new();

spend_coins_together(
&mut ctx,
synthetic_key,
coins,
Conditions::new()
.create_coin(puzzle_hash, amount, Vec::new())
.reserve_fee(fee),
(amount + fee).try_into().unwrap(),
StandardArgs::curry_tree_hash(synthetic_key).into(),
)?;

Ok(ctx.take())
}

pub fn create_server_coin(
synthetic_key: PublicKey,
selected_coins: Vec<Coin>,
Expand Down

0 comments on commit b50a7ad

Please sign in to comment.