PHPackages                             legalthings/lto-api - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. legalthings/lto-api

Abandoned → [lto/api](/?search=lto%2Fapi)Library

legalthings/lto-api
===================

LTO Network client

v0.3.0(5y ago)03843[4 issues](https://github.com/legalthings/lto-api.php/issues)MITPHPPHP &gt;=7.2.0

Since Mar 28Pushed 3y ago6 watchersCompare

[ Source](https://github.com/legalthings/lto-api.php)[ Packagist](https://packagist.org/packages/legalthings/lto-api)[ RSS](/packages/legalthings-lto-api/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (5)Versions (35)Used By (0)

[![LTO github readme](https://user-images.githubusercontent.com/100821/196711741-96cd4ba5-932a-4e95-b420-42d4d61c21fd.png)](https://user-images.githubusercontent.com/100821/196711741-96cd4ba5-932a-4e95-b420-42d4d61c21fd.png)

LTO Network client for PHP
==========================

[](#lto-network-client-for-php)

[![PHP](https://github.com/ltonetwork/lto-api.php/workflows/PHP/badge.svg)](https://github.com/ltonetwork/lto-api.php/actions)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/5928d9ef5b3a05feb8bebdaf94472d44d05d2f9dcafd23f0cba6d5c7bb798bd7/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6c746f6e6574776f726b2f6c746f2d6170692e7068702f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/ltonetwork/lto-api.php/?branch=master)[![Code Coverage](https://camo.githubusercontent.com/d474354c2a5bf67e7eeef58d2fbf433c3c7fba49d610329aafbcaeea97c30ed6/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6c746f6e6574776f726b2f6c746f2d6170692e7068702f6261646765732f636f7665726167652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/ltonetwork/lto-api.php/?branch=master)[![Packagist Stable Version](https://camo.githubusercontent.com/efdda6845ea74216780596cf646eb448bf1ccb75a40a6e17578397507a238dc4/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6c746f2f6170692e737667)](https://packagist.org/packages/lto/api)[![Packagist License](https://camo.githubusercontent.com/0c4618f7b3dae3f05fd824f29819f285a4712bd38398a2f6a7a0f65777baae51/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6c746f2f6170692e737667)](https://packagist.org/packages/lto/api)

*Signing and addresses work both for the (private) event chain as for the public chain.*

Installation
------------

[](#installation)

```
composer require lto/api

```

Accounts
--------

[](#accounts)

### Creation

[](#creation)

#### Create an account from seed

[](#create-an-account-from-seed)

```
$seedText = "manage manual recall harvest series desert melt police rose hollow moral pledge kitten position add";

$factory = new LTO\AccountFactory('T'); // 'T' for testnet, 'L' for mainnet
$account = $factory->seed($seedText);
```

#### Create an account from sign key

[](#create-an-account-from-sign-key)

```
$secretKey = 'wJ4WH8dD88fSkNdFQRjaAhjFUZzZhV5yiDLDwNUnp6bYwRXrvWV8MJhQ9HL9uqMDG1n7XpTGZx7PafqaayQV8Rp';

$factory = new LTO\AccountFactory('T'); // 'T' for testnet, 'L' for mainnet
$account = $factory->create($secretKey);
```

#### Create an account from full info

[](#create-an-account-from-full-info)

```
$accountInfo = [
  'address' => '3PLSsSDUn3kZdGe8qWEDak9y8oAjLVecXV1',
  'sign' => [
    'secretkey' => 'wJ4WH8dD88fSkNdFQRjaAhjFUZzZhV5yiDLDwNUnp6bYwRXrvWV8MJhQ9HL9uqMDG1n7XpTGZx7PafqaayQV8Rp',
    'publickey' => 'FkU1XyfrCftc4pQKXCrrDyRLSnifX1SMvmx1CYiiyB3Y'
  ],
  'encrypt' => [
    'secretkey' => 'BnjFJJarge15FiqcxrB7Mzt68nseBXXR4LQ54qFBsWJN',
    'publickey' => 'BVv1ZuE3gKFa6krwWJQwEmrLYUESuUabNCXgYTmCoBt6'
  ]
];

$factory = new LTO\AccountFactory('T'); // 'T' for testnet, 'L' for mainnet
$account = $factory->create($accountInfo);
```

Properties that are specified will be verified. Properties that are omitted will be generated where possible.

### Signing (ED25519)

[](#signing-ed25519)

#### Sign a message

[](#sign-a-message)

```
$signature = $account->sign('hello world'); // Base58 encoded signature
```

#### Verify a signature

[](#verify-a-signature)

```
if (!$account->verify($signature, 'hello world')) {
    throw new RuntimeException('invalid signature');
}
```

### Encryption (X25519)

[](#encryption-x25519)

#### Encrypt a message for another account

[](#encrypt-a-message-for-another-account)

```
$message = 'hello world';

$recipientPublicKey = "HBqhfdFASRQ5eBBpu2y6c6KKi1az6bMx8v1JxX4iW1Q8"; // base58 encoded X25519 public key
$recipient = $factory->createPublic(null, $recipientPublicKey);

$cyphertext = $account->encryptFor($recipient, $message); // Raw binary, not encoded
```

You can use `$account->encryptFor($account, $message);` to encrypt a message for yourself.

#### Decrypt a message received from another account

[](#decrypt-a-message-received-from-another-account)

```
$senderPublicKey = "HBqhfdFASRQ5eBBpu2y6c6KKi1az6bMx8v1JxX4iW1Q8"; // base58 encoded X25519 public key
$sender = $factory->createPublic(null, $senderPublicKey);

$message = $account->decryptFrom($sender, $cyphertext);
```

You can use `$account->decryptFrom($account, $message);` to decrypt a message from yourself.

Public layer
------------

[](#public-layer)

```
use LTO\Transaction\Transfer;
use LTO\PublicNode;

$node = new PublicNode('https://nodes.lto.network');

$amount = 1000.0; // Amount of LTO to transfer
$recipient = "3Jo1JCrBvnWCg37VDxMXAjYhsS9rRDLBSze";

$transferTx = (new Transfer($amount, $recipient))
    ->signWith($account)
    ->broadcastTo($node);
```

Private layer
-------------

[](#private-layer)

### Event chain

[](#event-chain)

#### Create a new event chain

[](#create-a-new-event-chain)

```
$chain = $account->createEventChain(); // Creates an empty event chain with a valid id and last hash
```

*Note: You need to add an identity as first event on the chain. This is **not** done automatically.*

#### Create and sign an event and add it to an existing event chain

[](#create-and-sign-an-event-and-add-it-to-an-existing-event-chain)

```
$body = [
  '$schema' => "http://specs.example.com/message#",
  'content' => "Hello world!"
];

$chainId = "JEKNVnkbo3jqSHT8tfiAKK4tQTFK7jbx8t18wEEnygya";
$chainLastHash = "3yMApqCuCjXDWPrbjfR5mjCPTHqFG8Pux1TxQrEM35jj";

$chain = new LTO\EventChain($chainId, $chainLastHash);

$chain->add(new Event($body))->signWith($account);
```

You need the chain id and the hash of the last event to use an existing chain.

### HTTP Authentication

[](#http-authentication)

Signing HTTP Messages is described IETF draft [draft-cavage-http-signatures-10](https://tools.ietf.org/id/draft-cavage-http-signatures-10.html).

The [HTTP Authentication library](https://github.com/jasny/http-signature) can be used to sign and verify [PSR-7 requests](https://www.php-fig.org/psr/psr-7/#33-psrhttpmessageresponseinterface).

This library can be used in conjunction with the HTTP authentication library. The `keyId` should be the base58 encoded public key.

For `POST` and `PUT` requests, it's recommended to create an HTTP Digest ([RFC 3230](https://tools.ietf.org/html/rfc3230)). This is a hash of the body, which manages to indirectly include the body in the signature. See the [HTTP Digest library](https://github.com/jasny/http-digest).

#### Creating the HTTP Authentication service

[](#creating-the-http-authentication-service)

```
use Jasny\HttpSignature\HttpSignature;

$secretKey = 'wJ4WH8dD88fSkNdFQRjaAhjFUZzZhV5yiDLDwNUnp6bYwRXrvWV8MJhQ9HL9uqMDG1n7XpTGZx7PafqaayQV8Rp';

$factory = new LTO\AccountFactory('T'); // 'T' for testnet, 'L' for mainnet
$ourAccount = $factory->create($secretKey);

$service = new HttpSignature(
    ['ed25519', 'ed25519-sha256'],
    new SignCallback($ourAccount),
    new VerifyCallback($accountFactory)
);
```

#### Server middleware

[](#server-middleware)

Create server middleware to verify incoming requests.

The `LTO\Account\ServerMiddleware` can be used to set the `account` attribute for a server request that contains a `signature_key_id` attribute.

```
use Jasny\HttpDigest\HttpDigest;
use Jasny\HttpDigest\ServerMiddleware as DigestMiddleware;
use Jasny\HttpDigest\Negitiation\DigestNegotiator;
use Jasny\HttpSignature\HttpSignature;
use Jasny\HttpSignature\ServerMiddleware as SignatureMiddleware;
use LTO\Account\ServerMiddleware as AccountMiddleware;
use Relay\RelayBuilder;

$factory = new LTO\AccountFactory('T'); // 'T' for testnet, 'L' for mainnet
$ourAccount = $factory->create($secretKey);

$digestService = HttpDigest(new DigestNegotiator(), ["SHA-256"]);

$signatureService = new HttpSignature(
    ['ed25519', 'ed25519-sha256'],
    function() { throw new \LogicException('sign not supported'); },
    new VerifyCallback($accountFactory)
);

$relayBuilder = new RelayBuilder($resolver);
$relay = $relayBuilder->newInstance([
    (new DigestMiddleware($digestService))->asDoublePass(),
    (new SignatureMiddleware($signatureService))->asDoublePass(),
    (new AccountMiddleware($factory))->asDoublePass(),
]);
```

The server middleware implements the PSR-15 `MiddlewareInterface` for single pass support and returns a callback for double pass with the `asDoublePass()` method.

#### Client middleware

[](#client-middleware)

Create client middleware to sign outgoing requests.

```
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Client;
use Jasny\HttpDigest\HttpDigest;
use Jasny\HttpDigest\ClientMiddleware as DigestMiddleware;
use Jasny\HttpDigest\Negitiation\DigestNegotiator;
use Jasny\HttpSignature\HttpSignature;
use Jasny\HttpSignature\ClientMiddleware as SignatureMiddleware;

$secretKey = 'wJ4WH8dD88fSkNdFQRjaAhjFUZzZhV5yiDLDwNUnp6bYwRXrvWV8MJhQ9HL9uqMDG1n7XpTGZx7PafqaayQV8Rp';

$factory = new LTO\AccountFactory('T'); // 'T' for testnet, 'L' for mainnet
$ourAccount = $factory->create($secretKey);

$digestService = HttpDigest(new DigestNegotiator(), ["SHA-256"]);

$signatureService = new HttpSignature(
    ['ed25519', 'ed25519-sha256'],
    new SignCallback($ourAccount),
    function() { throw new \LogicException('verify not supported'); }
);

$signatureMiddleware = new SignatureMiddleware(
    $service->withAlgorithm('ed25519-sha256'),
    $ourAccount->getPublicKey()
);

$stack = new HandlerStack();
$stack->push((new DigestMiddleware($digestService))->forGuzzle());
$stack->push($signatureMiddleware->forGuzzle());

$client = new Client(['handler' => $stack]);
```

Commandline scripts
-------------------

[](#commandline-scripts)

### Generate account from seed

[](#generate-account-from-seed)

Get the seed from `stdin` to generate account info.

```
$ vendor/bin/lto-seed
