ndeet / php-ln-lnd-rest

A Lightning Network Daemon (LND) package for LND's REST endpoints. PHP classes are generated by the Swagger Codegen project.
8 stars 4 forks source link

cURL error 60: SSL certificate problem: self signed certificate #2

Open jiyongieee opened 5 years ago

jiyongieee commented 5 years ago

Hi. I tried to use the api to display the walletBalance details but I got this error:

Exception when calling LightningApi->walletBalance: [0] cURL error 60: SSL certificate problem: self signed certificate (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)

May I know why this happened?

ndeet commented 5 years ago

Hi, this happens with self signed certs like LND creates by default. It worked before with passing the cert to Guzzle but I just tried and get an error. So the best way for local testing is to disable SSL validation e.g.

$apiInstance = new Lnd\Rest\Api\LightningApi(
  new GuzzleHttp\Client([
    'debug' => TRUE,
    'verify' => FALSE,
    'headers' => [
      'Grpc-Metadata-macaroon' => bin2hex($macaroonPath)
    ]
  ]),
  $apiConfig
);

try {
  $result = $apiInstance->getInfo();
  echo '<pre>';
  var_dump($result);
  echo '</pre>';
} catch (Exception $e) {
  echo 'Exception when calling LightningApi->getInfo: ', $e->getMessage(), PHP_EOL;
}

(don't do this on production though and put a proper proxy with valid SSL in front of LND)

btw, just updated files to LND 0.7.1

jiyongieee commented 5 years ago

Alright I already changed it to false and it works. Anyway I have another question regarding getinfo. I received this error:

Exception when calling LightningApi->getInfo: Object of class stdClass could not be converted to string

But, for walletbalance, it success. I wonder why I got error for getinfo method. Can you help me? Thank you.

ndeet commented 5 years ago

Not sure what is missing, can you share the full code? You need to instantiate LightningApi like I do above and then call $apiInstance->getInfo().

jiyongieee commented 5 years ago

Sure this is my function for getInfo method.

public function getInfo() {
$adminMacaroonFilePath = '../public/admin.macaroon'; $apiInstance = new LightningApi (new Client([ 'headers' => [ 'Grpc-Metadata-macaroon' => bin2hex(file_get_contents($adminMacaroonFilePath)) ] ])); try {
$result = $apiInstance->getInfo(); dd($result); } catch (\Exception $e) {
echo 'Exception when calling LightningApi->getInfo: ', $e->getMessage(), PHP_EOL; } }

I'm not sure what is missing here.

ndeet commented 5 years ago

@jiyongieee nothing obvious I see, seems good BUT:

please rename your own function to something else, because without more context and actual line of error it could also be that LND API works fine but your function is causing the error as a different return type is expected which can't be processed?

Another unrelated thing: your admin.macarron seems to be in public accessible path of your webapp (Laravel?) you should not put it there. With admin.macaroon anybody can swipe your funds.

jiyongieee commented 5 years ago

Thanks about the macaroon I just put it for a teest. Anyway, I think I tried another functions are working except this getinfo. I need to comment this ObjectSerializer::deserialize($content, $returnType, []) and just return $content to display getinfo.

public function getInfoWithHttpInfo() {

    $returnType = '\Lnd\Rest\Model\LnrpcGetInfoResponse';
    $request = $this->getInfoRequest();
    try {
        $options = $this->createHttpClientOption();

        try {
            $response = $this->client->send($request, $options);                
        } 
        catch (RequestException $e) {
            throw new ApiException(
                "[{$e->getCode()}] {$e->getMessage()}",
                $e->getCode(),
                $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
            );
        }
        $statusCode = $response->getStatusCode();
        if ($statusCode < 200 || $statusCode > 299) {
            throw new ApiException(
                sprintf(
                    '[%d] Error connecting to the API (%s)',
                    $statusCode,
                    $request->getUri()
                ),
                $statusCode,
                $response->getHeaders(),
                $response->getBody()
            );
        }
        $responseBody = $response->getBody();

        if ($returnType === '\SplFileObject') {
            $content = $responseBody; //stream goes to serializer
        } else {
            $content = $responseBody->getContents();

            if ($returnType !== 'string') {
                $content = json_decode($content);
                //dd($content);
            }
        }

        return [
            //ObjectSerializer::deserialize($content, $returnType, []),
            $content,
            $response->getStatusCode(),
            $response->getHeaders()
        ];
    } 
    catch (ApiException $e) {
        switch ($e->getCode()) {
            case 200:
                $data = ObjectSerializer::deserialize(
                    $e->getResponseBody(),
                    '\Lnd\Rest\Model\LnrpcGetInfoResponse',
                    $e->getResponseHeaders()
                );
                $e->setResponseObject($data);
                break;
        }
        throw $e;
    }
}
ndeet commented 5 years ago

Not sure what the other not pasted functions do but the one you posted above looks a bit overwhelming and I'm not sure what's going on there (eg. see no reason why that $returnType used or needed for, the api call will return the correct type already). From this package you do not need any deserialization, not sure where it gets serialized and for what reason. As I said, too many moving parts imo. My suggestion is that you make it work in the controller directly without any exception handling or other things that could break something that has nothing todo with the api calls. If that works, then move parts around into functions and ensure it still works.