Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support pinning of solana tokens #16963

Merged
merged 1 commit into from
Mar 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,8 @@ public GetNftSolanaMetadataContext(Runnable responseCompleteCallback) {
}

@Override
public void call(String tokenMetadata, Integer errorCode, String errorMessage) {
public void call(
String tokenUrl, String tokenMetadata, Integer errorCode, String errorMessage) {
this.tokenMetadata = tokenMetadata;
this.errorCode = errorCode;
this.errorMessage = errorMessage;
Expand Down
75 changes: 59 additions & 16 deletions components/brave_wallet/browser/brave_wallet_pin_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ const char kErrorMessage[] = "error_message";
const char kAssetUrlListKey[] = "cids";

namespace {

// Solana NFTs don't have token_id
const char kEmptyTokenIdPart[] = "*";
const char kNftPart[] = "nft";
/**
* Service name used in prefs for local pinning service.
Expand Down Expand Up @@ -266,7 +267,8 @@ void ContentTypeChecker::OnHeadersFetched(
// static
bool BraveWalletPinService::IsTokenSupportedForPinning(
const mojom::BlockchainTokenPtr& token) {
return token->is_erc721;
return token->is_erc721 ||
(token->is_nft && token->coin == mojom::CoinType::SOL);
}

/**
Expand Down Expand Up @@ -381,14 +383,16 @@ absl::optional<std::string> BraveWalletPinService::GetTokenPrefPath(
if (base::ContainsOnlyChars(token->contract_address, ".")) {
return absl::nullopt;
}
if (base::ContainsOnlyChars(token->token_id, ".")) {
if (!token->token_id.empty() &&
base::ContainsOnlyChars(token->token_id, ".")) {
return absl::nullopt;
}
DCHECK(!base::ContainsOnlyChars(token->chain_id, "."));
return base::StrCat({kNftPart, ".", service.value_or(kLocalService), ".",
base::NumberToString(static_cast<int>(token->coin)), ".",
token->chain_id, ".", token->contract_address, ".",
token->token_id});
return base::StrCat(
{kNftPart, ".", service.value_or(kLocalService), ".",
base::NumberToString(static_cast<int>(token->coin)), ".",
token->chain_id, ".", token->contract_address, ".",
(token->token_id.empty() ? kEmptyTokenIdPart : token->token_id)});
}

// static
Expand All @@ -407,7 +411,7 @@ mojom::BlockchainTokenPtr BraveWalletPinService::TokenFromPrefPath(
token->coin = static_cast<mojom::CoinType>(coin);
token->chain_id = parts.at(3);
token->contract_address = parts.at(4);
token->token_id = parts.at(5);
token->token_id = parts.at(5) == kEmptyTokenIdPart ? "" : parts.at(5);
token->is_nft = true;
return token;
}
Expand Down Expand Up @@ -519,7 +523,6 @@ void BraveWalletPinService::AddPin(mojom::BlockchainTokenPtr token,
std::move(callback).Run(false, std::move(pin_error));
return;
}

auto token_status = GetTokenStatus(service, token);
if (token_status &&
token_status->code == mojom::TokenPinStatusCode::STATUS_PINNED) {
Expand All @@ -529,11 +532,21 @@ void BraveWalletPinService::AddPin(mojom::BlockchainTokenPtr token,
return;
}

json_rpc_service_->GetERC721Metadata(
token->contract_address, token->token_id, token->chain_id,
base::BindOnce(&BraveWalletPinService::OnTokenMetaDataReceived,
weak_ptr_factory_.GetWeakPtr(), service,
std::move(callback), token.Clone()));
if (token->is_erc721) {
json_rpc_service_->GetERC721Metadata(
token->contract_address, token->token_id, token->chain_id,
base::BindOnce(&BraveWalletPinService::OnTokenMetaDataReceived,
weak_ptr_factory_.GetWeakPtr(), service,
std::move(callback), token.Clone()));
} else if (token->is_nft && token->coin == mojom::CoinType::SOL) {
json_rpc_service_->GetSolTokenMetadata(
token->contract_address,
base::BindOnce(&BraveWalletPinService::OnSolTokenMetaDataReceived,
weak_ptr_factory_.GetWeakPtr(), service,
std::move(callback), token.Clone()));
} else {
NOTREACHED();
}
}

void BraveWalletPinService::RemovePin(
Expand Down Expand Up @@ -591,6 +604,27 @@ void BraveWalletPinService::OnPinsRemoved(absl::optional<std::string> service,
std::move(callback).Run(result, nullptr);
}

void BraveWalletPinService::OnSolTokenMetaDataReceived(
absl::optional<std::string> service,
AddPinCallback callback,
mojom::BlockchainTokenPtr token,
const std::string& token_url,
const std::string& result,
mojom::SolanaProviderError error,
const std::string& error_message) {
if (error != mojom::SolanaProviderError::kSuccess) {
auto pin_error = mojom::PinError::New(
mojom::WalletPinServiceErrorCode::ERR_FETCH_METADATA_FAILED,
"Failed to obtain token metadata");
SetTokenStatus(service, token,
mojom::TokenPinStatusCode::STATUS_PINNING_FAILED, pin_error);
std::move(callback).Run(false, std::move(pin_error));
return;
}

ProcessTokenMetadata(service, token, token_url, result, std::move(callback));
}

void BraveWalletPinService::OnTokenMetaDataReceived(
absl::optional<std::string> service,
AddPinCallback callback,
Expand All @@ -609,6 +643,15 @@ void BraveWalletPinService::OnTokenMetaDataReceived(
return;
}

ProcessTokenMetadata(service, token, token_url, result, std::move(callback));
}

void BraveWalletPinService::ProcessTokenMetadata(
const absl::optional<std::string>& service,
const mojom::BlockchainTokenPtr& token,
const std::string& token_url,
const std::string& result,
AddPinCallback callback) {
auto metadata_cid = ExtractCID(token_url);
if (!metadata_cid) {
auto pin_error = mojom::PinError::New(
Expand Down Expand Up @@ -665,8 +708,8 @@ void BraveWalletPinService::OnTokenMetaDataReceived(
content_type_checker_->CheckContentTypeSupported(
ipfs_image_url.value(),
base::BindOnce(&BraveWalletPinService::OnContentTypeChecked,
weak_ptr_factory_.GetWeakPtr(), std::move(service),
std::move(token), std::move(cids), std::move(callback)));
weak_ptr_factory_.GetWeakPtr(), service, token.Clone(),
std::move(cids), std::move(callback)));
}

void BraveWalletPinService::OnContentTypeChecked(
Expand Down
14 changes: 14 additions & 0 deletions components/brave_wallet/browser/brave_wallet_pin_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,12 @@ class BraveWalletPinService : public KeyedService,
mojom::BlockchainTokenPtr,
absl::optional<bool> result);

void ProcessTokenMetadata(const absl::optional<std::string>& service,
const mojom::BlockchainTokenPtr& token,
const std::string& token_url,
const std::string& result,
AddPinCallback callback);

void OnTokenMetaDataReceived(absl::optional<std::string> service,
AddPinCallback callback,
mojom::BlockchainTokenPtr token,
Expand All @@ -180,6 +186,14 @@ class BraveWalletPinService : public KeyedService,
AddPinCallback callback,
absl::optional<bool> result);

void OnSolTokenMetaDataReceived(absl::optional<std::string> service,
AddPinCallback callback,
mojom::BlockchainTokenPtr token,
const std::string& token_url,
const std::string& result,
mojom::SolanaProviderError error,
const std::string& error_message);

// ipfs::IpfsServiceObserver
void OnIpfsLaunched(bool result, int64_t pid) override;
void OnIpfsShutdown() override;
Expand Down
Loading