diff --git a/.gitignore b/.gitignore index b3db3e2..c0d8a16 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +application.yml HELP.md .gradle build/ diff --git a/build.gradle b/build.gradle index a58b4dc..6b0a4e1 100644 --- a/build.gradle +++ b/build.gradle @@ -31,10 +31,16 @@ dependencies { testImplementation 'org.springframework.boot:spring-boot-starter-test' // swagger + implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0") + + //web3j + implementation 'org.web3j:core:4.9.6' + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0' // s3 implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE' + } tasks.named('test') { diff --git a/src/main/java/zerobibim/flory/domain/contract/NFT.java b/src/main/java/zerobibim/flory/domain/contract/NFT.java new file mode 100644 index 0000000..5705323 --- /dev/null +++ b/src/main/java/zerobibim/flory/domain/contract/NFT.java @@ -0,0 +1,428 @@ +package zerobibim.flory.domain.contract; + +import io.reactivex.Flowable; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.web3j.abi.EventEncoder; +import org.web3j.abi.TypeReference; +import org.web3j.abi.datatypes.Address; +import org.web3j.abi.datatypes.Bool; +import org.web3j.abi.datatypes.Event; +import org.web3j.abi.datatypes.Function; +import org.web3j.abi.datatypes.Type; +import org.web3j.abi.datatypes.Utf8String; +import org.web3j.abi.datatypes.generated.Uint256; +import org.web3j.crypto.Credentials; +import org.web3j.ens.EnsResolver; +import org.web3j.protocol.Web3j; +import org.web3j.protocol.Web3jService; +import org.web3j.protocol.core.DefaultBlockParameter; +import org.web3j.protocol.core.RemoteFunctionCall; +import org.web3j.protocol.core.methods.request.EthFilter; +import org.web3j.protocol.core.methods.response.BaseEventResponse; +import org.web3j.protocol.core.methods.response.Log; +import org.web3j.protocol.core.methods.response.TransactionReceipt; +import org.web3j.tx.Contract; +import org.web3j.tx.TransactionManager; +import org.web3j.tx.gas.ContractGasProvider; +import org.web3j.tx.gas.StaticGasProvider; + +/** + *

Auto generated code. + *

Do not modify! + *

Please use the web3j command line tools, + * or the org.web3j.codegen.SolidityFunctionWrapperGenerator in the + * codegen module to update. + * + *

Generated with web3j version 1.5.0. + */ +@SuppressWarnings("rawtypes") +public class NFT extends Contract { + public static final String BINARY = "Bin file was not provided"; + + public static final String FUNC_CANNOT_TRANSFER_TO_ZERO_ADDRESS = "CANNOT_TRANSFER_TO_ZERO_ADDRESS"; + + public static final String FUNC_NOT_CURRENT_OWNER = "NOT_CURRENT_OWNER"; + + public static final String FUNC_APPROVE = "approve"; + + public static final String FUNC_BALANCEOF = "balanceOf"; + + public static final String FUNC_GETAPPROVED = "getApproved"; + + public static final String FUNC_ISAPPROVEDFORALL = "isApprovedForAll"; + + public static final String FUNC_MINT = "mint"; + + public static final String FUNC_NAME = "name"; + + public static final String FUNC_OWNER = "owner"; + + public static final String FUNC_OWNEROF = "ownerOf"; + + public static final String FUNC_safeTransferFrom = "safeTransferFrom"; + + public static final String FUNC_SETAPPROVALFORALL = "setApprovalForAll"; + + public static final String FUNC_SUPPORTSINTERFACE = "supportsInterface"; + + public static final String FUNC_SYMBOL = "symbol"; + + public static final String FUNC_TOKENURI = "tokenURI"; + + public static final String FUNC_TRANSFERFROM = "transferFrom"; + + public static final String FUNC_TRANSFEROWNERSHIP = "transferOwnership"; + + public static final Event APPROVAL_EVENT = new Event("Approval", + Arrays.>asList(new TypeReference

(true) {}, new TypeReference
(true) {}, new TypeReference(true) {})); + ; + + public static final Event APPROVALFORALL_EVENT = new Event("ApprovalForAll", + Arrays.>asList(new TypeReference
(true) {}, new TypeReference
(true) {}, new TypeReference() {})); + ; + + public static final Event OWNERSHIPTRANSFERRED_EVENT = new Event("OwnershipTransferred", + Arrays.>asList(new TypeReference
(true) {}, new TypeReference
(true) {})); + ; + + public static final Event TRANSFER_EVENT = new Event("Transfer", + Arrays.>asList(new TypeReference
(true) {}, new TypeReference
(true) {}, new TypeReference(true) {})); + ; + + @Deprecated + protected NFT(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) { + super(BINARY, contractAddress, web3j, credentials, gasPrice, gasLimit); + } + + @Deprecated + protected NFT(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { + super(BINARY, contractAddress, web3j, transactionManager, gasPrice, gasLimit); + } + + + + public static List getApprovalEvents(TransactionReceipt transactionReceipt) { + List valueList = staticExtractEventParametersWithLog(APPROVAL_EVENT, transactionReceipt); + ArrayList responses = new ArrayList(valueList.size()); + for (Contract.EventValuesWithLog eventValues : valueList) { + ApprovalEventResponse typedResponse = new ApprovalEventResponse(); + typedResponse.log = eventValues.getLog(); + typedResponse._owner = (String) eventValues.getIndexedValues().get(0).getValue(); + typedResponse._approved = (String) eventValues.getIndexedValues().get(1).getValue(); + typedResponse._tokenId = (BigInteger) eventValues.getIndexedValues().get(2).getValue(); + responses.add(typedResponse); + } + return responses; + } + + public static ApprovalEventResponse getApprovalEventFromLog(Log log) { + Contract.EventValuesWithLog eventValues = staticExtractEventParametersWithLog(APPROVAL_EVENT, log); + ApprovalEventResponse typedResponse = new ApprovalEventResponse(); + typedResponse.log = log; + typedResponse._owner = (String) eventValues.getIndexedValues().get(0).getValue(); + typedResponse._approved = (String) eventValues.getIndexedValues().get(1).getValue(); + typedResponse._tokenId = (BigInteger) eventValues.getIndexedValues().get(2).getValue(); + return typedResponse; + } + + + + public Flowable approvalEventFlowable(EthFilter filter) { + return web3j.ethLogFlowable(filter).map(log -> getApprovalEventFromLog(log)); + } + + public Flowable approvalEventFlowable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) { + EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress()); + filter.addSingleTopic(EventEncoder.encode(APPROVAL_EVENT)); + return approvalEventFlowable(filter); + } + + public static List getApprovalForAllEvents(TransactionReceipt transactionReceipt) { + List valueList = staticExtractEventParametersWithLog(APPROVALFORALL_EVENT, transactionReceipt); + ArrayList responses = new ArrayList(valueList.size()); + for (Contract.EventValuesWithLog eventValues : valueList) { + ApprovalForAllEventResponse typedResponse = new ApprovalForAllEventResponse(); + typedResponse.log = eventValues.getLog(); + typedResponse._owner = (String) eventValues.getIndexedValues().get(0).getValue(); + typedResponse._operator = (String) eventValues.getIndexedValues().get(1).getValue(); + typedResponse._approved = (Boolean) eventValues.getNonIndexedValues().get(0).getValue(); + responses.add(typedResponse); + } + return responses; + } + + public static ApprovalForAllEventResponse getApprovalForAllEventFromLog(Log log) { + Contract.EventValuesWithLog eventValues = staticExtractEventParametersWithLog(APPROVALFORALL_EVENT, log); + ApprovalForAllEventResponse typedResponse = new ApprovalForAllEventResponse(); + typedResponse.log = log; + typedResponse._owner = (String) eventValues.getIndexedValues().get(0).getValue(); + typedResponse._operator = (String) eventValues.getIndexedValues().get(1).getValue(); + typedResponse._approved = (Boolean) eventValues.getNonIndexedValues().get(0).getValue(); + return typedResponse; + } + + public Flowable approvalForAllEventFlowable(EthFilter filter) { + return web3j.ethLogFlowable(filter).map(log -> getApprovalForAllEventFromLog(log)); + } + + public Flowable approvalForAllEventFlowable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) { + EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress()); + filter.addSingleTopic(EventEncoder.encode(APPROVALFORALL_EVENT)); + return approvalForAllEventFlowable(filter); + } + + public static List getOwnershipTransferredEvents(TransactionReceipt transactionReceipt) { + List valueList = staticExtractEventParametersWithLog(OWNERSHIPTRANSFERRED_EVENT, transactionReceipt); + ArrayList responses = new ArrayList(valueList.size()); + for (Contract.EventValuesWithLog eventValues : valueList) { + OwnershipTransferredEventResponse typedResponse = new OwnershipTransferredEventResponse(); + typedResponse.log = eventValues.getLog(); + typedResponse.previousOwner = (String) eventValues.getIndexedValues().get(0).getValue(); + typedResponse.newOwner = (String) eventValues.getIndexedValues().get(1).getValue(); + responses.add(typedResponse); + } + return responses; + } + + public static OwnershipTransferredEventResponse getOwnershipTransferredEventFromLog(Log log) { + Contract.EventValuesWithLog eventValues = staticExtractEventParametersWithLog(OWNERSHIPTRANSFERRED_EVENT, log); + OwnershipTransferredEventResponse typedResponse = new OwnershipTransferredEventResponse(); + typedResponse.log = log; + typedResponse.previousOwner = (String) eventValues.getIndexedValues().get(0).getValue(); + typedResponse.newOwner = (String) eventValues.getIndexedValues().get(1).getValue(); + return typedResponse; + } + + public Flowable ownershipTransferredEventFlowable(EthFilter filter) { + return web3j.ethLogFlowable(filter).map(log -> getOwnershipTransferredEventFromLog(log)); + } + + public Flowable ownershipTransferredEventFlowable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) { + EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress()); + filter.addSingleTopic(EventEncoder.encode(OWNERSHIPTRANSFERRED_EVENT)); + return ownershipTransferredEventFlowable(filter); + } + + public static List getTransferEvents(TransactionReceipt transactionReceipt) { + List valueList = staticExtractEventParametersWithLog(TRANSFER_EVENT, transactionReceipt); + ArrayList responses = new ArrayList(valueList.size()); + for (Contract.EventValuesWithLog eventValues : valueList) { + TransferEventResponse typedResponse = new TransferEventResponse(); + typedResponse.log = eventValues.getLog(); + typedResponse._from = (String) eventValues.getIndexedValues().get(0).getValue(); + typedResponse._to = (String) eventValues.getIndexedValues().get(1).getValue(); + typedResponse._tokenId = (BigInteger) eventValues.getIndexedValues().get(2).getValue(); + responses.add(typedResponse); + } + return responses; + } + + public static TransferEventResponse getTransferEventFromLog(Log log) { + Contract.EventValuesWithLog eventValues = staticExtractEventParametersWithLog(TRANSFER_EVENT, log); + TransferEventResponse typedResponse = new TransferEventResponse(); + typedResponse.log = log; + typedResponse._from = (String) eventValues.getIndexedValues().get(0).getValue(); + typedResponse._to = (String) eventValues.getIndexedValues().get(1).getValue(); + typedResponse._tokenId = (BigInteger) eventValues.getIndexedValues().get(2).getValue(); + return typedResponse; + } + + public Flowable transferEventFlowable(EthFilter filter) { + return web3j.ethLogFlowable(filter).map(log -> getTransferEventFromLog(log)); + } + + public Flowable transferEventFlowable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) { + EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress()); + filter.addSingleTopic(EventEncoder.encode(TRANSFER_EVENT)); + return transferEventFlowable(filter); + } + + public RemoteFunctionCall CANNOT_TRANSFER_TO_ZERO_ADDRESS() { + final Function function = new Function(FUNC_CANNOT_TRANSFER_TO_ZERO_ADDRESS, + Arrays.asList(), + Arrays.>asList(new TypeReference() {})); + return executeRemoteCallSingleValueReturn(function, String.class); + } + + public RemoteFunctionCall NOT_CURRENT_OWNER() { + final Function function = new Function(FUNC_NOT_CURRENT_OWNER, + Arrays.asList(), + Arrays.>asList(new TypeReference() {})); + return executeRemoteCallSingleValueReturn(function, String.class); + } + + public RemoteFunctionCall approve(String _approved, BigInteger _tokenId) { + final Function function = new Function( + FUNC_APPROVE, + Arrays.asList(new org.web3j.abi.datatypes.Address(160, _approved), + new org.web3j.abi.datatypes.generated.Uint256(_tokenId)), + Collections.>emptyList()); + return executeRemoteCallTransaction(function); + } + + public RemoteFunctionCall balanceOf(String _owner) { + final Function function = new Function(FUNC_BALANCEOF, + Arrays.asList(new org.web3j.abi.datatypes.Address(160, _owner)), + Arrays.>asList(new TypeReference() {})); + return executeRemoteCallSingleValueReturn(function, BigInteger.class); + } + + public RemoteFunctionCall getApproved(BigInteger _tokenId) { + final Function function = new Function(FUNC_GETAPPROVED, + Arrays.asList(new org.web3j.abi.datatypes.generated.Uint256(_tokenId)), + Arrays.>asList(new TypeReference
() {})); + return executeRemoteCallSingleValueReturn(function, String.class); + } + + public RemoteFunctionCall isApprovedForAll(String _owner, String _operator) { + final Function function = new Function(FUNC_ISAPPROVEDFORALL, + Arrays.asList(new org.web3j.abi.datatypes.Address(160, _owner), + new org.web3j.abi.datatypes.Address(160, _operator)), + Arrays.>asList(new TypeReference() {})); + return executeRemoteCallSingleValueReturn(function, Boolean.class); + } + + public RemoteFunctionCall mint(String _to, BigInteger _tokenId, String _uri) { + final Function function = new Function( + FUNC_MINT, + Arrays.asList(new org.web3j.abi.datatypes.Address(160, _to), + new org.web3j.abi.datatypes.generated.Uint256(_tokenId), + new org.web3j.abi.datatypes.Utf8String(_uri)), + Collections.>emptyList()); + return executeRemoteCallTransaction(function); + } + + public RemoteFunctionCall name() { + final Function function = new Function(FUNC_NAME, + Arrays.asList(), + Arrays.>asList(new TypeReference() {})); + return executeRemoteCallSingleValueReturn(function, String.class); + } + + public RemoteFunctionCall owner() { + final Function function = new Function(FUNC_OWNER, + Arrays.asList(), + Arrays.>asList(new TypeReference
() {})); + return executeRemoteCallSingleValueReturn(function, String.class); + } + + public RemoteFunctionCall ownerOf(BigInteger _tokenId) { + final Function function = new Function(FUNC_OWNEROF, + Arrays.asList(new org.web3j.abi.datatypes.generated.Uint256(_tokenId)), + Arrays.>asList(new TypeReference
() {})); + return executeRemoteCallSingleValueReturn(function, String.class); + } + + public RemoteFunctionCall safeTransferFrom(String _from, String _to, BigInteger _tokenId) { + final Function function = new Function( + FUNC_safeTransferFrom, + Arrays.asList(new org.web3j.abi.datatypes.Address(160, _from), + new org.web3j.abi.datatypes.Address(160, _to), + new org.web3j.abi.datatypes.generated.Uint256(_tokenId)), + Collections.>emptyList()); + return executeRemoteCallTransaction(function); + } + + public RemoteFunctionCall safeTransferFrom(String _from, String _to, BigInteger _tokenId, byte[] _data) { + final Function function = new Function( + FUNC_safeTransferFrom, + Arrays.asList(new org.web3j.abi.datatypes.Address(160, _from), + new org.web3j.abi.datatypes.Address(160, _to), + new org.web3j.abi.datatypes.generated.Uint256(_tokenId), + new org.web3j.abi.datatypes.DynamicBytes(_data)), + Collections.>emptyList()); + return executeRemoteCallTransaction(function); + } + + public RemoteFunctionCall setApprovalForAll(String _operator, Boolean _approved) { + final Function function = new Function( + FUNC_SETAPPROVALFORALL, + Arrays.asList(new org.web3j.abi.datatypes.Address(160, _operator), + new org.web3j.abi.datatypes.Bool(_approved)), + Collections.>emptyList()); + return executeRemoteCallTransaction(function); + } + + public RemoteFunctionCall supportsInterface(byte[] _interfaceID) { + final Function function = new Function(FUNC_SUPPORTSINTERFACE, + Arrays.asList(new org.web3j.abi.datatypes.generated.Bytes4(_interfaceID)), + Arrays.>asList(new TypeReference() {})); + return executeRemoteCallSingleValueReturn(function, Boolean.class); + } + + public RemoteFunctionCall symbol() { + final Function function = new Function(FUNC_SYMBOL, + Arrays.asList(), + Arrays.>asList(new TypeReference() {})); + return executeRemoteCallSingleValueReturn(function, String.class); + } + + public RemoteFunctionCall tokenURI(BigInteger _tokenId) { + final Function function = new Function(FUNC_TOKENURI, + Arrays.asList(new org.web3j.abi.datatypes.generated.Uint256(_tokenId)), + Arrays.>asList(new TypeReference() {})); + return executeRemoteCallSingleValueReturn(function, String.class); + } + + public RemoteFunctionCall transferFrom(String _from, String _to, BigInteger _tokenId) { + final Function function = new Function( + FUNC_TRANSFERFROM, + Arrays.asList(new org.web3j.abi.datatypes.Address(160, _from), + new org.web3j.abi.datatypes.Address(160, _to), + new org.web3j.abi.datatypes.generated.Uint256(_tokenId)), + Collections.>emptyList()); + return executeRemoteCallTransaction(function); + } + + public RemoteFunctionCall transferOwnership(String _newOwner) { + final Function function = new Function( + FUNC_TRANSFEROWNERSHIP, + Arrays.asList(new org.web3j.abi.datatypes.Address(160, _newOwner)), + Collections.>emptyList()); + return executeRemoteCallTransaction(function); + } + + @Deprecated + public static NFT load(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) { + return new NFT(contractAddress, web3j, credentials, gasPrice, gasLimit); + } + @Deprecated + public static NFT load(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { + return new NFT(contractAddress, web3j, transactionManager, gasPrice, gasLimit); + } + + + public static class ApprovalEventResponse extends BaseEventResponse { + public String _owner; + + public String _approved; + + public BigInteger _tokenId; + } + + public static class ApprovalForAllEventResponse extends BaseEventResponse { + public String _owner; + + public String _operator; + + public Boolean _approved; + } + + public static class OwnershipTransferredEventResponse extends BaseEventResponse { + public String previousOwner; + + public String newOwner; + } + + public static class TransferEventResponse extends BaseEventResponse { + public String _from; + + public String _to; + + public BigInteger _tokenId; + } +} \ No newline at end of file diff --git a/src/main/java/zerobibim/flory/domain/contract/controller/NftController.java b/src/main/java/zerobibim/flory/domain/contract/controller/NftController.java new file mode 100644 index 0000000..70a11e9 --- /dev/null +++ b/src/main/java/zerobibim/flory/domain/contract/controller/NftController.java @@ -0,0 +1,32 @@ +package zerobibim.flory.domain.contract.controller; + +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import zerobibim.flory.domain.contract.NFT; +import zerobibim.flory.domain.contract.NFT.*; + +import java.math.BigInteger; + +@RestController +@RequestMapping("/api/nft") +public class NftController { + private final NFT nft; + + @Autowired + public NftController(NFT nft) { + this.nft = nft; + } + + // Define your API endpoints here + @PostMapping("/mint") + public String mintToken(@RequestParam String to, @RequestParam BigInteger tokenId, @RequestParam String uri) { + try { + // Mint a new token + return "Token minted successfully"; + } catch (Exception e) { + // Handle exceptions appropriately (e.g., log the error) + return "Error minting token: " + e.getMessage(); + } + } +} diff --git a/src/main/java/zerobibim/flory/domain/contract/dto/NFTRequestDto.java b/src/main/java/zerobibim/flory/domain/contract/dto/NFTRequestDto.java new file mode 100644 index 0000000..f9e1aa2 --- /dev/null +++ b/src/main/java/zerobibim/flory/domain/contract/dto/NFTRequestDto.java @@ -0,0 +1,16 @@ +package zerobibim.flory.domain.contract.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +public class NFTRequestDto { + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class MemberNFTInfo { + private String walletAddress; + private String ipfsUrl; + } + +} diff --git a/src/main/java/zerobibim/flory/domain/contract/service/IPFSPhotoService.java b/src/main/java/zerobibim/flory/domain/contract/service/IPFSPhotoService.java new file mode 100644 index 0000000..17ff022 --- /dev/null +++ b/src/main/java/zerobibim/flory/domain/contract/service/IPFSPhotoService.java @@ -0,0 +1,38 @@ +package zerobibim.flory.domain.contract.service; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import okhttp3.*; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.io.IOException; + +@Service +public class IPFSPhotoService { + + @Value("${pinata.JWT}") + private String PINATE_JWT; + public String insertIpfs(Long memberPhotoId) throws IOException { + + OkHttpClient client = new OkHttpClient(); + + MediaType mediaType = MediaType.parse("application/json"); + RequestBody body = RequestBody.create(mediaType, "{\"pinataContent\":{\"name\": \"" +memberPhoto.getName() + "\"" + + ",\"description\":\"" + memberPhoto.getDescription() + "\",\"image\":\"" + memberPhoto.getImageUrl() + "\"}}"); + + Request request = new Request.Builder() + .url("https://api.pinata.cloud/pinning/pinJSONToIPFS") + .post(body) + .addHeader("Authorization", PINATA_JWT) + .addHeader("accept", "application/json") + .addHeader("content-type", "application/json") + .build(); + + ResponseBody responsebody = client.newCall(request).execute().body(); + ObjectMapper mapper = new ObjectMapper(); + assert responsebody != null; + JsonNode jsonNode = mapper.readTree(responsebody.byteStream()); + return jsonNode.get("IpfsHash").asText(); + } +} diff --git a/src/main/java/zerobibim/flory/domain/contract/service/Web3jService.java b/src/main/java/zerobibim/flory/domain/contract/service/Web3jService.java new file mode 100644 index 0000000..75e72a6 --- /dev/null +++ b/src/main/java/zerobibim/flory/domain/contract/service/Web3jService.java @@ -0,0 +1,34 @@ +package zerobibim.flory.domain.contract.service; + +import org.springframework.beans.factory.annotation.Value; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.web3j.abi.EventEncoder; +import org.web3j.abi.datatypes.generated.Uint256; +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.DefaultBlockParameter; +import org.web3j.protocol.core.DefaultBlockParameterName; +import org.web3j.protocol.core.methods.response.*; +import zerobibim.flory.domain.contract.NFT; +import zerobibim.flory.domain.contract.dto.NFTRequestDto; + +import java.math.BigInteger; +import java.util.Arrays; +import java.util.concurrent.ExecutionException; + +@Slf4j +@RequiredArgsConstructor +@Service("web3jService") +public class Web3jService { + + private final NFT nft; + + public TransactionReceipt nftCreate(NFTRequestDto.MemberNFTInfo memberNFTInfo) throws Exception { + + return nft.mint(memberNFTInfo.getWalletAddress(), "ipfs://" +) + .sendAsync() + .get(); + } + +} \ No newline at end of file diff --git a/src/main/java/zerobibim/flory/global/config/Web3jConfig.java b/src/main/java/zerobibim/flory/global/config/Web3jConfig.java new file mode 100644 index 0000000..c107af1 --- /dev/null +++ b/src/main/java/zerobibim/flory/global/config/Web3jConfig.java @@ -0,0 +1,47 @@ +package zerobibim.flory.global.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.web3j.crypto.Credentials; +import org.web3j.crypto.ECKeyPair; +import org.web3j.protocol.Web3j; +import org.web3j.protocol.http.HttpService; +import org.web3j.tx.Contract; +import org.web3j.tx.gas.StaticGasProvider; +import zerobibim.flory.domain.contract.NFT; + +import java.math.BigInteger; + +@Configuration +public class Web3jConfig { + + @Value("${infura.API_URL}") + private String INFURA_API_URL; + + @Value("${metamask.PRIVATE_KEY}") + private String PRIVATE_KEY; + + @Value("${metamask.CONTRACT_ADDRESS}") + private String CONTRACT_ADDRESS; + + @Bean + public Web3j web3j() { + return Web3j.build(new HttpService(INFURA_API_URL)); + } + + @Bean + public Credentials credentials() { + BigInteger privateKeyInBT = new BigInteger(PRIVATE_KEY, 16); + return Credentials.create(ECKeyPair.create(privateKeyInBT)); + } + + @Bean + public NFT nft() { + BigInteger gasPrice = Contract.GAS_PRICE; + BigInteger gasLimit = Contract.GAS_LIMIT; + //StaticGasProvider gasProvider = new StaticGasProvider(gasPrice, gasLimit); + + return NFT.load(CONTRACT_ADDRESS, web3j(), credentials(), gasPrice, gasLimit); + } +} \ No newline at end of file