Skip to content

Commit 3c5dbe8

Browse files
committed
Adjust Readme.md with more info about Borsh
1 parent 7138002 commit 3c5dbe8

22 files changed

+1226
-116
lines changed

README.md

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
[![Coverage (CodeCov)](https://codecov.io/github/Attestto-com/solana-php-sdk/graph/badge.svg?token=M12LECZ9QE)](https://codecov.io/github/Attestto-com/solana-php-sdk)
66
---
77

8-
:notice: Forked from: [verze-app/solana-php-sdk](https://github.com/verze-app/solana-php-sdk)
8+
## notice: Forked from the abandoned repo: [verze-app/solana-php-sdk](https://github.com/verze-app/solana-php-sdk)
99

1010
---
1111

@@ -79,8 +79,8 @@ For Borsh serialization/deseralization to work, a class::SCHEMA object reflectin
7979
class DidData
8080
{
8181

82-
use BorshDeserializable;
83-
82+
use BorshObject; //trait
83+
public $keyData;
8484

8585
public const SCHEMA = [
8686
VerificationMethodStruct::class => VerificationMethodStruct::SCHEMA[VerificationMethodStruct::class],
@@ -110,8 +110,46 @@ class DidData
110110
}
111111
}
112112
```
113+
## BORSH USAGE (PHP implementation)
114+
115+
To get a better understanding on the implementation and usage, please refer to the following references:
116+
117+
- [PHP Borsh Test](https://github.com/Attestto-com/solana-php-sdk/blob/master/tests/Unit/BorshTest.php)
118+
- [PHP Borsh Class](https://github.com/Attestto-com/solana-php-sdk/blob/master/src/Borsh/Borsh.php)
119+
- [PHP Borsh Trait](https://github.com/Attestto-com/solana-php-sdk/blob/master/src/Borsh/BorshObject.php)
120+
121+
example usage _**(This will be improved, WIP)**_:
122+
```php
123+
/**
124+
* deserializeDidData
125+
*
126+
* @param string $dataBase64 The base64 encoded data of the DID data account
127+
* @return DidData The deserialized DID data object
128+
* @example DidSolProgram::deserializeDidData('TVjvjfsd7fMA/gAAAA...');
129+
*/
130+
static function deserializeDidData($dataBase64)
131+
{
132+
133+
$base64String = base64_decode($dataBase64);
134+
$uint8Array = array_values(unpack('C*', $base64String));
135+
$didData = DidData::fromBuffer($uint8Array); // See above code block
136+
137+
$keyData = $didData->keyData;
113138

114-
Note: This project is in alpha, the code to generate instructions is still being worked on `$instruction = SystemProgram::abc()`
139+
$binaryString = pack('C*', ...$keyData);
140+
141+
$b58 = new Base58();
142+
$base58String = $b58->encode($binaryString);
143+
$didData->keyData = $base58String;
144+
return $didData;
145+
}
146+
```
147+
148+
## Notes:
149+
150+
- Most of the Magic is done in the [BorshDesealizable.php](https://github.com/Attestto-com/solana-php-sdk/blob/master/src/Borsh/BorshDeserializable.php) Trait.
151+
- This project is in alpha, the code to generate instructions is still being worked on `$instruction = SystemProgram::abc()`
152+
- This project is maintained by a single dev, so any feedback, ideas, comments are appreciated.
115153

116154
## Roadmap (WIP)
117155

@@ -124,7 +162,14 @@ Note: This project is in alpha, the code to generate instructions is still being
124162
2. Better cache `$recentBlockhash` when sending transactions.
125163
6. Suggestions? Open an issue or PR :D
126164

127-
## Testing
165+
## Testing & Code Coverage
166+
167+
WIP -- Working on coverage and deprecations. See [Coverage Report](https://app.codecov.io/github/Attestto-com/solana-php-sdk).
168+
169+
170+
[![GitHub Tests Action Status](https://github.com/Attestto-com/solana-php-sdk/actions/workflows/run-tests.yml/badge.svg?branch=master)](https://github.com/Attestto-com/solana-php-sdk/actions/workflows/run-tests.yml)
171+
[![Coverage (CodeCov)](https://codecov.io/github/Attestto-com/solana-php-sdk/graph/badge.svg?token=M12LECZ9QE)](https://codecov.io/github/Attestto-com/solana-php-sdk)
172+
128173

129174
```bash
130175
composer test

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
}
3232
],
3333
"require": {
34-
"php": "~8.0",
34+
"php": "~8.2",
3535
"ext-sodium": "*",
3636
"guzzlehttp/guzzle": "^7.3",
3737
"paragonie/sodium_compat": "^1.17",

docs/CLI.md

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
## SOLANA SDK CLI for Newbies
2+
3+
[Solana CLI Installation Instructions](https://docs.solanalabs.com/cli/install)
4+
5+
## Why installing the CLI?
6+
7+
I actually installed the CLI long time ago but never used it and tried with no luck to get things working using Vanilla JS and the Web3.js in intermittent attempts. ( hint: It doesn't work because the Web3.js package uses node.js libraries, as far as I know )
8+
9+
So, why is it needed?
10+
11+
Answer: Because the browser wallets provide very limited functionality when using them in DEV mode.
12+
13+
## Getting Started
14+
15+
#### 1- **Install a FileSystem Wallet (DEVNET)** [Docs](https://docs.solanalabs.com/cli/wallets/paper)
16+
17+
DO NOT do this for a Mainnet wallet as your keys would be residing in the Filesystem. You need to provide a valid URL, custom RPCs are not supported ( not recognized )
18+
19+
```bash
20+
solana config set --url https://api.devnet.solana.com
21+
```
22+
23+
#### 2- Fund the Wallet with more than SOL:
24+
25+
The following cmd generates a new keypair and stores it in the following path by default: _/Users/[yourUser]/.config/solana/id.json_
26+
27+
```bash
28+
solana-keygen new
29+
```
30+
31+
#### 3- Verifying the configuration:
32+
33+
```bash
34+
solana config get
35+
```
36+
37+
Output:
38+
39+
```bash
40+
Config File: /Users/eduardochongkan/.config/solana/cli/config.yml
41+
RPC URL: https://api.devnet.solana.com
42+
WebSocket URL: wss://api.devnet.solana.com/ (computed)
43+
Keypair Path: Pasv78UQDTJyPLSS8FTtCekyZHJoPcZCjiGWkr7hdzy.json
44+
Commitment: confirmed
45+
```
46+
47+
#### 4- Funding the Wallet:
48+
49+
To fund the local wallet:
50+
```bash
51+
solana airdrop 1
52+
```
53+
54+
To fund a remote wallet, e.g. a Phantom Wallet. If it fails due to Rate Limiting, try again with 0.5 Sol.
55+
56+
```bash
57+
solana airdrop 1 3Js7k6xYQbvXv6qUYLapYV7Sptfg37Tss9GcAyVEuUqk
58+
```
59+
OR
60+
```bash
61+
solana airdrop 0.5 3Js7k6xYQbvXv6qUYLapYV7Sptfg37Tss9GcAyVEuUqk
62+
```
63+
64+
Then
65+
66+
```bash
67+
solana balance
68+
```
69+
OR
70+
```bash
71+
solana balance 3Js7k6xYQbvXv6qUYLapYV7Sptfg37Tss9GcAyVEuUqk
72+
```
73+
74+
#### Wrapped Sol (wSol)
75+
76+
```bash
77+
spl-token --url devnet wrap 0.5
78+
```
79+
Outputs:
80+
```bash
81+
Wrapping 0.5 SOL into GdDubLim7hPPv95X2xPdKtbvWt4gJJ4uHfUYrPbxmKuZ
82+
83+
Signature: ertqCkWCkwtgCzDFtXbyNvFL9zEiqTmHX6zjMxpGXqAuPH8n7FCEaAnL7MiQpmL6cWGVWtEBVPXcRkqSKAvYNrx
84+
```
85+
86+
#### Getting Token Balance
87+
88+
```bash
89+
solana balance GdDubLim7hPPv95X2xPdKtbvWt4gJJ4uHfUYrPbxmKuZ
90+
```
91+
Outputs (that is wrapped Sol (wSol))
92+
```bash
93+
0.5 SOL
94+
```
95+
OR
96+
97+
```bash
98+
spl-token
99+
```
100+
101+
### Some DEVNET Token Mints:
102+
103+
- [Devnet USDC](https://explorer.solana.com/address/DL4ivZm3NVHWk9ZvtcqTchxoKArDK4rT3vbDx2gYVr7P?cluster=devnet): 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU
104+
- [Devnet USDT](https://explorer.solana.com/address/EJwZgeZrdC8TXTQbQBoL6bfuAnFUUy1PVCMB4DYPzVaS?cluster=devnet): EJwZgeZrdC8TXTQbQBoL6bfuAnFUUy1PVCMB4DYPzVaS
105+
- [Devnet SOL (wSOL](https://explorer.solana.com/address/So11111111111111111111111111111111111111112?cluster=devnet): So11111111111111111111111111111111111111112

src/.DS_Store

6 KB
Binary file not shown.

src/Programs/DidSolProgram.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
use Attestto\SolanaPhpSdk\SolanaRpcClient;
1010

1111
/**
12-
* Class DidSolProgram
12+
* Class DidSolProgram - Work In Progress
1313
*
1414
* This class represents a program for interacting with the Solana blockchain using the DID (Decentralized Identifier) protocol.
1515
* It provides methods for creating and managing DID accounts, signing and verifying messages, and other related operations.

src/Programs/SNS/Utils.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Attestto\SolanaPhpSdk\Programs\SNS;
44

5+
use Attestto\SolanaPhpSdk\Exceptions\InputValidationException;
56
use Attestto\SolanaPhpSdk\PublicKey;
67
use Attestto\SolanaPhpSdk\Connection;
78
use Attestto\SolanaPhpSdk\Exceptions\GenericException;
@@ -13,7 +14,8 @@ class Utils
1314
{
1415

1516
// config.json file should be in the same directory as this file
16-
public $config;
17+
public mixed $config;
18+
public $centralStateSNSRecords;
1719

1820

1921
// Constructor
@@ -25,7 +27,7 @@ public function __construct($config = null)
2527
$this->config = $this->loadConstants();
2628
}
2729
$sns_records_id = new PublicKey($this->config['BONFIDA_SNS_RECORDS_ID']);
28-
//dd($sns_records_id);
30+
2931
$this->centralStateSNSRecords = PublicKey::findProgramAddressSync(
3032
[$sns_records_id],
3133
$sns_records_id);
@@ -47,11 +49,12 @@ public function getHashedNameSync(string $name): Buffer
4749
}
4850

4951
/**
50-
* @deprecated Use {@link getNameAccountKeySync} instead
51-
* @param string $hashedName The hashed name buffer
52+
* @param Buffer $hashed_name
5253
* @param PublicKey|null $nameClass The name class public key
5354
* @param PublicKey|null $nameParent The name parent public key
5455
* @return PublicKey The public key of the name account
56+
* @throws InputValidationException
57+
* @deprecated Use {@link getNameAccountKeySync} instead
5558
*/
5659
public function getNameAccountKeySync(
5760
Buffer $hashed_name,

src/SolanaRpcClient.php

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,27 @@
22

33
namespace Attestto\SolanaPhpSdk;
44

5+
use GuzzleHttp\Handler\StreamHandler;
6+
use GuzzleHttp\Psr7\Message;
7+
use GuzzleHttp\Psr7\Uri;
8+
59
use Psr\Http\Client\ClientExceptionInterface;
610
use Psr\Http\Client\ClientInterface;
711
use Psr\Http\Message\RequestFactoryInterface;
8-
use Psr\Http\Message\ResponseInterface;
12+
use GuzzleHttp\Client as GuzzleClient;
13+
use GuzzleHttp\Psr7\Request;
14+
use GuzzleHttp\Psr7\Response;
15+
use GuzzleHttp\Psr7\HttpFactory;
16+
17+
918
use Attestto\SolanaPhpSdk\Exceptions\GenericException;
1019
use Attestto\SolanaPhpSdk\Exceptions\InvalidIdResponseException;
1120
use Attestto\SolanaPhpSdk\Exceptions\MethodNotFoundException;
1221
use Psr\Http\Message\StreamFactoryInterface;
22+
use Psr\Http\Message\StreamInterface;
1323
use Psr\Http\Message\UriFactoryInterface;
24+
use Random\RandomException;
25+
1426

1527
/**
1628
* @see https://docs.solana.com/developing/clients/jsonrpc-api
@@ -49,24 +61,25 @@ class SolanaRpcClient
4961

5062
/**
5163
* @param string $endpoint
52-
* @param ClientInterface $httpClient
53-
* @param RequestFactoryInterface $requestFactory
54-
* @param StreamFactoryInterface $streamFactory
55-
* @param UriFactoryInterface $uriFactory
64+
* @param ClientInterface|null $httpClient
65+
* @param RequestFactoryInterface|null $requestFactory
66+
* @param StreamFactoryInterface|Message|null $streamFactory
67+
* @param UriFactoryInterface|null $uriFactory
68+
* @throws RandomException
5669
*/
5770
public function __construct(
5871
string $endpoint,
59-
ClientInterface $httpClient,
60-
RequestFactoryInterface $requestFactory,
61-
StreamFactoryInterface $streamFactory,
62-
UriFactoryInterface $uriFactory
72+
ClientInterface $httpClient = null,
73+
RequestFactoryInterface $requestFactory = null,
74+
StreamFactoryInterface|Message $streamFactory= null ,
75+
UriFactoryInterface $uriFactory= null
6376
) {
64-
$this->endpoint = $endpoint;
77+
$this->endpoint = $endpoint ? : self::DEVNET_ENDPOINT;
6578
$this->randomKey = random_int(0, 99999999);
66-
$this->httpClient = $httpClient;
67-
$this->requestFactory = $requestFactory;
68-
$this->streamFactory = $streamFactory;
69-
$this->uriFactory = $uriFactory;
79+
$this->httpClient = $httpClient?: new GuzzleClient();
80+
$this->requestFactory = $requestFactory?: new HttpFactory();
81+
// $this->streamFactory = $streamFactory;
82+
// $this->uriFactory = $uriFactory?: new Uri();
7083
}
7184

7285
/**
@@ -84,10 +97,10 @@ public function call(string $method, array $params = [], array $headers = []): m
8497
$body = json_encode($this->buildRpc($method, $params));
8598
$request = $this->requestFactory->createRequest('POST', $this->endpoint)
8699
->withHeader('Content-Type', 'application/json')
87-
->withHeader('Accept', 'application/json')
88-
->withBody($this->streamFactory->createStream($body));
100+
->withHeader('Accept', 'application/json');
101+
//->withBody($this->streamFactory->createStream($body));
89102

90-
$response = $this->httpClient->request('POST', $this->endpoint, ['body' => $request->getBody()->getContents()]);
103+
$response = $this->httpClient->request('POST', $this->endpoint, ['body' => $body]);
91104

92105

93106

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
namespace Attestto\SolanaPhpSdk\Tests\Unit\Programs\SNS;
4+
5+
use Attestto\SolanaPhpSdk\PublicKey;
6+
use Attestto\SolanaPhpSdk\Tests\TestCase;
7+
use Attestto\SolanaPhpSdk\TransactionInstruction;
8+
use Attestto\SolanaPhpSdk\Util\Buffer;
9+
use Attestto\SolanaPhpSdk\Borsh\Borsh;
10+
use Attestto\SolanaPhpSdk\Programs\SNS\InstructionBurn;
11+
use Attestto\SolanaPhpSdk\Programs\SNS\Utils;
12+
13+
class DerivationTest extends TestCase
14+
{
15+
16+
private $items = [
17+
[
18+
'domain' => 'bonfida',
19+
'address' => 'Crf8hzfthWGbGbLTVCiqRqV5MVnbpHB1L9KQMd6gsinb',
20+
],
21+
[
22+
'domain' => 'bonfida.sol',
23+
'address' => 'Crf8hzfthWGbGbLTVCiqRqV5MVnbpHB1L9KQMd6gsinb',
24+
],
25+
[
26+
'domain' => 'dex.bonfida',
27+
'address' => 'HoFfFXqFHAC8RP3duuQNzag1ieUwJRBv1HtRNiWFq4Qu',
28+
],
29+
[
30+
'domain' => 'dex.bonfida.sol',
31+
'address' => 'HoFfFXqFHAC8RP3duuQNzag1ieUwJRBv1HtRNiWFq4Qu',
32+
],
33+
];
34+
35+
public function setUp(): void
36+
{
37+
parent::setUp();
38+
}
39+
40+
/** @test */
41+
public function it_derives_domain_key()
42+
{
43+
$utils = new Utils();
44+
foreach ($this->items as $item) {
45+
$result = $utils->getDomainKey($item['domain']);
46+
$this->assertInstanceOf(PublicKey::class, $result['pubkey']);
47+
$this->assertEquals($item['address'], $result['pubkey']->toBase58());
48+
}
49+
50+
foreach ($this->items as $item) {
51+
$result = $utils->getDomainKeySync($item['domain']);
52+
$this->assertInstanceOf(PublicKey::class, $result['pubkey']);
53+
$this->assertEquals($item['address'], $result['pubkey']->toBase58());
54+
}
55+
}
56+
57+
}

0 commit comments

Comments
 (0)