irufus / gdax-java

Java based wrapper for Coinbase Pro (Formerly known as GDAX API and Coinbase Exchange API)
MIT License
177 stars 131 forks source link

what is "api keys" ? #33

Closed rjpg closed 4 years ago

rjpg commented 6 years ago

I just have username and password on gdax ... where should I enter that in application.yml ?

or there is another "key" that I am not aware ?

by the way is there any simple example, in one .java file just to do login and get the orderbook ? (using the jar file )

rjpg commented 6 years ago

Okay I saw that we have to do login on gdax site and go to the menu to create a "key" and all that (that I do not understand why exist since we have a login and password ...)

The login/password will be used anywhere ?

I am used to use jar files (not mavens or similars geek shits to complicate )... with the jar file where do I put/use the "keys" ?? Do I have to unpack the JAR to edit the application.yml file and compress it again into the JAR ?

Any simple example file (with main() function ...) to see this working ? (I have not been able to put this working with a JAR file and Iam a java programer for more that 20 years )

irufus commented 6 years ago

You could build the JAR with your credentials or overload the properties by using another property file. I am looking into ways to make this simpler and add instructions on how to do so in the Readme. For now you could follow this example: https://gist.github.com/irufus/6260646a31757c3f5309fb4e79c067ff

rjpg commented 6 years ago

having to learn spring is almost a showstopper for this lib (at the moment for me it is. Just looking for this "simple" example I see I have a lot to learn about this spring ...).

why not have all in simple pure Java ? something simple like :

                       loginEnv = new LoginEnvironment();

            loginEnv.setUsername(username);
            loginEnv.setPassword(password);

            if(loginEnv.login()==-1) // or use exceptions....  
            {
                System.err.println("*** Failed to log in");
                System.exit(1);
            }

this example, on your link, is working with the .jar file ? (I need to include this lib into another project ... what is the simple way ? )

I need to select a market get level II prices/amounts (depth 10 at least buy/sell), in single calls (that I manage in my threads ...), and level III (orders list with timestamp - so I can build my own corrected/sequential info "stream" ). And also need to put (limit) orders in the selected market. Just this ... it is possible with this lib ?

rjpg commented 6 years ago

"You could build the JAR with your credentials..." - I could not say this sentence

robevansuk commented 6 years ago

Spring is actually quite simple once you realise what its attempting to do... It removes complexity from developing applications because it handles all the configuring of objects for you by separating concerns and providing better support for implementing cross cutting concerns in your code than you'd get by attempting to do it all manually.

For instance, if your class requires an instance of Foo and you have declared a Foo class and marked it with @Component, it will be automatically registered with Spring and when its required it can be plugged into your class using @Autowired annotation.

e.g. Normally you'd do something like this:

public class Bar {
  private Foo foo;
  public Bar(Foo foo) {
    this.foo=foo;
  }
}
public class Foo {
  private String[] args;
  public Foo(String... args){
    this.args = args;
  }
}

Then to create a Bar you'd create a Foo and manually wire it into the Bar within your application. Doing this any more than 2-3 times or passing around the foo internally to various other objects within the Bar creates a spaghetti mess of wiring in your code and tightly couples all your implementation. This makes maintaining the code HARD.

public class MainApplication {
  private Bar bar;
  public MainApplication(String... someArgs){
    Foo foo = new Foo(someArgs);
    Bar bar = new Bar(foo);
  }
}

In most applications however, you just want one instance of a given object and to pass it around where its needed simply. This is what you get with Spring.

Mark a Foo with @Component and you can wire in properties using @Value: e.g.

@Component
public class Foo {
  private String someValue;
  public Foo(@Value("foo.someValue") String someValue) {
    this.someValue = someValue;
  }
}

Now when we want to use this instance of Foo anywhere in our code, all we have to do is mark the constructor with @Autowired.

e.g.

public class Bar {
    Foo foo;

    @Autowired
    public Bar(Foo foo) {
      this.foo = foo;
    }
}

So long as there's a Foo instance available in the 'Spring Application Context' it will be plugged into our class automatically without us having to create the foo first and wire it in ourselves. Spring has a registry of "Beans" as they're called (easier to just think of them as instances of instances of Java objects).

This is just a very high level introduction to it. Spring also offers interceptions to occur in your code when certain conditions are met, using just annotations, it also manages the lifecycle of your application code, offers good support for all manner of integrations (social media/database connectivity/security/etc. - much of which is used in this code base to make things easier to read).

