diff --git a/README.md b/README.md
index a615013..2efdba9 100644
--- a/README.md
+++ b/README.md
@@ -115,10 +115,9 @@ For all examples it is assumed that you have a variable `$api = new GW2Api()`.
/v2/items | [Item\ItemEndpoint][ItemEndpoint]
`GW2Api::items()` | 📦🌏
~~/v2/leaderboards~~ | *disabled* | 🚫
/v2/maps | [Map\MapEndpoint][MapEndpoint]
`GW2Api::maps()` | 📦🌏
- /v2/materials | [Material\MaterialEndpoint][MaterialEndpoint]
`GW2Api::materials()` | 📦🌏
- ~~/v2/pvp~~ | *disabled* | 🚫
- ~~/v2/pvp/games~~ | *disabled* | 🚫
- ~~/v2/pvp/stats~~ | *disabled* | 🚫
+ /v2/materials | [Material\MaterialEndpoint][MaterialEndpoint]
`GW2Api::materials()` | 📦🌏 | 🚫
+ /v2/pvp/games | [Pvp\GameEndpoint][Pvp\GameEndpoint]
`GW2Api::pvp()->games()` | 🔒📦
+ /v2/pvp/stats | [Pvp\StatsEndpoint][Pvp\StatsEndpoint]
`GW2Api::pvp()->stats()` | 🔒
/v2/quaggans | [Quaggan\QuagganEndpoint][QuagganEndpoint]
`GW2Api::quaggans()` | 📦
/v2/recipes | [Recipe\RecipeEndpoint][RecipeEndpoint]
`GW2Api::recipes()` | 📦
/v2/recipes/search | [Recipe\SearchEndpoint][Recipe\SearchEndpoint]
`GW2Api::recipes()->search()` |
@@ -791,6 +790,42 @@ $api->materials()->lang('es')->all();
```
+#### /v2/pvp/games
+[Pvp\GameEndpoint]: #v2pvpgames
+
+`\GW2Treasures\GW2Api\V2\Endpoint\Pvp\GameEndpoint`
+([source](src/V2/Endpoint/Pvp/GameEndpoint.php))
+
+Implements [🔒AuthenticatedEndpoint][AuthenticatedEndpoint] and [📦BulkEndpoint][BulkEndpoint].
+
+##### Methods
+ - Inherited from [📦BulkEndpoint][BulkEndpoint].
+
+##### Example
+```php
+$api->pvp('API_KEY')->games()->get('A9F9FD97-F114-4F97-B2CA-5E814DF0340E');
+// => { id: "A9F9FD97-F114-4F97-B2CA-5E814DF0340E", map_id: 795, … }
+```
+
+
+#### /v2/pvp/stats
+[Pvp\StatsEndpoint]: #v2pvpstats
+
+`\GW2Treasures\GW2Api\V2\Endpoint\Pvp\StatsEndpoint`
+([source](src/V2/Endpoint/Pvp/StatsEndpoint.php))
+
+Implements [🔒AuthenticatedEndpoint][AuthenticatedEndpoint].
+
+##### Methods
+ - `get():mixed` Get pvp stats.
+
+##### Example
+```php
+$api->pvp('API_KEY')->stats()->get();
+// => { pvp_rank: 57, aggregate: { wins: 343, … }, … }
+```
+
+
#### /v2/quaggans
[QuagganEndpoint]: #v2quaggans
diff --git a/src/GW2Api.php b/src/GW2Api.php
index 27b5e8b..573dfc4 100644
--- a/src/GW2Api.php
+++ b/src/GW2Api.php
@@ -14,6 +14,7 @@
use GW2Treasures\GW2Api\V2\Endpoint\Item\ItemEndpoint;
use GW2Treasures\GW2Api\V2\Endpoint\Map\MapEndpoint;
use GW2Treasures\GW2Api\V2\Endpoint\Material\MaterialEndpoint;
+use GW2Treasures\GW2Api\V2\Endpoint\Pvp\PvpEndpoint;
use GW2Treasures\GW2Api\V2\Endpoint\Quaggan\QuagganEndpoint;
use GW2Treasures\GW2Api\V2\Endpoint\Recipe\RecipeEndpoint;
use GW2Treasures\GW2Api\V2\Endpoint\Skin\SkinEndpoint;
@@ -162,6 +163,10 @@ public function materials() {
return new MaterialEndpoint( $this );
}
+ public function pvp( $apiKey ) {
+ return new PvpEndpoint( $this, $apiKey );
+ }
+
public function quaggans() {
return new QuagganEndpoint( $this );
}
diff --git a/src/V2/Authentication/AuthenticatedEndpoint.php b/src/V2/Authentication/AuthenticatedEndpoint.php
index 2bd99cc..1a86c0a 100644
--- a/src/V2/Authentication/AuthenticatedEndpoint.php
+++ b/src/V2/Authentication/AuthenticatedEndpoint.php
@@ -3,6 +3,7 @@
namespace GW2Treasures\GW2Api\V2\Authentication;
trait AuthenticatedEndpoint {
+ /** @var string $apiKey */
protected $apiKey;
/**
diff --git a/src/V2/Endpoint/Pvp/GameEndpoint.php b/src/V2/Endpoint/Pvp/GameEndpoint.php
new file mode 100644
index 0000000..0ce1d88
--- /dev/null
+++ b/src/V2/Endpoint/Pvp/GameEndpoint.php
@@ -0,0 +1,33 @@
+apiKey = $apiKey;
+
+ parent::__construct($api);
+ }
+
+ /**
+ * The url of this endpoint.
+ *
+ * @return string
+ */
+ public function url() {
+ return 'v2/pvp/games';
+ }
+}
diff --git a/src/V2/Endpoint/Pvp/PvpEndpoint.php b/src/V2/Endpoint/Pvp/PvpEndpoint.php
new file mode 100644
index 0000000..252cd67
--- /dev/null
+++ b/src/V2/Endpoint/Pvp/PvpEndpoint.php
@@ -0,0 +1,45 @@
+apiKey = $apiKey;
+
+ parent::__construct($api);
+ }
+
+ /**
+ * The url of this endpoint.
+ *
+ * @return string
+ */
+ public function url() {
+ return 'v2/pvp';
+ }
+
+ /**
+ * @return GameEndpoint
+ */
+ public function games() {
+ return new GameEndpoint( $this->api, $this->apiKey );
+ }
+
+ /**
+ * @return StatsEndpoint
+ */
+ public function stats() {
+ return new StatsEndpoint($this->api, $this->apiKey);
+ }
+}
diff --git a/src/V2/Endpoint/Pvp/StatsEndpoint.php b/src/V2/Endpoint/Pvp/StatsEndpoint.php
new file mode 100644
index 0000000..4b82fbb
--- /dev/null
+++ b/src/V2/Endpoint/Pvp/StatsEndpoint.php
@@ -0,0 +1,28 @@
+request()->json();
+ }
+}
diff --git a/tests/V2/PvpEndpointTest.php b/tests/V2/PvpEndpointTest.php
new file mode 100644
index 0000000..8767f21
--- /dev/null
+++ b/tests/V2/PvpEndpointTest.php
@@ -0,0 +1,13 @@
+api()->pvp('API_KEY');
+
+ $this->assertEndpointUrl( 'v2/pvp', $endpoint );
+ $this->assertEndpointIsAuthenticated( $endpoint );
+
+ $this->assertInstanceOf( '\GW2Treasures\GW2Api\V2\Endpoint\Pvp\GameEndpoint', $endpoint->games() );
+ $this->assertInstanceOf( '\GW2Treasures\GW2Api\V2\Endpoint\Pvp\StatsEndpoint', $endpoint->stats() );
+ }
+}
diff --git a/tests/V2/PvpGameEndpointTest.php b/tests/V2/PvpGameEndpointTest.php
new file mode 100644
index 0000000..915666a
--- /dev/null
+++ b/tests/V2/PvpGameEndpointTest.php
@@ -0,0 +1,14 @@
+api()->pvp('API_KEY')->games();
+
+ $this->assertEndpointUrl( 'v2/pvp/games', $endpoint );
+ $this->assertEndpointIsAuthenticated( $endpoint );
+ $this->assertEndpointIsBulk( $endpoint );
+
+ $this->mockResponse( '["A9F9FD97-F114-4F97-B2CA-5E814DF0340E","4FDC931F-677F-4369-B20A-9FBB6A63B2B4"]' );
+ $this->assertContains( '4FDC931F-677F-4369-B20A-9FBB6A63B2B4', $endpoint->ids() );
+ }
+}
diff --git a/tests/V2/PvpStatsEndpointTest.php b/tests/V2/PvpStatsEndpointTest.php
new file mode 100644
index 0000000..7e744af
--- /dev/null
+++ b/tests/V2/PvpStatsEndpointTest.php
@@ -0,0 +1,13 @@
+api()->pvp('API_KEY')->stats();
+
+ $this->assertEndpointUrl( 'v2/pvp/stats', $endpoint );
+ $this->assertEndpointIsAuthenticated( $endpoint );
+
+ $this->mockResponse( '{"pvp_rank":57}' );
+ $this->assertEquals( 57, $endpoint->get()->pvp_rank );
+ }
+}