Skip to content

Commit f7d5174

Browse files
authored
Merge pull request #171 from 0xsequence/feature/marketplace
Marketplace Collectibles Intent
2 parents d96d4de + d1e24be commit f7d5174

25 files changed

Lines changed: 1267 additions & 11 deletions
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:bc35eb2d43a47427d30aba0196f9eac90d089dd3abca319528c5d25c83510d0d
3-
size 72364642
2+
oid sha256:aa8c65256ddbe91768b2d942e120a636fe6a977c626c4cf866c433a7eef91444
3+
size 66789159

Plugins/SequencePlugin/Source/SequencePlugin/Private/Indexer/Indexer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ FString UIndexer::HostName(const int64 ChainID)
3636
Hostname.Append("-indexer.sequence.app");
3737
return Hostname;
3838
}
39+
//
3940

4041
/*
4142
Here we construct a post request and parse out a response if valid.
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
// Copyright 2024 Horizon Blockchain Games Inc. All rights reserved.
2+
3+
#include "Marketplace/Marketplace.h"
4+
#include "Util/Async.h"
5+
#include "JsonObjectConverter.h"
6+
#include "Http.h"
7+
#include "Util/SequenceSupport.h"
8+
#include "ConfigFetcher.h"
9+
#include "HttpManager.h"
10+
11+
12+
UMarketplace::UMarketplace(){}
13+
14+
FString UMarketplace::Url(const int64& ChainID, const FString& EndPoint) const
15+
{
16+
FString Out_URL = HostName(ChainID);
17+
Out_URL.Append(this->PATH);
18+
19+
if (EndPoint.Len() > 0)
20+
{
21+
Out_URL.Append(EndPoint);
22+
}
23+
return Out_URL;
24+
}
25+
26+
FString UMarketplace::HostName(const int64 ChainID)
27+
{
28+
FString Hostname = "https://";
29+
Hostname.Append("marketplace-api.sequence.app/");
30+
Hostname.Append(USequenceSupport::GetNetworkNameForUrl(ChainID));
31+
return Hostname;
32+
}
33+
34+
void UMarketplace::HTTPPost(const int64& ChainID, const FString& Endpoint, const FString& Args, const TSuccessCallback<FString>& OnSuccess, const FFailureCallback& OnFailure) const
35+
{
36+
const FString RequestURL = this->Url(ChainID, Endpoint);
37+
38+
const TSharedRef<IHttpRequest> HTTP_Post_Req = FHttpModule::Get().CreateRequest();
39+
40+
FString AccessKey = UConfigFetcher::GetConfigVar("ProjectAccessKey");
41+
if (AccessKey.IsEmpty())
42+
{
43+
UE_LOG(LogTemp, Error, TEXT("AccessKey is empty! Failed to set HTTP header."));
44+
return;
45+
}
46+
47+
HTTP_Post_Req->SetVerb("POST");
48+
HTTP_Post_Req->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
49+
HTTP_Post_Req->SetHeader(TEXT("Accept"), TEXT("application/json"));
50+
51+
52+
HTTP_Post_Req->SetHeader(TEXT("X-Access-Key"), *AccessKey);
53+
HTTP_Post_Req->SetTimeout(30);
54+
HTTP_Post_Req->SetURL(RequestURL);
55+
HTTP_Post_Req->SetContentAsString(Args);
56+
57+
UE_LOG(LogTemp, Display, TEXT("body: %s"), *Args);
58+
UE_LOG(LogTemp, Display, TEXT("request: %s"), *RequestURL);
59+
60+
61+
HTTP_Post_Req->OnProcessRequestComplete().BindLambda([OnSuccess, OnFailure](const FHttpRequestPtr& Request, FHttpResponsePtr Response, const bool bWasSuccessful)
62+
{
63+
if (bWasSuccessful)
64+
{
65+
const FString Content = Response->GetContentAsString();
66+
UE_LOG(LogTemp, Display, TEXT("Response: %s"), *Content);
67+
OnSuccess(Content);
68+
}
69+
else
70+
{
71+
if (Request.IsValid() && Response.IsValid())
72+
{
73+
const FString ErrorMessage = Response->GetContentAsString();
74+
UE_LOG(LogTemp, Error, TEXT("Request failed: %s"), *ErrorMessage);
75+
OnFailure(FSequenceError(RequestFail, "Request failed: " + ErrorMessage));
76+
}
77+
else
78+
{
79+
UE_LOG(LogTemp, Error, TEXT("Request failed: Invalid Request Pointer"));
80+
OnFailure(FSequenceError(RequestFail, "Request failed: Invalid Request Pointer"));
81+
}
82+
}
83+
});
84+
85+
// Process the request
86+
HTTP_Post_Req->ProcessRequest();
87+
}
88+
89+
void UMarketplace::GetCollectibleListings(const int64 ChainID, const FSeqGetCollectiblesWithLowestListingsArgs& Args, TSuccessCallback<FSeqGetCollectiblesWithLowestListingsReturn> OnSuccess, const FFailureCallback& OnFailure)
90+
{
91+
const FString Endpoint = "ListCollectiblesWithLowestListing";
92+
93+
HTTPPost(ChainID, Endpoint, BuildArgs<FSeqGetCollectiblesWithLowestListingsArgs>(Args), [this, OnSuccess](const FString& Content)
94+
{
95+
const FSeqGetCollectiblesWithLowestListingsReturn Response = this->BuildResponse<FSeqGetCollectiblesWithLowestListingsReturn>(Content);
96+
OnSuccess(Response);
97+
}, OnFailure);
98+
}
99+
100+
template < typename T> FString UMarketplace::BuildArgs(T StructIn)
101+
{
102+
FString Result = "[FAILED TO PARSE]";
103+
if (StructIn.customGetter)
104+
{
105+
Result = StructIn.GetArgs();
106+
}
107+
else
108+
{
109+
if (!FJsonObjectConverter::UStructToJsonObjectString<T>(StructIn, Result))
110+
{
111+
UE_LOG(LogTemp, Display, TEXT("Failed to convert specified UStruct to a json object\n"));
112+
}
113+
}
114+
return Result;
115+
}
116+
117+
//generic
118+
template<typename T> T UMarketplace::BuildResponse(const FString Text)
119+
{
120+
//Take the FString and convert it to a JSON object first!
121+
TSharedPtr<FJsonObject> JSON_Step;
122+
//Then take the json object we make and convert it to a USTRUCT of type T then we return that!
123+
T Ret_Struct;
124+
125+
if (!FJsonSerializer::Deserialize(TJsonReaderFactory<>::Create(Text), JSON_Step))
126+
{
127+
UE_LOG(LogTemp, Display, TEXT("Failed to convert String: %s to Json object"), *Text);
128+
return T();
129+
}
130+
//this next line with throw an exception in null is used as an entry in json attributes! we need to remove null entries
131+
if (Ret_Struct.customConstructor)
132+
{//use the custom constructor!
133+
Ret_Struct.construct(*JSON_Step.Get());
134+
}
135+
else
136+
{//use unreal parsing!
137+
if (!FJsonObjectConverter::JsonObjectToUStruct<T>(JSON_Step.ToSharedRef(), &Ret_Struct))
138+
{
139+
UE_LOG(LogTemp, Display, TEXT("Failed to convert Json Object: %s to USTRUCT of type T"), *Text);
140+
return T();
141+
}
142+
}
143+
Ret_Struct.Setup(*JSON_Step.Get());//now for the edge cases we will manually inject the data where it needs to be!
144+
return Ret_Struct;
145+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright 2024 Horizon Blockchain Games Inc. All rights reserved.
2+
3+
#pragma once
4+
5+
#include "CoreMinimal.h"
6+
#include "Util/Async.h"
7+
#include "Marketplace/Structs/Struct_Data.h"
8+
#include "Marketplace.generated.h"
9+
10+
UCLASS()
11+
class SEQUENCEPLUGIN_API UMarketplace : public UObject
12+
{
13+
GENERATED_BODY()
14+
15+
private:
16+
17+
const FString PATH = "/rpc/Marketplace/";
18+
19+
//private functions
20+
21+
/*
22+
Creates the URL from a given chainID and endpoint
23+
*/
24+
FString Url(const int64& ChainID, const FString& EndPoint) const;
25+
26+
/*
27+
Returns the host name
28+
*/
29+
static FString HostName(int64 ChainID);
30+
31+
public:
32+
/*
33+
Used to send an HTTPPost req to a the sequence app
34+
@return the content of the post response
35+
*/
36+
void HTTPPost(const int64& ChainID, const FString& Endpoint, const FString& Args, const TSuccessCallback<FString>& OnSuccess, const FFailureCallback& OnFailure) const;
37+
38+
39+
//public functions
40+
41+
/*
42+
Here we take in text and convert it to a Struct of type T if possible
43+
@return a Struct of type T
44+
45+
NOTE: Because unreal doesn't support nested TArrays and TMaps I had to use special implementations
46+
for some data structures inorder for them to parse properly
47+
*/
48+
template < typename T > T BuildResponse(FString Text);
49+
50+
/*
51+
Here we take in a struct and convert it straight into a json object String
52+
@Param (T) Struct_in the struct we are converting to a json object string
53+
@Return the JSON Object String
54+
*/
55+
template < typename T> FString BuildArgs(T StructIn);
56+
57+
UMarketplace();
58+
59+
void GetCollectibleListings(const int64 ChainID, const FSeqGetCollectiblesWithLowestListingsArgs& Args, TSuccessCallback<FSeqGetCollectiblesWithLowestListingsReturn> OnSuccess, const FFailureCallback& OnFailure);
60+
61+
62+
63+
};
64+