In terms of API keys/passphrases, why do we need them, etc; these are a security mechanism known as OAuth. They are exchanged for access tokens when you make requests to the back end and they ensure you are the one making the requests and not someone else. Read only tokens should be sufficient for making requests that don't involve placing orders. The keys help identify who is using the API for coinbase and also act in place of your username/password which are far more readily taken advantage of if they are leaked.

For a simple example on using the repo - fork it to your own workspace, input your keys/passphrase, create a new class under a new package. Mark it with @Component, @Autowired in the MarketDataService and call getMarketDataOrderBook("BTC-USD", 3) and you'll have a snapshot of the orderbook available to you as a MarketData object. You can then call getBids/getAsks on that object.

rjpg commented 6 years ago

I do not see/understand any advantages in yor Foo Bar example compared to using pure Java (with out spring and/or annotations )...

Also lost it here : "

...Mark it with @Component, @Autowired in the MarketDataService and call getMarketDataOrderBook("BTC-USD", 3) and you'll have a snapshot of the orderbook available to you as a MarketData object. You can then call getBids/getAsks on that object...."

Can you provide some file example, assuming we are using the gdax-java.JAR, to have a orderbook snapshot ?

And, if possible (again assuming we are working with the JAR) another complete file example of placing a limit order ?

complete Java files Examples that have the main function ... so we understand were it starts (?... I was looking into the test classes but did not find the "main" function to understand were it starts or what to run (?) )

thanks in advance.

robevansuk commented 6 years ago

The example is overly simple, admittedly. Supposing you were to repeat the example 5-10 times, soon you'd appreciate an easier way that relieves you of all the boilerplate configuration for your classes. This is what Spring provides - dependency injection. You just have to tell Spring what dependencies need to be created so they can be made available for injection

If you look at MarketDataService, it makes use of a GdaxExchange object (the interface) that is @Autowired in (automatically injected/supplied from the Spring context - if available).

The GdaxExchangeImpl implements the GdaxExchange and is marked with @Component so an instance is available in the Spring Context.

Now whenever we need a GdaxExchange object we can annotate the Field or Constructor with @Autowired. This will then automatically inject an available GdaxExchangeImpl object into the field/constructor for us. We don't have to create an instance (across the several Service classes that make use of this object). We simply mark the constructor as @Autowired and say in the constructor signature that "we want one of those". This increases our ability to decouple the code hugely, which in turn improves our ability to maintain the code longer term, since now if we want a new implementation we can switch in an instant as soon as our new version of the GdaxExchange implementation is ready to swap out. Imagine having to update all your tests/class instantiations/configuration. It would take a huge effort without dependency injection.

Note: Spring is not the only Dependency Injection framework available. Google Guice also exists and also offers dependency injection.

As a worked example, pls see: https://github.com/robevansuk/gdax-java/blob/master/src/main/java/com/coinbase/exchange/api/gui/orderbook/OrderBookView.java#L98 which makes use of an autowired MarketDataService within the OrderBookView, so that the OrderBookView can call the getMarketData method. This will change in the near future so this link won't be around forever.

rjpg commented 6 years ago

I try to understand what you are saying but I don't because I don't know spring :-)

If possible I just need a .java file like this (with main...) in a eclipse project where the gdax-java .jar file is already in the classpath :

package main;

public class loader {

    public static void main(String[] args)  throws Exception {

        // 1 -what line codes should I use to do login 
        // 2 -what line codes should I use to select BTCEUR market  
        // 3 -what line codes should I use to retrieve the market data (depth 10) 
        // 4 -what line codes should I use to put buy / sell orders  

    }
}

Just need this info the rest I can take care ...

robevansuk commented 6 years ago

See https://stackoverflow.com/questions/48247177/gdax-api-bad-request-400/48382532#48382532 for a very similar example for what you are trying to do.

  1. no login exists as such when interacting with GDAX via the API. Requests are authenticated with API keys and signatures on the message to determine its authenticity.
  2. selecting BTC-EUR market - MarketDataService.getMarketData("BTC-EUR", 2) will get the top 50 bid/ask orders as a MarketData object
  3. MarketData.getBids() and MarketData.getAsks()
  4. OrderService.createOrder(someOrderObject) - creates a type of order. So far limit orders are handled but this needs building out a bit more, for various other types of order.
rjpg commented 6 years ago

Thanks ! I will test . Finaly I see one example with a main function ! I was about to lose hope ...

willydk commented 6 years ago

Thanks @robevansuk, that stackoverflow example works for me