Giter VIP home page Giter VIP logo

cdk's People

Contributors

biluohc avatar danieluhlik avatar davidcaseria avatar kodylow avatar lorenzolfm avatar ngutech21 avatar thesimplekid avatar yukibtc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

cdk's Issues

HttpClient: Calls a malformed urls

Mints with url path cannot be called because HttpClient removes the last part.
For mint url https://legend.lnbits.com/cashu/api/v1/4gr9Xcmz3XEkUNwiBiQGoC HttpClient get keys from https://legend.lnbits.com/cashu/api/v1/keys url

async fn main() {
   let token = Token::from_str("cashuAeyJ0b2tlbiI6W3sicHJvb2ZzIjpbeyJpZCI6IjBOSTNUVUFzMVNmeSIsImFtb3VudCI6MSwic2VjcmV0IjoiVE92cGVmZGxSZ0EzdlhMN05pM2MvRE1oY29URXNQdnV4eFc0Rys2dXVycz0iLCJDIjoiMDNiZThmMzQwOTMxYTI4ZTlkMGRmNGFmMWQwMWY1ZTcxNTFkMmQ1M2RiN2Y0ZDAyMWQzZGUwZmRiMDNjZGY4ZTlkIn1dLCJtaW50IjoiaHR0cHM6Ly9sZWdlbmQubG5iaXRzLmNvbS9jYXNodS9hcGkvdjEvNGdyOVhjbXozWEVrVU53aUJpUUdvQyJ9XX0");
   let mint_url = token.unwrap().token[0].mint.clone(); // https://legend.lnbits.com/cashu/api/v1/4gr9Xcmz3XEkUNwiBiQGoC
   let client = HttpClient{};
   let keys = client.get_mint_keys(&Url::from_str(mint_url.to_string().as_str()).unwrap()).await.unwrap(); // Request to https://legend.lnbits.com/cashu/api/v1/keys
}

Refactor wallet

The wallet-module in the cashu-sdk crate has several issues:

  • All methods are implemented twice: once for the blocking client and once for the non-blocking client. This could make future code upgrades challenging.
  • The wallet-struct is not testable with pure unittests, because it relies on a specific http-client. Mocking the client is hard, therefore this struct could only be tested with integrationstests.

Solution:

Introduce a trait for the client

#[async_trait(?Send)]
pub trait Client {
async fn get_keys(&self) -> Result<Keys, Error> 
...
}

Use a generic argument in the wallet with Client as the trait-bound

#[derive(Clone, Debug)]
pub struct Wallet<C: Client> {
    pub client: C,
    pub mint_keys: Keys,
    pub balance: Amount,
}

This way we can have multiple implementations for clients (e.g. use reqwest for the regular desktop wallets and gloo-net for wasm clients) and get rid of the duplicated code for the logic in the wallet module
For unittests there can can also be an mock implementation using automock or a manual created one.

The refactoring would also fix this issue: #41

This is how I structured the wallet in my cashu-implementation https://github.com/ngutech21/moksha/blob/master/moksha-wallet/src/wallet.rs

Public key serilzation

Public key serialization/deserialization seems to be broken.

  • Tests for pubkey
  • Test for seckey

Running just final-check fails

Running just final-check fails with a clippy error:

cargo clippy --locked --offline --workspace --all-targets -- --deny warnings --allow deprecated
warning: /Users/steffen/projects/cashu-crab/bindings/cashu-sdk-ffi/Cargo.toml: unused manifest key: dependencies.futures.feature
    Checking cashu-sdk-ffi v0.1.0 (/Users/steffen/projects/cashu-crab/bindings/cashu-sdk-ffi)
error: variable `Invoice` should have a snake case name
    --> /Users/steffen/projects/cashu-crab/target/debug/build/cashu-sdk-ffi-c6b10692a22ed522/out/cashu_sdk.uniffi.rs:2729:9
     |
2729 |         r#Invoice: ::uniffi::RustBuffer,
     |         ^^^^^^^^^ help: convert the identifier to snake case: `invoice`
     |
     = note: `-D non-snake-case` implied by `-D warnings`

error: variable `Invoice` should have a snake case name
    --> /Users/steffen/projects/cashu-crab/target/debug/build/cashu-sdk-ffi-c6b10692a22ed522/out/cashu_sdk.uniffi.rs:3383:9
     |
3383 |         r#Invoice: ::uniffi::RustBuffer,
     |         ^^^^^^^^^ help: convert the identifier to snake case: `invoice`