Plugins/SequencePlugin/Source/SequencePlugin/Private/Util/SequenceSupport.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,18 @@ FString USequenceSupport::StringListToParsableString(TArray<FString> StringData)
416416
return Ret;
417417
}
418418

419+
TArray<TSharedPtr<FJsonValue>> USequenceSupport::StringListToJsonArray(const TArray<FString>& StringData)
420+
{
421+
TArray<TSharedPtr<FJsonValue>> JsonArray;
422+
for (const FString& String : StringData)
423+
{
424+
// Add each string to the JSON array as a FJsonValueString
425+
JsonArray.Add(MakeShareable(new FJsonValueString(String)));
426+
}
427+
return JsonArray;
428+
}
429+
430+
419431
FString USequenceSupport::Int64ListToSimpleString(TArray<int64> IntData)
420432
{
421433
FString Ret = "[";

Plugins/SequencePlugin/Source/SequencePlugin/Public/Indexer/Structs/SeqGetTokenBalancesReturn.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ struct SEQUENCEPLUGIN_API FSeqGetTokenBalancesReturn
5252
const TSharedPtr<FJsonObject>* itemObj;
5353
if ((*lst)[i].Get()->TryGetObject(itemObj))
5454
{
55-
balances[i].setup(*itemObj->Get());
55+
balances[i].Setup(*itemObj->Get());
5656
}
5757
}
5858
}

