Skip to content

Commit

Permalink
SDK-2 docs (#172)
Browse files Browse the repository at this point in the history
* add sponsoring docs

* add token docs

* add migration guide

* minor fixes in SDK migration part

* rename idOrAddress -> collectionId

---------

Co-authored-by: ashkuc <[email protected]>
  • Loading branch information
Maksandre and ashkuc authored Sep 10, 2024
1 parent 0edb4eb commit 00236eb
Show file tree
Hide file tree
Showing 7 changed files with 252 additions and 17 deletions.
1 change: 1 addition & 0 deletions docs/.vuepress/configs/sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export const sidebar: Record<string, SidebarConfig> = {
'/build/sdk/examples-nesting.md',
'/build/sdk/refungible.md',
'/build/sdk/sponsoring.md',
'/build/sdk/v2/migration.md'
]
},
{
Expand Down
4 changes: 2 additions & 2 deletions docs/build/sdk/v2/collections.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ await sdk.collection.setProperties({
### Now, let's query our collection and check its properties

```ts:no-line-numbers
const collection = await sdk.collection.get({idOrAddress: result.collectionId});
const collection = await sdk.collection.get({collectionId: result.collectionId});
console.log(collection.properties);
```
Expand Down Expand Up @@ -178,7 +178,7 @@ Every NFT token in the collection above could have three properties:
The SDK also specifies some additional token properties related to Unique Schema. Let's check them.

```ts:no-line-numbers
const collection = await sdk.collection.get({idOrAddress: collectionId})
const collection = await sdk.collection.get({collectionId})
console.log(collection.tokenPropertyPermissions);
```
Expand Down
135 changes: 135 additions & 0 deletions docs/build/sdk/v2/migration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# Migration from SDK V1 to SDK V2

This guide provides instructions on migrating from SDK V1 to SDK V2, highlighting key changes and improvements.


## Working with Balances

The method signature for retrieving balances has remained the same.

```ts
const alice = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY";

// V1
const balanceV1 = await sdkV1.balance.get({ address: alice });

// V2
const balanceV2 = await sdkV2.balance.get({ address: alice });
```

However, the format of the returned balance object has been simplified. All balances are now returned in raw format, leaving it to the application to format the value as needed.


```ts
// V1
console.log(balanceV1.availableBalance.amount); // 6994.40616

// V2
console.log(balanceV2.available); // 6994406160000000000000
```

For token transfers, SDK V2 requires the amount to be specified in raw format instead of a formatted number.


```ts
// V1
sdkV1.balance.transfer({ amount: 2.3, destination: alice });

// V2
sdkV2.balance.transfer({ amount: "2300000000000000000", to: alice });

// or
sdkV2.balance.transfer({ amount: 2.3, to: alice, isAmountInCoins: true });
```

## Working with Collections and Tokens


### Reading Collections

There are only minor changes in how collections are retrieved.

```ts
// V1
const collectionV1 = await sdkV1.collection.get({ collectionId: 665 });

// V2
const collectionV2 = await sdkV2.collection.get({ collectionId: 665 });

// or collection may be retrieved by address
const collectionV2_ = await sdkV2.collection.get({ collectionId: '0x17C4E6453cc49aaAAeaCA894E6D9683E00000299' });

```

### Reading Tokens

The method signature for retrieving tokens has no changes.

```ts
// V1
const tokenV1 = await sdkV1.token.get({ collectionId: 1, tokenId: 1 });

// V2
const tokenV2 = await sdkV2.token.get({ collectionId: 1, tokenId: 1 });

// collectionId may be replaced with collection address
const tokenV2_ = await sdkV2.token.get({ collectionId: '0x17C4e6453cC49AAaaEaCA894E6D9683e00000001', tokenId: 1 });
```

However, the response format has changed significantly. SDK V2 returns attributes in the Unique Schema V2 format, even for tokens created using Unique Schema V1.


Attributes in SDK V1:


```
"0": {
name: {
_: "gender",
},
value: {
en: "Female",
_: "Female",
},
isArray: false,
type: "string",
rawValue: 0,
isEnum: true,
},
"1": { ... }
```

Attributes in SDK V2:

```
[
{
trait_type: "gender",
value: "Female",
},
{ ... }
]
```

### Extrinsics

The extrinsic methods for transferring, burning, and nesting tokens remain unchanged.


## What If the Application Create Tokens in SDK-V1 Collections

If your application creates tokens in collections originally created with SDK-V1, you should continue using SDK-V1 for this purpose.

However, if your application also reads collections and tokens created by other users, it is recommended to use V2 methods for reading. This ensures that attributes are displayed correctly for new collections and tokens.


```ts
// Getting collections
sdkV1.collection.get({ collectionId: 1 }); // before
sdkV1.collection.getV2({ collectionId: 1 }); // after

// Getting tokens
sdkV1.token.get({ collectionId: 1, tokenId: 1 }); // before
sdkV1.token.getV2({ collectionId: 1, tokenId: 1 }); // after
```

2 changes: 2 additions & 0 deletions docs/build/sdk/v2/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ yarn add @unique-nft/sdk@alpha @unique-nft/sr25519

To begin using the Unique SDK, you need to import the required modules, set the base URL for the API, and optionally configure the default signer account.

You can find the list of public endpoints in the [reference section](../../../reference/sdk-endpoints.md).

<!-- TODO set production baseUrl -->
```typescript:no-line-numbers
import { UniqueChain } from "@unique-nft/sdk";
Expand Down
58 changes: 48 additions & 10 deletions docs/build/sdk/v2/sponsoring.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ You also need to know how to [mint and transfer NFTs](./tokens.md).
The process consists of two steps:

1. Set collection sponsor – only the collection owner or admin can do
2. Confirm sponsorship. The sponsor should confirm willingness to sponsor collection
2. Confirm sponsorship. The sponsor should confirm willingness to sponsor a collection

```ts:no-line-numbers
// At this point we assume you already have a minted collection and NFT
Expand All @@ -34,19 +34,57 @@ await sdk.collection.confirmSponsorship({collectionId});
```

At this point, every action with tokens of this collection, such as transfer or minting, will be sponsored by `account`.
<!--
TODO
Let's check that an account without native tokens can perform NFT transfer.

## Setting limits

You may want to set limits on sponsorship to prevent your sponsorship account from being drained. We already discussed how to set limits in the [collection section](collections.md#collection-limits). Let's take a closet look on sponsorship-related limits.

<!-- TODO setVariableMetadata is not the case anymore -->

```ts:no-line-numbers
await sdk.collection.create({
name: "Test",
description: "Test collection",
symbol: "TST",
limits: {
// The time interval in blocks defines once per how long a non-privileged user approve transaction can be sponsored.
sponsorApproveTimeout: 100,
// Defines how many blocks need to pass between setVariableMetadata transactions in order for them to be sponsored
sponsoredDataRateLimit: 100,
// The maximum byte size of custom token data that can be sponsored when tokens are minted in sponsored mode
sponsoredDataSize: 2048,
// The time interval in blocks that defines once per how long a non-privileged user transfer or mint transaction can be sponsored
sponsorTransferTimeout: 0,
},
});
```

## Let's check that an account without native tokens can transfer NFT

```ts:no-line-numbers
// generate a new account without OPL
const emptyAccount = Sr25519Account.fromUri(Sr25519Account.generateMnemonic());
// mint new token to `emptyAccount`
const {result} = await sdk.token.mintNFTs({collectionId, tokens: [
// mint new token directly to `emptyAccount`
const tokensCreation = await sdk.token.mintNFTs({collectionId, tokens: [
{owner: account.address}
]});
``` -->
const [token] = tokensCreation.result;
// emptyAccount makes transfer
await sdk.token.transfer(
{
to: alice.address,
collectionId,
tokenId: token.tokenId,
},
{ signerAddress: emptyAccount.address },
emptyAccount,
);
// Check alice is the new owner
const { owner } = await sdk.token.get({
collectionId: collectionId,
tokenId: token.tokenId,
});
```
59 changes: 54 additions & 5 deletions docs/build/sdk/v2/tokens.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ Now, let's have a look at the newly created token.

```ts:no-line-numbers
const nft = await sdk.token.get({
collectionIdOrAddress: result.collectionId,
collectionId: result.collectionId,
tokenId: 1
});
Expand Down Expand Up @@ -148,7 +148,7 @@ Let's make a quick recap of how it can be done. Below, we set mutability for tok
await sdk.collection.create({
...
tokenPropertyPermissions: [
// This is how we specify token properties mutability during the collection creation
// This is how we specify token properties' mutability during the collection creation
{key: 'A', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}},
...
Expand All @@ -164,6 +164,16 @@ await sdk.token.setProperties({
});
```

As far as deleted:

```ts:no-line-numbers
await sdk.token.deleteProperties({
collectionId,
tokenId,
keys: ['A'],
});
```

Attributes are part of `tokenData` property which is by default mutable for collection admin. You can override it during the collection creation.

The SDK provides the following method for attribute mutation:
Expand Down Expand Up @@ -206,6 +216,13 @@ const approvalTx = await sdk.token.approve({
spender: alice.address,
});
// Let's check token is approved
const { isApproved } = await sdk.token.getApproved({
collectionId,
tokenId,
spender: alice.address,
});
// Now, Alice can transfer approved token
const transferFromTx = await sdk.token.transfer(
{
Expand All @@ -217,7 +234,7 @@ const transferFromTx = await sdk.token.transfer(
{
signerAddress: alice.address,
},
// This transaction performed by Alice
// This transaction made by Alice
alice,
);
```
Expand All @@ -233,6 +250,31 @@ await sdk.token.burn({
});
```

If token is approved for account this account can be burn token from:

```ts:no-line-numbers
// Approve token for alice
const approvalTx = await sdk.token.approve({
collectionId,
tokenId,
spender: alice.address,
});
// alice burns token directly without transfer
await sdk.token.burn(
{
collectionId,
tokenId: token1.tokenId,
amount: 1,
from: account.address,
},
{ signerAddress: alice.address },
alice,
);
```



<!-- TODO add burn from docs -->

## Nesting
Expand All @@ -254,6 +296,15 @@ In the example above, `token1` will be nested to `token2`. This means:
- Topmost token owner (real owner) of `token2` will be the owner of `token1`
- if `token2` is transferred to a different account, this new account becomes the topmost owner for `token1`

Let's get token's topmost owner:

```ts:no-line-numbers
const { topmostOwner } = await sdk.token.get({
collectionId: collectionId,
tokenId: token1.tokenId,
});
```

The topmost token owner can `unnest` tokens. In the example below, `token1` will be transferred from the `token2` address back to the topmost owner.

```ts:no-line-numbers
Expand All @@ -267,5 +318,3 @@ In Unique Network every collection and token have unique ID. At the same time th
The concept of collections and token addresses is particularly useful when working with [smart contracts](../../evm/index.md).
:::

<!-- TODO Add docs regarding getting topmostOwner -->

10 changes: 10 additions & 0 deletions docs/reference/sdk-endpoints.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Public endpoints

## SDK-V2

| | Endpoint |
|----------|----------|
| Unique | https://rest.unique.network/v2/unique |
| Quartz | https://rest.unique.network/v2/quartz |
| Opal | https://rest.unique.network/v2/opal |

## SDK-V1

| | Endpoint |
|----------|----------|
| Unique | https://rest.unique.network/unique/v1 |
Expand Down

0 comments on commit 00236eb

Please sign in to comment.