# Collection NFT

Definition: allow user create a NFT Collection with different Contract(token) address.

- allow user mint the NFTs with collection
- when collection deployed, NFTs will have different Contract(token) address in layer1
- Loopring own collection on L2, allow user to view/edit their Collection information.
- will soon enable the "Import Collection" to manage legacy NFTs

***

## Step 1. get Account

```ts
const {accInfo} = await LoopringAPI.exchangeAPI.getAccount({
	owner: LOOPRING_EXPORTED_ACCOUNT.address,
});
console.log("accInfo:", accInfo);
``` 

***

## Step 2. get eddsaKey

```ts
const eddsaKey = await signatureKeyPairMock(accInfo);
console.log("eddsaKey:", eddsaKey.sk);
```

***

## Step 3. get apiKey

```ts
const {apiKey} = await LoopringAPI.userAPI.getUserApiKey(
	{
		accountId: accInfo.accountId,
	},
	eddsaKey.sk
);
console.log("apiKey:", apiKey);

```

***

## Step 4. get storageId

```ts
const storageId = await LoopringAPI.userAPI.getNextStorageId(
	{
		accountId: accInfo.accountId,
		sellTokenId: TOKEN_INFO.tokenMap[ "LRC" ].tokenId, // same as maxFee tokenId
	},
	apiKey
);
```

***

## Step 5. get collection Information(tokenAddress)

```ts
const collectionRes = await LoopringAPI.userAPI
	.getUserOwenCollection({
			owner: accInfo.owner,
			tokenAddress: mockData.nftTokenAddress,
			isMintable: true
		},
		apiKey
	)
if ((collectionRes &&
	((collectionRes as sdk.RESULT_INFO).code ||
		(collectionRes as sdk.RESULT_INFO).message)) || !collectionRes.collections.length
) {
	console.log("Collection is disable to mint ");
	throw "Collection is disable to mint ";
}

const collectionMeta = (collectionRes as any).collections[ 0 ] as CollectionMeta;

const counterFactualNftInfo: NFTCounterFactualInfo = {
	nftOwner: accInfo.owner,
	nftFactory: collectionMeta.nftFactory ?? sdk.NFTFactory_Collection[ sdk.ChainId.GOERLI ],
	nftBaseUri: collectionMeta.baseUri,
};

```

***

## Step 6. fee

```ts
const fee = await LoopringAPI.userAPI.getNFTOffchainFeeAmt(
	{
		accountId: accInfo.accountId,
		tokenAddress: collectionMeta.contractAddress,
		requestType: sdk.OffchainNFTFeeReqType.NFT_MINT,
	},
	apiKey
);
```

***

## Step7. Mint

```ts
const response = await LoopringAPI.userAPI.submitNFTMint({
	request: {
		exchange: LOOPRING_EXPORTED_ACCOUNT.exchangeAddress,
		minterId: accInfo.accountId,
		minterAddress: accInfo.owner,
		toAccountId: accInfo.accountId,
		toAddress: accInfo.owner,
		nftType: 0,
		tokenAddress: collectionMeta.contractAddress,
		nftId: LOOPRING_EXPORTED_ACCOUNT.nftId, //nftId.toString(16),
		amount: "1",
		validUntil: LOOPRING_EXPORTED_ACCOUNT.validUntil,
		storageId: storageId.offchainId ?? 9,
		maxFee: {
			tokenId: TOKEN_INFO.tokenMap[ "LRC" ].tokenId,
			amount: fee.fees[ "LRC" ].fee ?? "9400000000000000000",
		},
		counterFactualNftInfo,
		royaltyPercentage: 5,
		forceToMint: true, // suggest use as false, for here is just for run test
	},
	web3,
	chainId: sdk.ChainId.GOERLI,
	walletType: sdk.ConnectorNames.Unknown,
	eddsaKey: eddsaKey.sk,
	apiKey: apiKey,
});
```

____

### ps: Mint with legacy nftFactory

<font color='red'>! Mint NFT from this way has no collection information at deploy contract(tokenAdress is
unique)</font>
***

#### Step 1,2,3,4 is same logic

#### Step 5. get tokenAddress

```ts
const counterFactualNftInfo = {
	nftOwner: accInfo.owner,
	nftFactory: sdk.NFTFactory[ sdk.ChainId.GOERLI ],
	nftBaseUri: "",
};
const nftTokenAddress =
	LoopringAPI.nftAPI.computeNFTAddress(counterFactualNftInfo)
		.tokenAddress || "";
console.log("nftTokenAddress", nftTokenAddress);
```

***

#### Step 6. get fee

```ts
 const fee = await LoopringAPI.userAPI.getNFTOffchainFeeAmt(
	{
		accountId: accInfo.accountId,
		tokenAddress: nftTokenAddress,
		requestType: sdk.OffchainNFTFeeReqType.NFT_MINT,
	},
	apiKey
);
```

#### Step 7. Mint

```ts

const response = await LoopringAPI.userAPI.submitNFTMint({
	request: {
		exchange: LOOPRING_EXPORTED_ACCOUNT.exchangeAddress,
		minterId: accInfo.accountId,
		minterAddress: accInfo.owner,
		toAccountId: accInfo.accountId,
		toAddress: accInfo.owner,
		nftType: 0,
		tokenAddress: nftTokenAddress,
		nftId: LOOPRING_EXPORTED_ACCOUNT.nftId, //nftId.toString(16),
		amount: "1",
		validUntil: LOOPRING_EXPORTED_ACCOUNT.validUntil,
		storageId: storageId.offchainId ?? 9,
		maxFee: {
			tokenId: TOKEN_INFO.tokenMap[ "LRC" ].tokenId,
			amount: fee.fees[ "LRC" ].fee ?? "9400000000000000000",
		},
		royaltyPercentage: 5,
		counterFactualNftInfo,
		forceToMint: true, // suggest use as false, for here is just for run test
	},
	web3,
	chainId: sdk.ChainId.GOERLI,
	walletType: sdk.ConnectorNames.Unknown,
	eddsaKey: eddsaKey.sk,
	apiKey: apiKey,
});
```