Plugins/SequencePlugin/Source/SequencePlugin/Public/Indexer/Structs/SeqTokenBalance.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,12 @@ struct SEQUENCEPLUGIN_API FSeqTokenBalance
6363
/*
6464
* Used for handling edge cases with unreal's parsing
6565
*/
66-
void setup(FJsonObject json_in)
66+
void Setup(FJsonObject json_in)
6767
{
6868
const TSharedPtr<FJsonObject> *item;
6969
if (json_in.TryGetObjectField(TEXT("tokenMetaData"), item))
7070
{
71-
tokenMetaData.setup(*item->Get());
71+
tokenMetaData.Setup(*item->Get());
7272
}
7373
}//setup
7474
};

Plugins/SequencePlugin/Source/SequencePlugin/Public/Indexer/Structs/SeqTokenMetaData.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,30 @@ struct SEQUENCEPLUGIN_API FSeqTokenMetaData
9595
/*
9696
* Used to handle Edge cases with UE's json parsing
9797
*/
98-
void setup(FJsonObject json_in)
98+
void Setup(FJsonObject json_in)
9999
{//the json object we expect here will be a mirror of what is above EXCEPT we will be snipping out what we need!
100100

101+
FString tokenIdString;
102+
if (json_in.TryGetStringField(TEXT("tokenId"), tokenIdString))
103+
{
104+
tokenId = FCString::Atoi64(*tokenIdString);
105+
}
106+
FString decimalsString;
107+
if (json_in.TryGetStringField(TEXT("decimals"), decimalsString))
108+
{
109+
decimals = FCString::Atoi64(*decimalsString);
110+
}
111+
112+
json_in.TryGetStringField(TEXT("name"), name);
113+
json_in.TryGetStringField(TEXT("description"), description);
114+
json_in.TryGetStringField(TEXT("image"), image);
115+
json_in.TryGetStringField(TEXT("video"), video);
116+
json_in.TryGetStringField(TEXT("audio"), audio);
117+
json_in.TryGetStringField(TEXT("image_data"), image_data);
118+
json_in.TryGetStringField(TEXT("background_color"), background_color);
119+
json_in.TryGetStringField(TEXT("animation_url"), animation_url);
120+
json_in.TryGetStringField(TEXT("external_url"), external_url);
121+
101122
attributes.Empty();
102123
properties.Empty();
103124

Plugins/SequencePlugin/Source/SequencePlugin/Public/Indexer/Structs/SeqTokenSupply.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ struct SEQUENCEPLUGIN_API FSeqTokenSupply
4646
const TSharedPtr<FJsonObject>* itemObj;
4747
if (json_in.TryGetObjectField(TEXT("tokenMetaData"), itemObj))
4848
{
49-
tokenMetaData.setup(*itemObj->Get());
49+
tokenMetaData.Setup(*itemObj->Get());
5050
}
5151
}
5252
};

Plugins/SequencePlugin/Source/SequencePlugin/Public/Indexer/Structs/SeqTxnTransfer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ struct SEQUENCEPLUGIN_API FSeqTxnTransfer
8686
const TSharedPtr<FJsonObject>* srcEntryPtr;
8787
if (srcEntry->Get()->TryGetObject(srcEntryPtr))
8888
{
89-
tokenMetaData.Find(i)->setup(*srcEntryPtr->Get());
89+
tokenMetaData.Find(i)->Setup(*srcEntryPtr->Get());
9090
}//valid src Object
9191
}//Matching Key!
9292
}//For loop through all source keys

0 commit comments

Comments
 (0)