error: could not compile `cashu-sdk-ffi` (lib) due to 2 previous errors
warning: build failed, waiting for other jobs to finish...
error: could not compile `cashu-sdk-ffi` (lib test) due to 2 previous errors
error: Recipe `clippy` failed on line 84 with exit code 101

There are multiple issues:

  • The CI does not catch this, because it does not run the just actions but uses a matrix build
  • Clippy checks code that is generated by ffi -> I didn't find a solution to exclude the code from the target folder in clippy. Any ideas?

As a quick fix the --deny warnings can be omitted so the final-check action doesn't fails but just prints out a warning.

Mint sanity checks

Check, add and document mint sanity checks.

  • No duplicate proofs
  • input >= output

running just build results in compile error in cashu-sdk-js

steps to reproduce:

git clone https://github.com/thesimplekid/cashu-crab.git
just build
-> compile error:

error[E0277]: `std::result::Result<Melted, cashu_sdk::wallet::Error>` is not a future
   --> bindings/cashu-sdk-js/src/wallet.rs:154:14
    |
154 |             .await
    |             -^^^^^
    |             ||
    |             |`std::result::Result<Melted, cashu_sdk::wallet::Error>` is not a future
    |             help: remove the `.await`
    |
    = help: the trait `Future` is not implemented for `std::result::Result<Melted, cashu_sdk::wallet::Error>`
    = note: std::result::Result<Melted, cashu_sdk::wallet::Error> must be a future or must implement `IntoFuture` to be awaited
    = note: required for `std::result::Result<Melted, cashu_sdk::wallet::Error>` to implement `IntoFuture`

warning: call to `.deref()` on a reference in this situation does nothing
error[E0308]: mismatched types
  --> bindings/cashu-sdk-js/src/wallet.rs:39:32
   |
39 |             inner: Wallet::new(client.deref().clone(), mint_keys.deref().clone()),
   |                    ----------- ^^^^^^^^^^^^^^^^^^^^^^ expected `Client`, found a different `Client`
   |                    |
   |                    arguments to this function are incorrect
   |
note: associated function defined here

expected result

cloning the repo and running just build without any feature flags compiles the workspace

JsClient.deref() returns a non-blocking client, which seems to be correct. But Wallet::new() expects a blocking client. I don't understand why this happens since blocking is an optional feature, that is not enabled by default.

Secret Type

Create a secret type instead of just a string

Simplify mint after NUT-06 update (`amount` deprecation)

Hey, I was glancing over the code and saw that after the NUT-06 update here, you might have left some idiosyncrasies from earlier times in the code:

https://github.com/thesimplekid/cashu-crab/blob/b287c87df0e6d87468d7dfa6d0a48e014967834f/src/mint.rs#L133

Since the mint does not know anything about "first" and "second" promises (blind signatures) anymore, you can treat these as one big slice and don't have to separate them anymore. Instead, the wallet now has to figure out which of the promises it received it wants to keep and which to send on. I am guessing, this is what your code does here:

https://github.com/thesimplekid/cashu-crab/blob/b287c87df0e6d87468d7dfa6d0a48e014967834f/src/wallet.rs#L110C21-L110C29

Keep up the insane work! Cheers!

Replace k256 library with rust-secp256k1

Hi! I was having a look around the code and notice the library is using k256 instead of the rust-secp256k1 library. k256 is not cryptographic audited compared to rust-secp256k1 which is probably the most audited crypto library out there.

I was looking to work on a cashu library and found this package. do you think this would be a good change?
I would probably be interested in doing the change.

Decode token: Base64Error(InvalidPadding)

Decoding tokens where mint url have path cause error Base64Error(InvalidPadding)

Code to reproduce:

use cashu_sdk::nuts::nut00::wallet::Token;

fn main() {
    let token = Token::from_str("cashuAeyJ0b2tlbiI6W3sicHJvb2ZzIjpbeyJpZCI6IjBOSTNUVUFzMVNmeSIsImFtb3VudCI6MSwic2VjcmV0IjoiVE92cGVmZGxSZ0EzdlhMN05pM2MvRE1oY29URXNQdnV4eFc0Rys2dXVycz0iLCJDIjoiMDNiZThmMzQwOTMxYTI4ZTlkMGRmNGFmMWQwMWY1ZTcxNTFkMmQ1M2RiN2Y0ZDAyMWQzZGUwZmRiMDNjZGY4ZTlkIn1dLCJtaW50IjoiaHR0cHM6Ly9sZWdlbmQubG5iaXRzLmNvbS9jYXNodS9hcGkvdjEvNGdyOVhjbXozWEVrVU53aUJpUUdvQyJ9XX0");
    println!("Mint url: {}", token.unwrap().token[0].mint);
}

Bug: Same token

