Skip to content

Commit 701c6c5

Browse files
author
Aleksandr Penskoi
committed
Rewriting 'Mint you own NFT' in script, update readme.
1 parent 02a1975 commit 701c6c5

File tree

5 files changed

+326
-70
lines changed

5 files changed

+326
-70
lines changed

README.md

Lines changed: 72 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -69,73 +69,80 @@ Ensure that Nami is set to Testnet, that you have some Test Ada, and that you've
6969

7070
### Optional: Mint your own NFTs
7171

72-
This process will be simplified in the future.
72+
#### Start plutus-chain-index
7373

74+
Set environment variables:
75+
76+
``` shell
77+
$ pwd
78+
.../seabug
79+
$ export CARDANO_NODE_SOCKET_PATH=$PWD/data/cardano-node/ipc/node.socket
80+
$ mkdir -p chain-index
81+
$ export CHAIN_INDEX_PATH=$PWD/chain-index/chain-index.sqlite
82+
```
83+
84+
Fix permission problem for `node.socket` (if you receive error like: `plutus-chain-index: Network.Socket.connect: <socket: 35>: permission denied (Permission denied)`):
85+
86+
``` shell
87+
$ sudo chmod 0666 $CARDANO_NODE_SOCKET_PATH
88+
```
89+
90+
Building and run plutus-chain-index from the source:
91+
92+
```
93+
$ cd ..
94+
$ git clone [email protected]:input-output-hk/plutus-apps.git
95+
$ cd plutus-apps
96+
$ nix build -f default.nix plutus-chain-index
97+
$ result/bin/plutus-chain-index start-index --network-id 1097911063 --db-path $CHAIN_INDEX_PATH/chain-index.sqlite --socket-path $CARDANO_NODE_SOCKET_PATH
98+
```
99+
100+
The index should be synced for minting.
101+
102+
#### Prepare wallet
103+
104+
``` shell
105+
$ cd seabug
106+
$ nix develop
107+
$ scripts/prepare-wallet.sh
108+
new wallet generated:
109+
address: addr_test1vp3tywa08qjjj7mplzmwjs9kmes0ce3ud5da3x0wppu5e9qgxqhps
110+
PHK: 62b23baf3825297b61f8b6e940b6de60fc663c6d1bd899ee08794c94
111+
file: payment.addr
112+
file: payment.vkey
113+
file: pab/signing-keys/signing-key-62b23baf3825297b61f8b6e940b6de60fc663c6d1bd899ee08794c94.skey
114+
```
115+
116+
Add some Ada to your wallet:
117+
- by Nami wallet
118+
- or by [Faucet](https://testnets.cardano.org/en/testnets/cardano/tools/faucet/)
119+
120+
Check the result:
121+
74122
```shell
75-
$ # Setup server admin token, password: seabug
76-
$ PGPASSWORD=seabug psql -U seabug -h localhost -c "INSERT INTO admin_token(token) VALUES ('ADMIN_TOKEN')"
77-
78-
$ # Upload image
79-
$ curl --location --request POST "locahost:8008" \
80-
-F "image=@./cat123.png" \
81-
-F "title=Cat Cat number 123" \
82-
-F "description=Cat eating piece of cheese" \
83-
-H "Authorization: ADMIN_TOKEN"
84-
85-
$ # Get IPFS CID, replace SHA_256_HASH with hash from previous response, note "ipfsHash"
86-
$ curl --location --request GET 'localhost:8008' \
87-
| jq 'to_entries[] | select (.value.sha256hash=="SHA_256_HASH")'
88-
89-
$ # Convert CID, replace "IPFS_HASH" with hash from previous response, note the result
90-
$ ipfs cid format -b=base36 IPFS_HASH
91-
92-
$ # Configure keys for BPI
93-
$ cd plutus-use-cases/mlabs
94-
$ cardano-cli address build \
95-
--payment-verification-key-file payment.vkey \
96-
--out-file payment.addr \
97-
--testnet-magic 1097911063
98-
$ cardano-cli address key-gen \
99-
--verification-key-file payment.vkey \
100-
--signing-key-file payment.skey
101-
$ mkdir -p pab/signing-keys
102-
$ cat payment.addr
103-
$ mv payment.skey pab/signing-keys/signing-key-PKH_HERE.skey
104-
105-
$ # Start BPI, note "minting-policy", it will be used later
106-
$ nix develop -L -c cabal run efficient-nft-pab
107-
108-
$ # In other console
109-
$ # Mint underlying CNFTs, replace "CONVERTED_CID" with the result of `ipfs` command
110-
$ curl --location --request POST 'localhost:3003/api/contract/activate' \
111-
--header 'Content-Type: application/json' \
112-
--data-raw '
113-
{
114-
"caID": {
115-
"tag":"MintCnft",
116-
"contents":[
117-
{
118-
"mc'"'"'name":"Cat number 123",
119-
"mc'"'"'description":"Cat eating piece of cheese",
120-
"mc'"'"'image":"ipfs://CONVERTED_CID",
121-
"mc'"'"'tokenName":"cat-123" # This should be hex encoded (without 0x)
122-
}
123-
]
124-
}
125-
}'
126-
127-
$ # Go back to previous terminal and stop BPI
128-
$ # Replace "CURRENCY_SYMBOL" in /efficient-nft-pab/Main.hs with currency symbol from BPI log
129-
$ # Restart BPI, note "seabug-mint-request"
130-
$ nix develop -L -c cabal run efficient-nft-pab
131-
132-
$ # Mint SeaBug NFT
133-
$ curl --location --request POST 'localhost:3003/api/contract/activate'
134-
--header 'Content-Type: application/json' \
135-
--data-raw 'INSERT_seabug-mint-request_HERE'
136-
137-
$ cd ../cardano-transaction-lib
138-
$ # Replace value of "mintingPolicy1" in seabug_contracts/MintingPolicy.js with policy noted from BPI
123+
$ cd seabug
124+
$ cardano-cli query utxo --testnet-magic 1097911063 --address $(cat payment.addr)
125+
TxHash TxIx Amount
126+
--------------------------------------------------------------------------------------
127+
ed11c8765d764852d049cd1a2239524ade0c6057a3a51146dc8c9d7bcbe008e0 0 100000000 lovelace + TxOutDatumNone
128+
```
129+
130+
#### Mint your own NFT
131+
132+
If you have an image:
133+
134+
``` shell
135+
$ cd seabug
136+
$ scripts/mint-nft.sh 'image.jpeg' 'Title' 'Description' 'Token name'
137+
```
138+
139+
The script take some time to work, especially if you don't use effitient_nft_pab before (`cd plutus-use-cases/mlabs && nix develop -c cabal run efficient-nft-pab --disable-optimisation`).
140+
141+
If you already uploaded the image to nft.storage and have IPFC_CID (you can get it from nft.storage web interface).
142+
143+
``` shell
144+
$ cd seabug
145+
$ scripts/mint-nft.sh 'image.jpeg' 'Title' 'Description' 'Token name' k2cwueaf1ew3nr2gq2rw83y13m2f5jpg8uyymn66kr8ogeglrwcou5u8
139146
```
140147

141148
## Components

flake.nix

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,15 @@
1818
in rec {
1919
devShell = pkgs.mkShell {
2020
nativeBuildInputs = with pkgs; [
21-
postgresql
22-
jq
21+
arion.packages.${system}.arion
22+
cardano-node.packages.${system}.cardano-cli
2323
curl
24+
httpie
2425
ipfs
25-
cardano-node.packages.${system}.cardano-cli
26-
arion.packages.${system}.arion
26+
jq
27+
postgresql
28+
shfmt
29+
expect
2730
];
2831
};
2932
});

