Skip to content

Commit

Permalink
chore: merge rc into main (#662)
Browse files Browse the repository at this point in the history
  • Loading branch information
ItsANameToo authored Feb 9, 2024
2 parents d96065b + a5f68d9 commit f9cf9fb
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 24 deletions.
3 changes: 3 additions & 0 deletions app/Data/Collections/CollectionDetailData.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace App\Data\Collections;

use App\Data\Token\TokenData;
use App\Enums\CurrencyCode;
use App\Models\Collection;
use App\Models\User;
Expand Down Expand Up @@ -45,6 +46,7 @@ public function __construct(
public ?Carbon $activityUpdatedAt,
public ?Carbon $activityUpdateRequestedAt,
public ?bool $isFetchingActivity,
public TokenData $token,
) {
}

Expand Down Expand Up @@ -77,6 +79,7 @@ public static function fromModel(Collection $collection, ?CurrencyCode $currency
activityUpdatedAt: $collection->activity_updated_at,
activityUpdateRequestedAt: $collection->activity_update_requested_at,
isFetchingActivity: $collection->is_fetching_activity,
token: TokenData::fromModel($collection->nativeToken()),
);
}
}
32 changes: 16 additions & 16 deletions app/Http/Client/Opensea/OpenseaPendingRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@

class OpenseaPendingRequest extends PendingRequest
{
protected string $apiUrl;

/**
* Create a new HTTP Client instance.
*
Expand All @@ -36,8 +34,6 @@ public function __construct(?Factory $factory = null)
{
parent::__construct($factory);

$this->apiUrl = config('services.opensea.endpoint');

$this->options = [
'headers' => [
'accept' => 'application/json',
Expand All @@ -52,9 +48,9 @@ public function __construct(?Factory $factory = null)
* @param array<mixed> $query
* @return Response
*/
public function get(string $url, $query = null, int $apiVersion = 1)
public function get(string $url, $query = null)
{
$url = sprintf('%sv%d/%s', $this->apiUrl, $apiVersion, $url);
$url = 'https://api.opensea.io/api/v2/'.ltrim($url, '/');

try {
return parent::get($url, $query);
Expand All @@ -78,10 +74,9 @@ public function nft(Chain $chain, string $address, string $identifier): ?Opensea
try {
$chain = OpenseaChain::fromChainId($chain->value)->value;

$response = self::get(
url: sprintf('chain/%s/contract/%s/nfts/%s', $chain, $address, $identifier),
apiVersion: 2
);
$response = $this->get(sprintf(
'/chain/%s/contract/%s/nfts/%s', $chain, $address, $identifier
));

return new OpenseaNftDetails($response->json('nft'));
} catch (ClientException $exception) {
Expand All @@ -101,7 +96,7 @@ public function getCollectionFloorPrice(string $collectionSlug): ?Web3Collection
try {
$response = $this->makeCollectionStatsRequest($collectionSlug);

$floorPrice = $response->json('total.floor_price');
$floorPrice = $response['total']['floor_price'] ?? null;

$currency = 'eth'; // OpenSea reports everything in ETH

Expand Down Expand Up @@ -134,21 +129,26 @@ public function getCollectionTotalVolume(Collection $collection): ?string
{
$response = $this->makeCollectionStatsRequest($collection->openSeaSlug());

$volume = $response->json('total.volume');
$volume = $response['total']['volume'] ?? null;

return $volume === null
? null
: CryptoUtils::convertToWei($volume, CryptoCurrencyDecimals::ETH->value);
}

private function makeCollectionStatsRequest(string $collectionSlug): Response
/**
* Make a request to OpenSea endpoint to retrieve the collection statistics, but cache the entire response as it can be reused by another job.
*
* @return array<mixed>
*/
private function makeCollectionStatsRequest(string $collectionSlug): array
{
// We cache for an hour because floor price job runs every hour...
// But we cache it just so that we can reuse the response for total volume without needing to hit an API endpoint again...
$ttl = now()->addMinutes(59);

return Cache::remember('opensea:collections-stats:'.$collectionSlug, $ttl, function () use ($collectionSlug) {
return self::get(sprintf('collections/%s/stats', $collectionSlug), apiVersion: 2);
});
return Cache::remember('opensea:collections-stats:'.$collectionSlug, $ttl, fn () => $this->get(
'/collections/'.$collectionSlug.'/stats'
)->json());
}
}
1 change: 0 additions & 1 deletion config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@

'opensea' => [
'key' => env('OPENSEA_API_KEY', null),
'endpoint' => env('OPENSEA_API_ENDPOINT', 'https://api.opensea.io/api/'),

// @see https://docs.opensea.io/v1.0/reference/api-overview#api-faqs
'rate' => [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { CollectionHeaderBottom } from "./CollectionHeaderBottom";
import * as useAuthOverlay from "@/Hooks/useAuthOverlay";
import CollectionDetailDataFactory from "@/Tests/Factories/Collections/CollectionDetailDataFactory";
import { render, screen, within } from "@/Tests/testing-library";
const collection = new CollectionDetailDataFactory().withCryptoCurrency("DARK").create({

const collection = new CollectionDetailDataFactory().withCryptoCurrency("DARK", 18).create({
floorPrice: (1 * 1e18).toString(),
volume: (123 * 1e18).toString(),
supply: 9999,
Expand Down Expand Up @@ -100,7 +101,7 @@ describe("CollectionHeaderBottom", () => {
const gridElement = screen.getByTestId("CollectionHeaderBottom__volume");

expect(within(gridElement).getByTestId("GridHeader__title")).toHaveTextContent("Volume");
expect(within(gridElement).getByTestId("GridHeader__value")).toHaveTextContent("0 DARK");
expect(within(gridElement).getByTestId("GridHeader__value")).toHaveTextContent("N/A");
});

it("should handle no supply value", () => {
Expand Down Expand Up @@ -156,6 +157,7 @@ describe("CollectionHeaderBottom", () => {
<CollectionHeaderBottom
collection={new CollectionDetailDataFactory().withCryptoCurrency(null).create({
floorPrice: (1 * 1e18).toString(),
volume: null,
})}
/>,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,12 @@ export const CollectionHeaderBottom = ({ collection }: CollectionHeaderBottomPro
className="lg:border-r lg:border-theme-secondary-300 lg:pl-0 lg:pr-6 dark:lg:border-theme-dark-700"
title={t("common.volume")}
value={
<FormatCrypto
value={collection.volume ?? "0"}
token={token}
/>
collection.volume !== null ? (
<FormatCrypto
value={collection.volume}
token={collection.token}
/>
) : null
}
/>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { faker } from "@faker-js/faker";
import CollectionNftDataFactory from "./CollectionNftDataFactory";
import ModelFactory from "@/Tests/Factories/ModelFactory";
import TokenDataFactory from "@/Tests/Factories/Token/TokenDataFactory";

export default class CollectionDetailDataFactory extends ModelFactory<App.Data.Collections.CollectionDetailData> {
protected factory(): App.Data.Collections.CollectionDetailData {
Expand All @@ -25,16 +26,21 @@ export default class CollectionDetailDataFactory extends ModelFactory<App.Data.C
volume: this.optional(faker.finance.amount(1 * 1e18, 25 * 1e18, 0)),
owners: this.optional(faker.datatype.number(1000)),
nftsCount: 0,
token: new TokenDataFactory().create(),
mintedAt: this.optional(faker.date.past().getTime()),
activityUpdatedAt: this.optional(faker.date.recent().toISOString()),
activityUpdateRequestedAt: this.optional(faker.date.recent().toISOString()),
isFetchingActivity: false,
};
}

withCryptoCurrency(currency: null | string): this {
withCryptoCurrency(currency: null | string, decimals?: number): this {
return this.state(() => ({
floorPriceCurrency: currency,
token: new TokenDataFactory().create({
symbol: currency ?? undefined,
decimals,
}),
}));
}

Expand Down
1 change: 1 addition & 0 deletions resources/types/generated.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ declare namespace App.Data.Collections {
activityUpdatedAt: string | null;
activityUpdateRequestedAt: string | null;
isFetchingActivity: boolean | null;
token: App.Data.Token.TokenData;
};
export type CollectionFeaturedData = {
id: number;
Expand Down

0 comments on commit f9cf9fb

Please sign in to comment.