When I execute the code twice or more, it is possible to generate the same token, it should generate a completely different token.

Sometimes , even though the balance is sufficient, the call will return an error: Token already spent.

My Code

        let  r6 = api::send(1, "https://8333.space:3338/".to_string());
        let  r7 = api::send(1, "https://8333.space:3338/".to_string());
        let  r8 = api::send(1, "https://8333.space:3338/".to_string());

result

r6 :Ok(CashuTransaction(CashuTransaction { id: Some("991b5fcbe03fb8ddf50fcb94308e7579ecc82b589f2b6425cd0b0f510751ce98"), status: Pending(Send), time: 1692633929, amount: 1, mint: "https://8333.space:3338/", token: "cashuAeyJ0b2tlbiI6W3sibWludCI6Imh0dHBzOi8vODMzMy5zcGFjZTozMzM4IiwicHJvb2ZzIjpbXX1dLCJtZW1vIjpudWxsfQ==", from: None }))
r7 :Ok(CashuTransaction(CashuTransaction { id: Some("991b5fcbe03fb8ddf50fcb94308e7579ecc82b589f2b6425cd0b0f510751ce98"), status: Pending(Send), time: 1692633931, amount: 1, mint: "https://8333.space:3338/", token: "cashuAeyJ0b2tlbiI6W3sibWludCI6Imh0dHBzOi8vODMzMy5zcGFjZTozMzM4IiwicHJvb2ZzIjpbXX1dLCJtZW1vIjpudWxsfQ==", from: None }))

The KeysetId of v1 api parse failed, it's not hex string

curl -X GET https://8333.space:3338/v1/keys

{"keysets":[{"id":"I2yN+iRYfkzT","unit":"sat","keys":{"1":"03ba786a2c0745f8c30e490288acd7a72dd53d65afd292ddefa326a4a3fa14c566","2":"03361cd8bd1329fea797a6add1cf1990ffcf2270ceb9fc81eeee0e8e9c1bd0cdf5","4":"036e37..

It's version is Nutshell/0.15.2

curl -X GET https://8333.space:3338/v1/info

{"name":"Cashu test mint","pubkey":"03e3d23e1b66eadaf15ce0d640a908e8ba1984baed34ab98c547aab4cf4249440d","version":"Nutshell/0.15.2","description":"This mint is for testing and development purposes only. Do not use this mint as a default mint in your application! Please use it with caution and only with very small amounts. Your Cashu client could have bugs. Accidents and bugs can lead to loss of funds for which we are not responsible for.","contact":[["",""]],"nuts":{"4":{"methods":[{"method":"bolt11","unit":"sat","min_amount":0,"max_amount":500000}],"disabled":false},"5":{"methods":[{"method":"bolt11","unit":"sat","min_amount":0,"max_amount":500000}],"disabled":false},"7":{"supported":true},"8":{"supported":true},"9":{"supported":true},"10":{"supported":true},"11":{"supported":true},"12":{"supported":true}}}

Url serialization

The trailing slash should be handled better. It breaks round tripping token serializations

Likely need to create a crate url structs. Rust nostr does something similar

Melt: index out of bounds

Trying to spend token and getting this error, it would be helpful to provide some Error message. Spending from nutstash works fine.

thread 'actix-rt|system:0|arbiter:1' panicked at cashu-crab/crates/cashu-sdk/src/mint.rs:309:42:
index out of bounds: the len is 1 but the index is 1
cashuAeyJ0b2tlbiI6W3sicHJvb2ZzIjpbeyJpZCI6InBvWFdrOG9OOU9MbCIsImFtb3VudCI6MSwic2VjcmV0IjoiVEtxcDVUdHdYTUtsb2I3MmxoRXI2Sjd6b2ZLWVhHakpDcHgzT0txbmJqUT0iLCJDIjoiMDJhYTViNjkwZTkzODY0ODE1ZGMwZDU2NzhiNWEzZDFjMDhhNTQ3MzczZDZiYmUyM2E4MzYyZjVhZGE5YTM1Yzg4In1dLCJtaW50IjoiaHR0cHM6Ly9jYXNodS50Y2hhaWNhcC5zcGFjZS9jYXNodSJ9XX0

Id type

Create an id type instead of just a string

All feature combinations need to be tested

All combinations of features need to be tested.

Currently all optional nuts are as features in some cases it may make sense to remove the feature and include it as default. For example NUT08, its unlikely anyone disables this feature and having it behind a feature flag maybe more overhead then it is worth. NUT07 is also unlikely to go unused.

Only NUT13 adds extra external dependencies so that maybe the only one worth feature gating.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.