scripts/mint-nft.sh

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
if [ $# != 4 ] && [ $# != 5 ]; then
6+
echo "Arguments: <IMAGE_FILE> <TITLE> <DESCRIPTION> <TOKEN_NAME> [<IPFC_CID>]"
7+
exit 1
8+
fi
9+
10+
IMAGE=$1
11+
TITLE=$2
12+
DESC=$3
13+
TOKEN_NAME=$4
14+
IPFC_CID=$5
15+
16+
echo IMAGE: $IMAGE
17+
echo TITLE: $TITLE
18+
echo DESC: $DESC
19+
echo TOKEN_NAME: $TOKEN_NAME
20+
echo IPFC_CID: $IPFC_CID
21+
22+
TOKEN_NAME_BASE64=$(echo -n $TOKEN_NAME | od -A n -t x1 | tr -d " \n")
23+
echo TOKEN_NAME_BASE64: $TOKEN_NAME_BASE64
24+
25+
PKH=$(cardano-cli address key-hash --payment-verification-key-file plutus-use-cases/mlabs/payment.vkey)
26+
echo PKH: $PKH
27+
28+
# enviroment variables
29+
SEABUG_ADMIN_TOKEN=ADMIN_TOKEN
30+
TESTNET_MAGIC=1097911063
31+
export PGPASSWORD=seabug
32+
export CARDANO_NODE_SOCKET_PATH=$PWD/data/cardano-node/ipc/node.socket
33+
34+
############################################################
35+
# Prepare
36+
############################################################
37+
38+
# Setup server admin token, password: seabug
39+
psql -U seabug -h localhost -q -c "INSERT INTO admin_token(token) VALUES ('$SEABUG_ADMIN_TOKEN') ON CONFLICT DO NOTHING"
40+
41+
############################################################
42+
# Functions
43+
############################################################
44+
45+
get_ipfs_hash() {
46+
local IMAGE_HASH=$1
47+
http GET localhost:8008/images |
48+
jq -r "to_entries[] | select (.value.sha256hash == \"$IMAGE_HASH\") | .value.ipfsHash"
49+
}
50+
51+
efficient_nft_pab() {
52+
cd plutus-use-cases/mlabs
53+
rm -fv ../../efficient_nft_pab_out
54+
if [ -z $CURRENCY ]; then
55+
echo "> unbuffer nix develop -c cabal run efficient-nft-pab --disable-optimisation -- --pkh $PKH --auth-pkh $PKH --token \"$TOKEN_NAME\" | tee ../../efficient_nft_pab_out"
56+
unbuffer nix develop -c cabal run efficient-nft-pab --disable-optimisation -- --pkh $PKH --auth-pkh $PKH --token "$TOKEN_NAME" >../../efficient_nft_pab_out
57+
else
58+
echo "> unbuffer nix develop -c cabal run efficient-nft-pab --disable-optimisation -- --pkh $PKH --auth-pkh $PKH --token "$TOKEN_NAME" --currency $CURRENCY | tee ../../efficient_nft_pab_out"
59+
unbuffer nix develop -c cabal run efficient-nft-pab --disable-optimisation -- --pkh $PKH --auth-pkh $PKH --token "$TOKEN_NAME" --currency $CURRENCY >../../efficient_nft_pab_out
60+
fi
61+
}
62+
63+
wait_up_efficient_nft_pab() {
64+
sleep 1
65+
echo '>' wait_up_efficient_nft_pab...
66+
while [ -z "$(rg 'Starting BotPlutusInterface server' efficient_nft_pab_out)" ] && [ ! -z "$(jobs)" ]; do
67+
echo -n .
68+
sleep 1
69+
done
70+
sleep 3
71+
if [ ! -z "$(rg 'Network.Socket.bind: resource busy' efficient_nft_pab_out)" ]; then
72+
echo "For some reason efficient_nft_pab already run, kill it"
73+
exit 1
74+
fi
75+
echo '>' wait_up_efficient_nft_pab...ok
76+
}
77+
78+
mint_cnft_request() {
79+
local IPFC_CID=$1
80+
http POST localhost:3003/api/contract/activate \
81+
caID[tag]=MintCnft \
82+
caID[contents][0]["mc'name"]="$TITLE" \
83+
caID[contents][0]["mc'description"]="$DESC" \
84+
caID[contents][0]["mc'image"]="ipfs://$IPFC_CID" \
85+
caID[contents][0]["mc'tokenName"]="$TOKEN_NAME_BASE64" -v
86+
}
87+
88+
mint_request() {
89+
http POST 'localhost:3003/api/contract/activate' \
90+
caID[tag]=Mint \
91+
caID[contents][0][unAssetClass][0][unCurrencySymbol]="$CURRENCY" \
92+
caID[contents][0][unAssetClass][1][unTokenName]="$TOKEN_NAME" \
93+
caID[contents][1]["mp'fakeAuthor"][unPaymentPubKeyHash][getPubKeyHash]="$PKH" \
94+
caID[contents][1]["mp'feeVaultKeys"]:=[] \
95+
caID[contents][1]["mp'price"]:=100000000 \
96+
caID[contents][1]["mp'daoShare"]:=500 \
97+
caID[contents][1]["mp'owner"][0][unPaymentPubKeyHash][getPubKeyHash]="$PKH" \
98+
caID[contents][1]["mp'owner"][1]:=null \
99+
caID[contents][1]["mp'lockLockupEnd"][getSlot]:=5 \
100+
caID[contents][1]["mp'authorShare"]:=1000 \
101+
caID[contents][1]["mp'lockLockup"]:=5 -v
102+
}
103+
104+
wait_balance_tx_efficient_nft_pab() {
105+
echo '>' wait_balance_tx_efficient_nft_pab...
106+
while [ -z "$(rg BalanceTxResp efficient_nft_pab_out)" ] && [ ! -z "$(jobs)" ]; do
107+
echo -n .
108+
sleep 1
109+
done
110+
echo '>' wait_balance_tx_efficient_nft_pab...ok
111+
}
112+
113+
kill_bg_jobs() {
114+
echo '>' kill bg jobs...
115+
sleep 5
116+
killall efficient-nft-p
117+
kill $(jobs -p)
118+
while [ ! -z $(jobs -p) ]; do
119+
sleep 1
120+
echo -n .
121+
done
122+
echo '>' kill bg jobs...ok
123+
}
124+
125+
query_utxo() {
126+
cardano-cli query utxo --testnet-magic $TESTNET_MAGIC --address $(cat plutus-use-cases/mlabs/payment.addr)
127+
}
128+
129+
############################################################
130+
# upload image
131+
############################################################
132+
133+
query_utxo
134+
135+
if [ -z $IPFC_CID ]; then
136+
echo '>' Image upload...
137+
BUF=$(
138+
http --form POST localhost:8008/admin/upload_image \
139+
"Authorization:$SEABUG_ADMIN_TOKEN" \
140+
"files@$IMAGE" \
141+
"title=$TITLE" \
142+
"description=$DESC" \
143+
--pretty none
144+
)
145+
IMAGE_HASH=$(echo -n "$BUF" | rg '^\{' | jq -r '.sha256hash')
146+
if [ -z "$IMAGE_HASH" ] || [ "$IMAGE_HASH" = "null" ]; then
147+
echo Upload image error: $BUF
148+
exit 1
149+
fi
150+
echo '>' Image upload...ok
151+
echo '>' IMAGE_HASH: $IMAGE_HASH
152+
IPFS_HASH=$(get_ipfs_hash $IMAGE_HASH)
153+
echo '>' IPFS_HASH: $IPFS_HASH
154+
IPFS_CID=$(ipfs cid format -b base36 $IPFS_HASH)
155+
echo '>' IPFS_CID: $IPFS_CID
156+
fi
157+
158+
############################################################
159+
# mint cnft
160+
############################################################
161+
162+
echo '>>>' mint cnft
163+
164+
echo '>' Run efficient-nft-pab...
165+
efficient_nft_pab &
166+
wait_up_efficient_nft_pab
167+
echo '>' Run efficient-nft-pab...ok
168+
169+
echo '>' Run mint_cnft_request...
170+
mint_cnft_request $IPFC_CID
171+
wait_balance_tx_efficient_nft_pab
172+
echo '>' Run mint_cnft_request...ok
173+
174+
kill_bg_jobs
175+
176+
BALANCE_TX_RESP=$(cat efficient_nft_pab_out | rg BalanceTxResp)
177+
echo '>' BALANCE_TX_RESP: $BALANCE_TX_RESP
178+
179+
export CURRENCY=$(echo -n $BALANCE_TX_RESP | sed -E "s/^.*txMint = Value \(Map \[\(([^,]+).*/\1/")
180+
echo '>' CURRENCY: $CURRENCY
181+
182+
query_utxo
183+
184+
echo '>' sleep 30 for minting work
185+
sleep 30
186+
187+
query_utxo
188+
189+
############################################################
190+
# mint nft
191+
############################################################
192+
193+
echo '>>>' mint nft
194+
195+
cp -v efficient_nft_pab_out efficient_nft_pab_out0
196+
197+
echo '>' Run efficient-nft-pab...
198+
efficient_nft_pab &
199+
wait_up_efficient_nft_pab
200+
echo '>' Run efficient-nft-pab...ok
201+
202+
echo '>' Run mint_request...
203+
mint_request
204+
wait_balance_tx_efficient_nft_pab
205+
echo '>' Run mint_request...ok
206+
207+
kill_bg_jobs
208+
209+
BALANCE_TX_RESP=$(cat efficient_nft_pab_out | rg BalanceTxResp)
210+
echo '>' BALANCE_TX_RESP: $BALANCE_TX_RESP
211+
212+
MINTING_POLICY=$(cat efficient_nft_pab_out | rg minting-policy | sed -e 's/minting-policy: //' | jq -r .getMintingPolicy)
213+
echo '>' MINTING_POLICY: $MINTING_POLICY
214+
215+
echo '>' patch seabug_contracts/Seabug/MintingPolicy.js
216+
sed -i "3s/\".*\"/\"$MINTING_POLICY\"/" cardano-transaction-lib/seabug_contracts/Seabug/MintingPolicy.js
217+
218+
query_utxo
219+
220+
echo '>' sleep 30 for minting work
221+
sleep 30
222+
223+
query_utxo
224+
225+
echo mint-nft ended

0 commit comments

Comments
 (0)