Skip to content

Commit

Permalink
should theoretically work
Browse files Browse the repository at this point in the history
  • Loading branch information
Yakuhito committed Oct 2, 2024
1 parent aebd333 commit caa6faf
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 6 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ This library offers the following functions:

- 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`, `getMainnetGenesisChallenge`, `getTestnet11GenesisChallenge`, `lookUpPossibleLaunchers`
- utils: `getCoinId`, `masterPublicKeyToWalletSyntheticKey`, `masterPublicKeyToFirstPuzzleHash`, `masterSecretKeyToWalletSyntheticSecretKey`, `secretKeyToPublicKey`, `puzzleHashToAddress`, `addressToPuzzleHash`, `newLineageProof`, `newEveProof`, `signMessage`, `verifySignedMessage`, `syntheticKeyToPuzzleHash`, `morphLauncherId`, `getMainnetGenesisChallenge`, `getTestnet11GenesisChallenge`.

The `Peer` class also exposes the following methods: `getAllUnspentCoins`, `syncStore`, `syncStoreFromLauncherId`, `broadcastSpend`, `isCoinSpent`, `getHeaderHash`, `getFeeEstimate`, `getPeak`, `getHintedCoinStates`, `fetchServerCoin`, `getStoreCreationHeight`.
The `Peer` class also exposes the following methods: `getAllUnspentCoins`, `syncStore`, `syncStoreFromLauncherId`, `broadcastSpend`, `isCoinSpent`, `getHeaderHash`, `getFeeEstimate`, `getPeak`, `getHintedCoinStates`, `fetchServerCoin`, `getStoreCreationHeight`, `lookUpPossibleLaunchers`, `waitForCoinToBeSpent`.

Note that all functions come with detailed JSDoc comments.

Expand Down
9 changes: 9 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -555,4 +555,13 @@ export declare class Peer {
* @returns {Promise<PossibleLaunchersResponse>} Possible launcher ids for datastores, as well as a height + header hash combo to use for the next call.
*/
lookUpPossibleLaunchers(lastHeight: number | undefined | null, headerHash: Buffer): Promise<PossibleLaunchersResponse>
/**
* Waits for a coin to be spent on-chain.
*
* @param {Buffer} coin_id - Id of coin to track.
* @param {Option<u32>} lastHeight - Min. height to search records from. If null, sync will be done from the genesis block.
* @param {Buffer} headerHash - Header hash corresponding to `lastHeight`. If null, this should be the genesis challenge of the current chain.
* @returns {Promise<Buffer>} Promise that resolves when the coin is spent (returning the coin id).
*/
waitForCoinToBeSpent(coinId: Buffer, lastHeight: number | undefined | null, headerHash: Buffer): Promise<Buffer>
}
41 changes: 37 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use chia::bls::{

use chia::protocol::{
Bytes as RustBytes, Bytes32 as RustBytes32, Coin as RustCoin, CoinSpend as RustCoinSpend,
NewPeakWallet, ProtocolMessageTypes, SpendBundle as RustSpendBundle,
CoinStateUpdate, NewPeakWallet, ProtocolMessageTypes, SpendBundle as RustSpendBundle,
};
use chia::puzzles::{standard::StandardArgs, DeriveSynthetic, Proof as RustProof};
use chia::traits::Streamable;
Expand All @@ -28,7 +28,7 @@ use napi::Result;
use native_tls::TlsConnector;
use std::collections::HashMap;
use std::{net::SocketAddr, sync::Arc};
use tokio::sync::mpsc::UnboundedSender;
use tokio::sync::mpsc::{unbounded_channel, UnboundedSender};
use tokio::sync::Mutex;
use wallet::{
PossibleLaunchersResponse as RustPossibleLaunchersResponse,
Expand Down Expand Up @@ -482,7 +482,9 @@ impl Peer {

let inner = Arc::new(peer);
let peak = Arc::new(Mutex::new(None));
let coin_listeners = Arc::new(Mutex::new(HashMap::new()));
let coin_listeners = Arc::new(Mutex::new(
HashMap::<RustBytes32, UnboundedSender<()>>::new(),
));

let peak_clone = peak.clone();
let coin_listeners_clone = coin_listeners.clone();
Expand All @@ -494,6 +496,25 @@ impl Peer {
*peak_guard = Some(new_peak);
}
}

if message.msg_type == ProtocolMessageTypes::CoinStateUpdate {
if let Ok(coin_state_update) = CoinStateUpdate::from_bytes(&message.data) {
let mut listeners = coin_listeners_clone.lock().await;

for coin_state_update_item in coin_state_update.items {
if coin_state_update_item.spent_height.is_none() {
continue;
}

if let Some(listener) =
listeners.get(&coin_state_update_item.coin.coin_id())
{
let _ = listener.send(());
listeners.remove(&coin_state_update_item.coin.coin_id());
}
}
}
}
}
});

Expand Down Expand Up @@ -836,7 +857,19 @@ impl Peer {
.await
.map_err(js::err)?;

if spent_height.is_none() {}
if spent_height.is_none() {
let (sender, mut receiver) = unbounded_channel::<()>();

{
let mut listeners = self.coin_listeners.lock().await;
listeners.insert(rust_coin_id, sender);
}

receiver
.recv()
.await
.ok_or_else(|| js::err("Failed to receive spent notification"))?;
}

wallet::unsubscribe_from_coin_states(&self.inner.clone(), rust_coin_id)
.await
Expand Down

0 comments on commit caa6faf

Please sign in to comment.