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

Added examples and docs for nft mint, send, burn #532

Merged
merged 30 commits into from
Jun 26, 2023
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
8359013
added nft mint, send, burn
anistark Jun 3, 2023
a1fc8e4
removed walletdb
anistark Jun 3, 2023
d7787a5
removed lock file
anistark Jun 3, 2023
2c25e0f
added example-walletdb to gitignore
anistark Jun 3, 2023
2cb5285
added example-walletdb to gitignore
anistark Jun 3, 2023
067fbc4
Update bindings/nodejs/examples/how_tos/nfts/burn_nft.ts
anistark Jun 4, 2023
ccb8b47
Update bindings/nodejs/examples/how_tos/nfts/burn_nft.ts
anistark Jun 4, 2023
fb9c527
Update bindings/nodejs/examples/how_tos/nfts/send_nft.ts
anistark Jun 4, 2023
fe53c09
Update bindings/nodejs/examples/how_tos/nfts/send_nft.ts
anistark Jun 4, 2023
025aa1b
Update bindings/python/examples/how_tos/nfts/mint_nft.py
anistark Jun 4, 2023
51d0e34
Update bindings/python/examples/how_tos/nfts/send_nft.py
anistark Jun 4, 2023
5fb29fb
Update documentation/sdk/docs/how_tos/nfts/01_mint_nft.mdx
anistark Jun 4, 2023
11c0580
Update documentation/sdk/docs/how_tos/nfts/02_send_nft.mdx
anistark Jun 4, 2023
ff344f8
Update documentation/sdk/docs/how_tos/nfts/03_burn_nft.mdx
anistark Jun 4, 2023
d1465ee
Update documentation/sdk/docs/how_tos/nfts/03_burn_nft.mdx
anistark Jun 4, 2023
1780573
Update sdk/examples/how_tos/nfts/burn_nft.rs
anistark Jun 4, 2023
1c5ea71
Update sdk/examples/how_tos/nfts/mint_nft.rs
anistark Jun 4, 2023
56509a2
renamed files. formatted. [wip] output same for 3
anistark Jun 7, 2023
dd01fda
senderAddress removed. testing only.
anistark Jun 7, 2023
80dce56
nft owner only in address unlock
anistark Jun 7, 2023
743c2e8
node and rust outputs match. python pending
anistark Jun 8, 2023
9d5ff33
removing commented code
anistark Jun 12, 2023
281ecef
Merge branch 'develop' into docs/sdk-nft
anistark Jun 22, 2023
ce23e28
removed example files
anistark Jun 22, 2023
d430033
updated rust examples to updated sync
anistark Jun 22, 2023
0e82469
removed comment
anistark Jun 22, 2023
9cc8d1a
added back account sync
anistark Jun 22, 2023
41e6e4d
formatted
anistark Jun 23, 2023
ccfeb81
removed yarn.lock
anistark Jun 26, 2023
fba44ca
Apply suggestions from code review
thibault-martinez Jun 26, 2023
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
**/target
*.pyc
**/*.rs.bk
yarn.lock
anistark marked this conversation as resolved.
Show resolved Hide resolved

# IDE files
.vscode
Expand All @@ -20,6 +21,7 @@ online_walletdb
/pingdb
/pongdb
backup
example-walletdb

# JSON files
address.json
Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,47 @@
// Copyright 2023 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { getUnlockedWallet } from './common';
import { Wallet } from '@iota/sdk';

// In this example we will burn an existing nft output.
//
// Make sure that `example.stronghold` and `example.walletdb` already exist by
// running the `how_tos/accounts-and-addresses/create-wallet` example!
//
// Rename `.env.example` to `.env` first, then run
// yarn run-example ./wallet/14-burn-nft.ts
// yarn run-example ./how_tos/nfts/burn_nft.ts
async function run() {
try {
if (!process.env.STRONGHOLD_PASSWORD) {
throw new Error(
'.env STRONGHOLD_PASSWORD is undefined, see .env.example',
);
}

// Create the wallet
const wallet = await getUnlockedWallet();
const wallet = new Wallet({
storagePath: process.env.WALLET_DB_PATH,
});

// Get the account we generated with `01-create-wallet`
const account = await wallet.getAccount('Alice');
const account = await wallet.getAccount(
`${process.env.ACCOUNT_ALIAS_1}`,
);

// May want to ensure the account is synced before sending a transaction.
let balance = await account.sync();

if (balance.nfts.length == 0) {
throw new Error(`No NFT available in account 'Alice'`);
throw new Error(
`No NFT available in account '${process.env.ACCOUNT_ALIAS_1}'`,
);
}
// Get the first nft
const nftId = balance.nfts[0];

console.log(`Balance BEFORE burning:\n`, balance);

// Burn a native token
// Burn an NFT
const transaction = await account
.prepareBurnNft(nftId)
.then((prepared) => prepared.send());
Expand All @@ -41,7 +53,7 @@ async function run() {
transaction.transactionId,
);
console.log(
`Transaction included: ${process.env.EXPLORER_URL}/block/${blockId}`,
`Block included: ${process.env.EXPLORER_URL}/block/${blockId}`,
);
console.log(`Burned NFT ${nftId}`);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ import {
SenderFeature,
utf8ToHex,
Utils,
Wallet,
} from '@iota/sdk';

Thoralf-M marked this conversation as resolved.
Show resolved Hide resolved
import { getUnlockedWallet } from './common';

// The owner address of the first NFT we'll mint
const NFT1_OWNER_ADDRESS =
'rms1qpszqzadsym6wpppd6z037dvlejmjuke7s24hm95s9fg9vpua7vluaw60xu';
Expand All @@ -25,30 +24,32 @@ const NFT1_TAG = utf8ToHex('some NFT tag');
// The base coin amount we sent with the second NFT
const NFT2_AMOUNT = '1000000';

// In this example we will mint an NFT in two different ways.
// In this example we will mint a new nft.
//
// Make sure that `example.stronghold` and `example.walletdb` already exist by
// running the `how_tos/accounts-and-addresses/create-wallet` example!
//
// Rename `.env.example` to `.env` first, then run
// yarn run-example ./wallet/10-mint-nft.ts
// yarn run-example ./how_tos/nfts/mint_nft.ts
async function run() {
try {
// Create the wallet
const wallet = await getUnlockedWallet();
if (!process.env.STRONGHOLD_PASSWORD) {
throw new Error(
'.env STRONGHOLD_PASSWORD is undefined, see .env.example',
);
}

// Get the account we generated with `01-create-wallet`
const account = await wallet.getAccount('Alice');
const wallet = new Wallet({
storagePath: process.env.WALLET_DB_PATH,
});

// May want to ensure the account is synced before sending a transaction.
let balance = await account.sync();
const nftsBefore = balance.nfts;
const account = await wallet.getAccount(
`${process.env.ACCOUNT_ALIAS_1}`,
);

// We send from the first address in the account.
const senderAddress = (await account.addresses())[0].address;

console.log('Sending the minting transaction for NFT 1...');

const params: MintNftParams = {
address: NFT1_OWNER_ADDRESS, // Remove or change to senderAddress to send to self
sender: senderAddress,
Expand All @@ -68,7 +69,7 @@ async function run() {
);

console.log(
`Transaction included: ${process.env.EXPLORER_URL}/block/${blockId}`,
`Block included: ${process.env.EXPLORER_URL}/block/${blockId}`,
);
console.log('Minted NFT 1');

Expand All @@ -80,16 +81,16 @@ async function run() {
amount: NFT2_AMOUNT,
nftId: '0x0000000000000000000000000000000000000000000000000000000000000000',
unlockConditions: [
new AddressUnlockCondition(new Ed25519Address(hexAddress)),
new AddressUnlockCondition(
new Ed25519Address(Utils.bech32ToHex(NFT1_OWNER_ADDRESS)),
),
],
immutableFeatures: [
new IssuerFeature(new Ed25519Address(hexAddress)),
],
features: [new SenderFeature(new Ed25519Address(hexAddress))],
});

console.log('Sending minting transaction for NFT 2...');

transaction = await account.sendOutputs([output]);
console.log(`Transaction sent: ${transaction.transactionId}`);

Expand All @@ -99,25 +100,16 @@ async function run() {
);

console.log(
`Transaction included: ${process.env.EXPLORER_URL}/block/${blockId}`,
`Block included: ${process.env.EXPLORER_URL}/block/${blockId}`,
);

console.log('Minted NFT 2');

// Ensure the account is synced after minting.
balance = await account.sync();
const nftsAfter = balance.nfts;

console.log('New owned NFTs:', nftsBefore.length, nftsAfter.length);
for (const nftId of nftsAfter) {
if (!nftsBefore.includes(nftId)) {
console.log(`- ${nftId}`);
}
}
await account.sync();
} catch (error) {
console.log('Error: ', error);
console.error('Error: ', error);
}
process.exit(0);
}

run();
run().then(() => process.exit());
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
// Copyright 2023 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { SendNftParams } from '@iota/sdk';
import { SendNftParams, Wallet } from '@iota/sdk';

import { getUnlockedWallet } from './common';

// The address to send the tokens to
// The address to send the NFT to
const RECV_ADDRESS =
'rms1qpszqzadsym6wpppd6z037dvlejmjuke7s24hm95s9fg9vpua7vluaw60xu';

Expand All @@ -15,14 +13,23 @@ const RECV_ADDRESS =
// running the `how_tos/accounts-and-addresses/create-wallet` example!
//
// Rename `.env.example` to `.env` first, then run
// yarn run-example ./wallet/08-send-nft.ts
// yarn run-example ./how_tos/nfts/send_nft.ts
async function run() {
try {
// Create the wallet
const wallet = await getUnlockedWallet();
if (!process.env.STRONGHOLD_PASSWORD) {
throw new Error(
'.env STRONGHOLD_PASSWORD is undefined, see .env.example',
);
}

const wallet = new Wallet({
storagePath: process.env.WALLET_DB_PATH,
});

// Get the account we generated with `01-create-wallet`
const account = await wallet.getAccount('Alice');
const account = await wallet.getAccount(
`${process.env.ACCOUNT_ALIAS_1}`,
);

// May want to ensure the account is synced before sending a transaction.
const balance = await account.sync();
Expand All @@ -40,8 +47,6 @@ async function run() {
},
];

console.log(`Sending NFT '${nftId}' to '${RECV_ADDRESS}'...`);

// Send the full NFT output to the specified address
const transaction = await account
.prepareSendNft(outputs)
Expand All @@ -55,7 +60,7 @@ async function run() {
);

console.log(
`Transaction included: ${process.env.EXPLORER_URL}/block/${blockId}`,
`Block included: ${process.env.EXPLORER_URL}/block/${blockId}`,
);

// To send an NFT with expiration unlock condition prepareOutput() can be used like this:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@
# In this example we will burn an NFT
wallet = Wallet('./alice-database')

account = wallet.get_account('Alice')

# Sync account with the node
response = account.sync()

if 'STRONGHOLD_PASSWORD' not in os.environ:
raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example")

wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"])

account = wallet.get_account('Alice')

# Sync account with the node
response = account.sync()

# TODO: replace with your own values.
nftId = "0xf95f4d5344217a2ba19a6c19a47f97d267edf8c4d76a7b8c08072ad35acbebbe"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,19 @@

wallet = Wallet('./alice-database')

account = wallet.get_account('Alice')

# Sync account with the node
response = account.sync()

if 'STRONGHOLD_PASSWORD' not in os.environ:
raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example")

wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"])

account = wallet.get_account('Alice')

# Sync account with the node
response = account.sync()

outputs = [{
"immutableMetadata": utf8_to_hex("some immutable nft metadata"),
}]

transaction = account.prepare_mint_nfts(outputs).send()

print(f'Block sent: {os.environ["EXPLORER_URL"]}/block/{transaction["blockId"]}')
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,20 @@

wallet = Wallet('./alice-database')

account = wallet.get_account('Alice')

# Sync account with the node
response = account.sync()

if 'STRONGHOLD_PASSWORD' not in os.environ:
raise Exception(".env STRONGHOLD_PASSWORD is undefined, see .env.example")

wallet.set_stronghold_password(os.environ["STRONGHOLD_PASSWORD"])

account = wallet.get_account('Alice')

# Sync account with the node
response = account.sync()

outputs = [{
"address": "rms1qpszqzadsym6wpppd6z037dvlejmjuke7s24hm95s9fg9vpua7vluaw60xu",
"nftId": "0x17f97185f80fa56eab974de6b7bbb80fa812d4e8e37090d166a0a41da129cebc",
}]

transaction = account.prepare_send_nft(outputs).send()

print(f'Block sent: {os.environ["EXPLORER_URL"]}/block/{transaction["blockId"]}')
50 changes: 50 additions & 0 deletions documentation/sdk/docs/how_tos/nfts/burn_nft.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
title: Burn NFT
description: 'How to burn NFT'
image: /img/logo/iota_mark_light.png
keywords:
- how to
- burn
- nft
- nodejs
- python
- rust
---

import CodeBlock from '@theme/CodeBlock';
import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
import RustCode from "!!raw-loader!../../../../../sdk/examples/how_tos/nfts/burn_nft.rs";
import NodejsCode from "!!raw-loader!../../../../../bindings/nodejs/examples/how_tos/nfts/burn_nft.ts";
import PythonCode from "!!raw-loader!../../../../../bindings/python/examples/how_tos/nfts/burn_nft.py";

This How-To will show you how to burn an NFT.


## Code Example

<Tabs groupId="language">
<TabItem value="rust" label="Rust">
<CodeBlock className="language-rust">
{RustCode}
</CodeBlock>
</TabItem>
<TabItem value="nodejs" label="Nodejs">
<CodeBlock className="language-typescript">
{NodejsCode}
</CodeBlock>
</TabItem>
<TabItem value="python" label="Python">
<CodeBlock className="language-python">
{PythonCode}
</CodeBlock>
</TabItem>
</Tabs>

## Expected Output

```bash
Transaction sent: 0xed7955f0c2d1a1e267b61b0a1859b58a9b5112385c18feae1a198f3a9992d19e
Block included: https://explorer.shimmer.network/testnet/block/0x1c4fe528677089eeffaa01eefe34eda4a75f7c6f2020d83af61221571979f616
Burned NFT 0xd2356323fad25efa3ec772a341d122eaf5ea3bf1cba48b70a1038b7d00bc385d
```
Loading