From fe51d56ba3a6705e31365d1aeab9657cb6a097ed Mon Sep 17 00:00:00 2001 From: maneeSHA-256 Date: Thu, 23 Jan 2025 18:14:59 +0530 Subject: [PATCH 1/6] maintaining general response format --- README.md | 371 ++++++++---- docs/docs.go | 205 +++---- docs/swagger.json | 202 +++---- docs/swagger.yaml | 184 +++--- main.go | 1436 ++++++++++++++++++++++++++++++++------------- 5 files changed, 1530 insertions(+), 868 deletions(-) diff --git a/README.md b/README.md index ae0f052..6c92f81 100644 --- a/README.md +++ b/README.md @@ -14,11 +14,11 @@ curl -X POST http://localhost:8080/create -d '{"email":"","password":" ``` #### sample with valid request ``` -curl -X POST http://localhost:8080/create -d '{"email":"jiya@p.com","password":"123","name":"jiya"}' +curl -X POST http://localhost:8080/create -d '{"email":"mani@p.com","password":"123","name":"mani"}' ``` **Response:** ``` -{"did":"bafybmie5l4jpfxmnnqi3sk4vnt6fx3sbuzf632ubeflc7let6rljzq4usi"} +{"did":"bafybmiaysyb5hbdb6clsk7jncdejxwomxumv3zos5t57f6bwz7numvaina","email":"mani@p.com","name":"mani"} ``` #### sample with invalid request (invalid input format to name) ``` @@ -68,19 +68,19 @@ curl -L -X POST http://localhost:8080/register_did -H 'Authorization: Bearer " -H 'Author ``` #### sample with valid request ``` -curl -L -X GET "http://localhost:8080/request_balance?did=bafybmigfq7dnhqdpghluqfirvn5yz76vpvrkutofswih7sidmqmssohvbq" -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU4MTY2NTAsInN1YiI6ImJhZnlibWlnZnE3ZG5ocWRwZ2hsdXFmaXJ2bjV5ejc2dnB2cmt1dG9mc3dpaDdzaWRtcW1zc29odmJxIn0.c3CFWttRFrm3KKlCi8uazISOekI_T1PvV9jLsObREqE' +curl -L -X GET "http://localhost:8080/request_balance?did=bafybmihsnmqer6f6rifz5mg5elf7uwt3en6t35vics7y5y7pn4anyt4wb4" -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3Mzc3MjE4MTQsInN1YiI6ImJhZnlibWloc25tcWVyNmY2cmlmejVtZzVlbGY3dXd0M2VuNnQzNXZpY3M3eTV5N3BuNGFueXQ0d2I0In0.LiYfB_qFd13TpsxeGgoi3f2pDsZ7RDAeqzG1vtNTbu0' ``` **Response:** ``` -{"account_info":[{"did":"bafybmigfq7dnhqdpghluqfirvn5yz76vpvrkutofswih7sidmqmssohvbq","did_type":0,"locked_rbt":0,"pinned_rbt":0,"pledged_rbt":14.824,"rbt_amount":5.176}],"message":"Got account info successfully","result":null,"status":true} +{"status":true,"message":"Got account info successfully","result":[{"did":"bafybmihsnmqer6f6rifz5mg5elf7uwt3en6t35vics7y5y7pn4anyt4wb4","did_type":0,"locked_rbt":0,"pinned_rbt":0,"pledged_rbt":0,"rbt_amount":1}]} ``` #### sample with invalid request (empty input to did) ``` -curl -L -X GET "http://localhost:8080/request_balance?did=" -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU0NjY4MjIsInN1YiI6ImJhZnlibWlmZWJxbHZxMnVldHhvM21ncnd1Z2YzazRyZGp1cG82aDZma243bXpyYjVla2h4dHRhbW5xIn0.NeIFZ0BitoO5hEaMF_fZbyyCGD2b4jh9FVM4536VMFI' +curl -L -X GET "http://localhost:8080/request_balance?did=" -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3Mzc3MjE4MTQsInN1YiI6ImJhZnlibWloc25tcWVyNmY2cmlmejVtZzVlbGY3dXd0M2VuNnQzNXZpY3M3eTV5N3BuNGFueXQ0d2I0In0.LiYfB_qFd13TpsxeGgoi3f2pDsZ7RDAeqzG1vtNTbu0' ``` **Response:** ``` -{"error":"Missing required parameter: did"} +{"status":false,"message":"Missing required parameter: did","result":null} ``` @@ -180,19 +180,19 @@ curl -L -X POST http://localhost:8080/rbt/unpledge -H 'Authorization: Bearer ","sign_data ``` #### sample with valid request ``` -curl -X POST http://localhost:8080/sign -d '{"did":"bafybmifqpi36mvzocqqpsh3rtjrjy5434wlqv4nz7zr4ejqx3qul5gl36q","sign_data":{"hash":"YmY0ZGI0NDEzNWZkYTg2Nzc1YTg1ZWQzMTRjZmIyZTI0MmVmZjBjYzdmOTI3OWNiYzVkZmQ5NjAxMTNkNDlhYQ==","id":"0319B7FA-F9CF-4019-97AB-FA5D69608735","mode":4}}' +curl -X POST http://localhost:8080/sign -d '{"did":"bafybmiaysyb5hbdb6clsk7jncdejxwomxumv3zos5t57f6bwz7numvaina","sign_data":{"hash":"NDkzYTkyN2NjYTA1YTgzZDA1ZWVjZjcwMzgxYjQ5ZGY1YTFlOTNiODM0OTE5OWJiYWY4NGVmNjBkNDdkMTEzNA==","id":"4CC6CE58-3C12-4CCB-B0D3-05395D4E3650","mode":4, "only_priv_key":true}}' ``` **Response:** -while transacting RBTs +(While registering DID) ``` -"\"Transfer finished successfully in 6.679579318s with trnxid 7c57df13b39e7eed7c5980eb4e4b78f0eadee662cff2b49a47b9b7534b2067b9\"\n" +{"status":true,"message":"DID registered successfully","result":null} ``` #### sample with invalid request (invalid did) ``` -curl -X POST http://localhost:8080/sign -d '{"did":"bafybmifqpi36mvzocqqpsh3rtjrjy5434wlqv4nz7zr4ejqx3qul5gl36q","sign_data":{"hash":"YmY0ZGI0NDEzNWZkYTg2Nzc1YTg1ZWQzMTRjZmIyZTI0MmVmZjBjYzdmOTI3OWNiYzVkZmQ5NjAxMTNkNDlhYQ==","id":"","mode":4}}' +curl -X POST http://localhost:8080/sign -d '{"did":"bafybmiaysyb5hbdb6clsk7jncdejxwomxumv3zos5t57f6bwz7numvanhb","sign_data":{"hash":"ZWQ1MWY0OWYxNTYzMTEzNGEzZTQyMDJmYWJkYmRjMzAzY2I3OGZlZjk1Zjc3MjhlM2M5NTllNGMxOWY5ZjFjZQ==","id":"BA81DDB1-5DBD-4C86-877B-1FA630A868D3","mode":4, "only_priv_key":true}}' ``` **Response:** ``` -{"error":"failed to send sign response, Invalid request ID"} +{"status":false,"message":"User not found, sql: no rows in result set","result":null} ``` @@ -225,19 +225,19 @@ curl -L -X POST http://localhost:8080/request_txn -H 'Authorization: Bearer &role=" -H 'Authorizati ``` #### sample with valid request ``` -curl -L -X GET "http://localhost:8080/get_all_ft?did=bafybmifebqlvq2uetxo3mgrwugf3k4rdjupo6h6fkn7mzrb5ekhxttamnq" -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU1NDIzMjksInN1YiI6ImJhZnlibWlmZWJxbHZxMnVldHhvM21ncnd1Z2YzazRyZGp1cG82aDZma243bXpyYjVla2h4dHRhbW5xIn0.Kii2kW5CTkdV7IjNjkaYiXTP40rYXlj7UcUWxmSxfm0' +curl -L -X GET "http://localhost:8080/get_all_ft?did=bafybmiaysyb5hbdb6clsk7jncdejxwomxumv3zos5t57f6bwz7numvaina" -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3Mzc3MjExODgsInN1YiI6ImJhZnlibWlheXN5YjVoYmRiNmNsc2s3am5jZGVqeHdvbXh1bXYzem9zNXQ1N2Y2Ynd6N251bXZhaW5hIn0.WU8P4UJiq-Jap_NhmHONhCah6d5xtoL6lHaH6ceUFJ4' ``` **Response:** ``` -{"ft_info":[{"creator_did":"bafybmifebqlvq2uetxo3mgrwugf3k4rdjupo6h6fkn7mzrb5ekhxttamnq","ft_count":2,"ft_name":"test1"}],"message":"Got FT info successfully","result":null,"status":true} +{"status":true,"message":"Got FT info successfully","result":[{"creator_did":"bafybmiaysyb5hbdb6clsk7jncdejxwomxumv3zos5t57f6bwz7numvaina","ft_count":4,"ft_name":"testFT-1"}]} ``` #### sample with invalid request (empty input to did) ``` -curl -L -X GET "http://localhost:8080/get_all_ft?did=" -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU1NDIzMjksInN1YiI6ImJhZnlibWlmZWJxbHZxMnVldHhvM21ncnd1Z2YzazRyZGp1cG82aDZma243bXpyYjVla2h4dHRhbW5xIn0.Kii2kW5CTkdV7IjNjkaYiXTP40rYXlj7UcUWxmSxfm0' +curl -L -X GET "http://localhost:8080/get_all_ft?did=" -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3Mzc3MjExODgsInN1YiI6ImJhZnlibWlheXN5YjVoYmRiNmNsc2s3am5jZGVqeHdvbXh1bXYzem9zNXQ1N2Y2Ynd6N251bXZhaW5hIn0.WU8P4UJiq-Jap_NhmHONhCah6d5xtoL6lHaH6ceUFJ4' ``` **Response:** ``` -{"error":"Missing required parameter: did"} +{"status":false,"message":"Missing required parameter: did","result":null} ``` ### Curl request to get FT chain @@ -362,19 +362,19 @@ curl -L -X GET "http://localhost:8080/get_ft_chain?did=&tokenID=&nft=" -H 'Aut ``` #### sample with valid request ``` -curl -L -X GET "http://localhost:8080/get_nft?did=bafybmifebqlvq2uetxo3mgrwugf3k4rdjupo6h6fkn7mzrb5ekhxttamnq&nft=Qme4NFXJ7f3f4umwbjL7A6ps2udw8WdcCz5cYWG2w9ecDA" -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU1NDIzMjksInN1YiI6ImJhZnlibWlmZWJxbHZxMnVldHhvM21ncnd1Z2YzazRyZGp1cG82aDZma243bXpyYjVla2h4dHRhbW5xIn0.Kii2kW5CTkdV7IjNjkaYiXTP40rYXlj7UcUWxmSxfm0' +curl -L -X GET "http://localhost:8080/get_nft?did=bafybmifqpi36mvzocqqpsh3rtjrjy5434wlqv4nz7zr4ejqx3qul5gl36q&nft=QmV8SEuVqrqhQxDsden9t22Hp7vyXUJCPLcS5ic6MnPK7P" -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3Mzc3ODc5NDQsInN1YiI6ImJhZnlibWlmcXBpMzZtdnpvY3FxcHNoM3J0anJqeTU0MzR3bHF2NG56N3pyNGVqcXgzcXVsNWdsMzZxIn0.yeC38PkFauWhOkOiWeyCAT-813O-KahTrr9ESZ8TF4Y' ``` **Response:** ``` -{"message":"NFT fetched successfully","result":null,"status":true} +{"status":true,"message":"NFT fetched successfully","result":null} ``` #### sample with invalid request (invalid did) ``` -curl -L -X GET "http://localhost:8080/get_nft?did=bafybmifebqlvq2uetxo3mgrwugf3k4rdjupo6h6fkn7mzrb5ekhxttamhj&nft=Qme4NFXJ7f3f4umwbjL7A6ps2udw8WdcCz5cYWG2w9echy" -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU1NDIzMjksInN1YiI6ImJhZnlibWlmZWJxbHZxMnVldHhvM21ncnd1Z2YzazRyZGp1cG82aDZma243bXpyYjVla2h4dHRhbW5xIn0.Kii2kW5CTkdV7IjNjkaYiXTP40rYXlj7UcUWxmSxfm0' +curl -L -X GET "http://localhost:8080/get_nft?did=bafybmifqpi36mvzocqqpsh3rtjrjy5434wlqv4nz7zr4ejqx3qul5glmnb&nft=QmV8SEuVqrqhQxDsden9t22Hp7vyXUJCPLcS5ic6MnPK7P" -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3Mzc3ODc5NDQsInN1YiI6ImJhZnlibWlmcXBpMzZtdnpvY3FxcHNoM3J0anJqeTU0MzR3bHF2NG56N3pyNGVqcXgzcXVsNWdsMzZxIn0.yeC38PkFauWhOkOiWeyCAT-813O-KahTrr9ESZ8TF4Y' ``` **Response:** ``` -{"error":"DID mismatch"} +{"status":false,"message":"DID mismatch","result":null} ``` ### Curl request to get NFT chain @@ -539,19 +539,19 @@ curl -L -X GET "http://localhost:8080/get_nft_chain?did=&nft=&la ``` #### sample with valid request ``` -curl -L -X GET "http://localhost:8080/get_nft_chain?did=bafybmifebqlvq2uetxo3mgrwugf3k4rdjupo6h6fkn7mzrb5ekhxttamnq&nft=Qme4NFXJ7f3f4umwbjL7A6ps2udw8WdcCz5cYWG2w9ecDA" -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU1NDIzMjksInN1YiI6ImJhZnlibWlmZWJxbHZxMnVldHhvM21ncnd1Z2YzazRyZGp1cG82aDZma243bXpyYjVla2h4dHRhbW5xIn0.Kii2kW5CTkdV7IjNjkaYiXTP40rYXlj7UcUWxmSxfm0' +curl -L -X GET "http://localhost:8080/get_nft_chain?did=bafybmifqpi36mvzocqqpsh3rtjrjy5434wlqv4nz7zr4ejqx3qul5gl36q&nft=QmV8SEuVqrqhQxDsden9t22Hp7vyXUJCPLcS5ic6MnPK7P" -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3Mzc3ODc5NDQsInN1YiI6ImJhZnlibWlmcXBpMzZtdnpvY3FxcHNoM3J0anJqeTU0MzR3bHF2NG56N3pyNGVqcXgzcXVsNWdsMzZxIn0.yeC38PkFauWhOkOiWeyCAT-813O-KahTrr9ESZ8TF4Y' ``` **Response:** ``` -{"NFTDataReply":[{"BlockId":"0-82227efb89892902326ccdda6422cd8a2247c037749fff6a5c181deaf6602936","BlockNo":0,"NFTData":"","NFTOwner":"bafybmifebqlvq2uetxo3mgrwugf3k4rdjupo6h6fkn7mzrb5ekhxttamnq","NFTValue":0},{"BlockId":"1-98baffa792c3bf87759ee19608c23f8c6afeb471f59f0a7911a971959ab7b81b","BlockNo":1,"NFTData":"","NFTOwner":"bafybmibuj72pm5x6yjhmfgacfusbk5veur5poqfm7qibk45kk5ktiep3d4","NFTValue":11}],"message":"Fetched NFT data","result":null,"status":true} +{"status":true,"message":"Fetched NFT data","result":[{"BlockId":"0-545c71dbbefd73709d8b13c4f6cd756d1a445898bdd823a9dd200a43d951c1a1","BlockNo":0,"NFTData":"","NFTOwner":"bafybmiaysyb5hbdb6clsk7jncdejxwomxumv3zos5t57f6bwz7numvaina","NFTValue":0},{"BlockId":"1-be986f46ca72891f0b046a16bd369051de168ef0581026175b7b7829bd8c36f6","BlockNo":1,"NFTData":"","NFTOwner":"bafybmifqpi36mvzocqqpsh3rtjrjy5434wlqv4nz7zr4ejqx3qul5gl36q","NFTValue":11}]} ``` #### sample with invalid request (invalid input to nft) ``` -curl -L -X GET "http://localhost:8080/get_nft_chain?did=bafybmifebqlvq2uetxo3mgrwugf3k4rdjupo6h6fkn7mzrb5ekhxttamnq&nft=Qme4NFXJ7f3f4umwbjL7A6ps2udw8WdcCz5cYWG2w9echj" -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU1NDIzMjksInN1YiI6ImJhZnlibWlmZWJxbHZxMnVldHhvM21ncnd1Z2YzazRyZGp1cG82aDZma243bXpyYjVla2h4dHRhbW5xIn0.Kii2kW5CTkdV7IjNjkaYiXTP40rYXlj7UcUWxmSxfm0' +curl -L -X GET "http://localhost:8080/get_nft_chain?did=bafybmifqpi36mvzocqqpsh3rtjrjy5434wlqv4nz7zr4ejqx3qul5gl36q&nft=QmV8SEuVqrqhQxDsden9t22Hp7vyXUJCPLcS5ic6MnPK7k" -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3Mzc3ODc5NDQsInN1YiI6ImJhZnlibWlmcXBpMzZtdnpvY3FxcHNoM3J0anJqeTU0MzR3bHF2NG56N3pyNGVqcXgzcXVsNWdsMzZxIn0.yeC38PkFauWhOkOiWeyCAT-813O-KahTrr9ESZ8TF4Y' ``` **Response:** ``` -{"NFTDataReply":null,"message":"Failed to get nft data, token does not exist","result":null,"status":false} +{"status":false,"message":"Failed to get nft data, token does not exist","result":null} ``` ### Curl request to get all NFTs @@ -561,17 +561,150 @@ curl -L -X GET "http://localhost:8080/get_all_nft?did=" -H 'Authorizatio ``` #### sample with valid request ``` -curl -L -X GET "http://localhost:8080/get_all_nft?did=bafybmifebqlvq2uetxo3mgrwugf3k4rdjupo6h6fkn7mzrb5ekhxttamnq" -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU1NDIzMjksInN1YiI6ImJhZnlibWlmZWJxbHZxMnVldHhvM21ncnd1Z2YzazRyZGp1cG82aDZma243bXpyYjVla2h4dHRhbW5xIn0.Kii2kW5CTkdV7IjNjkaYiXTP40rYXlj7UcUWxmSxfm0' +curl -L -X GET "http://localhost:8080/get_all_nft?did=bafybmiaysyb5hbdb6clsk7jncdejxwomxumv3zos5t57f6bwz7numvaina" -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3Mzc3MjExODgsInN1YiI6ImJhZnlibWlheXN5YjVoYmRiNmNsc2s3am5jZGVqeHdvbXh1bXYzem9zNXQ1N2Y2Ynd6N251bXZhaW5hIn0.WU8P4UJiq-Jap_NhmHONhCah6d5xtoL6lHaH6ceUFJ4' ``` **Response:** ``` -{"message":"Got All NFTs","nfts":[{"nft":"QmSYAeRRoxurxEpraDGu4B9fUn38VP7vXBoxzZqQnmfijY","nft_value":0,"owner_did":"bafybmifebqlvq2uetxo3mgrwugf3k4rdjupo6h6fkn7mzrb5ekhxttamnq"}],"result":null,"status":true} +{"status":true,"message":"Got All NFTs","result":[{"nft":"QmNMBaU9B6ZaBjaPgufTaTsTu9dHjtf3XWWogFPJ3zy9u6","nft_value":0,"owner_did":"bafybmiaysyb5hbdb6clsk7jncdejxwomxumv3zos5t57f6bwz7numvaina"}]} ``` #### sample with invalid request (invalid input to did) ``` -curl -L -X GET "http://localhost:8080/get_all_nft?did=bafybmifebqlvq2uetxo3mgrwugf3k4rdjupo6h6fkn7mzrb5ekhxttaghh" -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzU1NDIzMjksInN1YiI6ImJhZnlibWlmZWJxbHZxMnVldHhvM21ncnd1Z2YzazRyZGp1cG82aDZma243bXpyYjVla2h4dHRhbW5xIn0.Kii2kW5CTkdV7IjNjkaYiXTP40rYXlj7UcUWxmSxfm0' +curl -L -X GET "http://localhost:8080/get_all_nft?did=bafybmiaysyb5hbdb6clsk7jncdejxwomxumv3zos5t57f6bwz7numvabhg" -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3Mzc3MjExODgsInN1YiI6ImJhZnlibWlheXN5YjVoYmRiNmNsc2s3am5jZGVqeHdvbXh1bXYzem9zNXQ1N2Y2Ynd6N251bXZhaW5hIn0.WU8P4UJiq-Jap_NhmHONhCah6d5xtoL6lHaH6ceUFJ4' +``` +**Response:** +``` +{"status":false,"message":"DID mismatch","result":null} +``` + +### Curl request to generate Smart Contract Token +``` +curl -L -X POST "http://localhost:8080/generate-smart-contract -H 'Authorization: Bearer ' -d '{"did":"", "binary_code_path":, "raw_code_path":"", "schema_file_path":"}' +``` +#### sample with valid request +``` +curl -L -X POST 'http://localhost:8080/generate-smart-contract' \ +-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3Mzc3MjExODgsInN1YiI6ImJhZnlibWlheXN5YjVoYmRiNmNsc2s3am5jZGVqeHdvbXh1bXYzem9zNXQ1N2Y2Ynd6N251bXZhaW5hIn0.WU8P4UJiq-Jap_NhmHONhCah6d5xtoL6lHaH6ceUFJ4' \ +-F 'did=bafybmiaysyb5hbdb6clsk7jncdejxwomxumv3zos5t57f6bwz7numvaina' \ +-F 'binaryCodePath=@/home/maneesha/Rubix-Git/Smart-Contract/code_files/bidding_contract.wasm' \ +-F 'rawCodePath=@/home/maneesha/Rubix-Git/Smart-Contract/code_files/lib.rs' \ +-F 'schemaFilePath=@/home/maneesha/Rubix-Git/Smart-Contract/code_files/bidding_contract.json' + +``` +**Response:** +``` +{"status":true,"message":"Smart contract generated successfully","result":{"binaryFilePath":"uploads/36b74eed-d3af-435d-8b72-e618ee998bf9_binaryCodePath","rawFilePath":"uploads/36b74eed-d3af-435d-8b72-e618ee998bf9_rawCodePath","schemaFilePath":"uploads/36b74eed-d3af-435d-8b72-e618ee998bf9_schemaFilePath"}} +``` +#### sample with invalid request (invalid did) +``` +curl -L -X POST 'http://localhost:8080/generate-smart-contract' \ +-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3Mzc3MjExODgsInN1YiI6ImJhZnlibWlheXN5YjVoYmRiNmNsc2s3am5jZGVqeHdvbXh1bXYzem9zNXQ1N2Y2Ynd6N251bXZhaW5hIn0.WU8P4UJiq-Jap_NhmHONhCah6d5xtoL6lHaH6ceUFJ4' \ +-F 'did=bafybmiaysyb5hbdb6clsk7jncdejxwomxumv3zos5t57f6bwz7numvanhb' \ +-F 'binaryCodePath=@/home/maneesha/Rubix-Git/Smart-Contract/code_files/bidding_contract.wasm' \ +-F 'rawCodePath=@/home/maneesha/Rubix-Git/Smart-Contract/code_files/lib.rs' \ +-F 'schemaFilePath=@/home/maneesha/Rubix-Git/Smart-Contract/code_files/bidding_contract.json' +``` +**Response:** +``` +{"status":false,"message":"User not found, sql: no rows in result set","result":null} +``` + +### Curl request to deploy Smart Contract +``` +curl -L -X POST "http://localhost:8080/deploy-smart-contract -H 'Authorization: Bearer ' -d '{"deployerAddr":"", "smartContractToken":"", "quorumType":<1 or 2>, "rbtAmount":,"comment":""}' +``` +#### sample with valid request +``` +curl -L -X POST http://localhost:8080/deploy-smart-contract -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3Mzc3MjExODgsInN1YiI6ImJhZnlibWlheXN5YjVoYmRiNmNsc2s3am5jZGVqeHdvbXh1bXYzem9zNXQ1N2Y2Ynd6N251bXZhaW5hIn0.WU8P4UJiq-Jap_NhmHONhCah6d5xtoL6lHaH6ceUFJ4' -d '{ + "deployerAddr":"bafybmiaysyb5hbdb6clsk7jncdejxwomxumv3zos5t57f6bwz7numvaina", + "smartContractToken":"QmWi85birn8KiNeVxRdH6mCWqVtimK2SUzecKhnKxgBt4H", + "quorumType":2, + "rbtAmount":3, + "comment":"testing sct deploy" +}' +``` +**Response:** +``` +{"status":true,"message":"Smart Contract Token Deployed successfully in 16.916829104s","result":null} +``` +#### sample with invalid request (invalid input to smartContractToken) +``` +curl -L -X POST http://localhost:8080/deploy-smart-contract -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3Mzc3MjExODgsInN1YiI6ImJhZnlibWlheXN5YjVoYmRiNmNsc2s3am5jZGVqeHdvbXh1bXYzem9zNXQ1N2Y2Ynd6N251bXZhaW5hIn0.WU8P4UJiq-Jap_NhmHONhCah6d5xtoL6lHaH6ceUFJ4' -d '{ + "deployerAddr":"bafybmiaysyb5hbdb6clsk7jncdejxwomxumv3zos5t57f6bwz7numvaina", + "smartContractToken":"QmWi85birn8KiNeVxRdH6mCWqVtimK2SUzecKhnKxgH", + "quorumType":2, + "rbtAmount":3, + "comment":"testing sct deploy" +}' +``` +**Response:** +``` +{"status":false,"message":"smart contract deployment failed: Invalid smart contract token","result":null} +``` + +### Curl request to execute Smart Contract +``` +curl -L -X POST http://localhost:8080/execute-smart-contract -H 'Authorization: Bearer ' -d '{ + "comment": "string", + "smartContractToken": "string", + "smartContractData": "string", + "executorAddr": "string", + "quorumType": 0 +}' + +``` +#### sample with valid request +``` +curl -L -X POST http://localhost:8080/execute-smart-contract -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3Mzc3ODc5NDQsInN1YiI6ImJhZnlibWlmcXBpMzZtdnpvY3FxcHNoM3J0anJqeTU0MzR3bHF2NG56N3pyNGVqcXgzcXVsNWdsMzZxIn0.yeC38PkFauWhOkOiWeyCAT-813O-KahTrr9ESZ8TF4Y' -d '{ + "comment": "testing nft transfer from wallet", + "smartContractToken": "QmWi85birn8KiNeVxRdH6mCWqVtimK2SUzecKhnKxgBt4H", + "smartContractData": "54", + "executorAddr": "bafybmifqpi36mvzocqqpsh3rtjrjy5434wlqv4nz7zr4ejqx3qul5gl36q", + "quorumType": 2 +}' +``` +**Response:** +``` +{"status":true,"message":"Smart Contract Token Executed successfully in 11.302358297s","result":null} +``` +#### sample with invalid request (invalid input format of quorumType) +``` +curl -L -X POST http://localhost:8080/execute-smart-contract -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3Mzc3ODc5NDQsInN1YiI6ImJhZnlibWlmcXBpMzZtdnpvY3FxcHNoM3J0anJqeTU0MzR3bHF2NG56N3pyNGVqcXgzcXVsNWdsMzZxIn0.yeC38PkFauWhOkOiWeyCAT-813O-KahTrr9ESZ8TF4Y' -d '{ + "comment": "testing nft transfer from wallet", + "smartContractToken": "QmWi85birn8KiNeVxRdH6mCWqVtimK2SUzecKhnKxgBt4H", + "smartContractData": "54", + "executorAddr": "bafybmifqpi36mvzocqqpsh3rtjrjy5434wlqv4nz7zr4ejqx3qul5gl36q", + "quorumType": "2" +}' ``` **Response:** ``` -{"error":"DID mismatch"} +{"status":false,"message":"Invalid input, json: cannot unmarshal string into Go struct field ExecuteSmartContractRequest.quorumType of type int","result":null} +``` + +### Curl request to subscribe Smart Contract +``` +curl -L -X POST "http://localhost:8080/subscribe-smart-contract -H 'Authorization: Bearer ' -d '{"did":"", "smartContractToken":}' + +``` +#### sample with valid request +``` +curl -L -X POST http://localhost:8080/subscribe-smart-contract -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3Mzc3ODc5NDQsInN1YiI6ImJhZnlibWlmcXBpMzZtdnpvY3FxcHNoM3J0anJqeTU0MzR3bHF2NG56N3pyNGVqcXgzcXVsNWdsMzZxIn0.yeC38PkFauWhOkOiWeyCAT-813O-KahTrr9ESZ8TF4Y' -d '{ + "did":"bafybmifqpi36mvzocqqpsh3rtjrjy5434wlqv4nz7zr4ejqx3qul5gl36q", + "smartContractToken":"QmWi85birn8KiNeVxRdH6mCWqVtimK2SUzecKhnKxgBt4H" +}' +``` +**Response:** +``` +{"status":true,"message":"Smart contract subscribed successfully","result":null} +``` +#### sample with invalid request (invalid input to smartContractToken) +``` +curl -L -X POST http://localhost:8080/subscribe-smart-contract -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3Mzc3ODc5NDQsInN1YiI6ImJhZnlibWlmcXBpMzZtdnpvY3FxcHNoM3J0anJqeTU0MzR3bHF2NG56N3pyNGVqcXgzcXVsNWdsMzZxIn0.yeC38PkFauWhOkOiWeyCAT-813O-KahTrr9ESZ8TF4Y' -d '{ + "did":"bafybmifqpi36mvzocqqpsh3rtjrjy5434wlqv4nz7zr4ejqx3qul5gl36q", + "smartContractToken":"QmWi85birn8KiNeVxRdH6mCWqVtimK2SUzecKhnKxgH" +}' +``` +**Response:** ``` +{"status":false,"message":"failed to subscribe SmartContract, Invalid smart contract token","result":null} +``` \ No newline at end of file diff --git a/docs/docs.go b/docs/docs.go index c498e18..e430291 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -1,5 +1,4 @@ -// Code generated by swaggo/swag. DO NOT EDIT. - +// Package docs Code generated by swaggo/swag. DO NOT EDIT package docs import "github.com/swaggo/swag" @@ -59,22 +58,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -166,22 +162,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -227,22 +220,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -344,22 +334,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -405,22 +392,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -473,22 +457,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -534,22 +515,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -621,22 +599,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -680,20 +655,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": true + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -737,20 +711,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": true + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -794,20 +767,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": true + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -851,20 +823,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": true + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -908,20 +879,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": true + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -1056,22 +1026,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -1117,22 +1084,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -1176,20 +1140,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": true + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -1235,20 +1198,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": true + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -1294,22 +1256,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -1348,19 +1307,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/main.SignRequest" + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -1406,22 +1365,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -1467,22 +1423,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -1528,22 +1481,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -1605,20 +1555,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": true + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -1626,6 +1575,18 @@ const docTemplate = `{ } }, "definitions": { + "main.BasicResponse": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "result": {}, + "status": { + "type": "boolean" + } + } + }, "main.CreateFTRequest": { "type": "object", "properties": { @@ -1722,7 +1683,7 @@ const docTemplate = `{ "quorumType": { "type": "integer" }, - "rbtamount": { + "rbtAmount": { "type": "integer" }, "smartContractToken": { diff --git a/docs/swagger.json b/docs/swagger.json index 092bf9b..5758b47 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -52,22 +52,19 @@ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -159,22 +156,19 @@ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -220,22 +214,19 @@ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -337,22 +328,19 @@ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -398,22 +386,19 @@ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -466,22 +451,19 @@ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -527,22 +509,19 @@ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -614,22 +593,19 @@ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -673,20 +649,19 @@ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": true + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -730,20 +705,19 @@ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": true + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -787,20 +761,19 @@ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": true + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -844,20 +817,19 @@ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": true + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -901,20 +873,19 @@ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": true + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -1049,22 +1020,19 @@ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -1110,22 +1078,19 @@ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -1169,20 +1134,19 @@ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": true + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -1228,20 +1192,19 @@ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": true + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -1287,22 +1250,19 @@ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -1341,19 +1301,19 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/main.SignRequest" + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -1399,22 +1359,19 @@ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -1460,22 +1417,19 @@ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -1521,22 +1475,19 @@ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -1598,20 +1549,19 @@ "200": { "description": "OK", "schema": { - "type": "object", - "additionalProperties": true + "$ref": "#/definitions/main.BasicResponse" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } }, "401": { "description": "Unauthorized", "schema": { - "$ref": "#/definitions/main.ErrorResponse" + "$ref": "#/definitions/main.BasicResponse" } } } @@ -1619,6 +1569,18 @@ } }, "definitions": { + "main.BasicResponse": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "result": {}, + "status": { + "type": "boolean" + } + } + }, "main.CreateFTRequest": { "type": "object", "properties": { @@ -1715,7 +1677,7 @@ "quorumType": { "type": "integer" }, - "rbtamount": { + "rbtAmount": { "type": "integer" }, "smartContractToken": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index e6e735d..566a70e 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1,5 +1,13 @@ basePath: / definitions: + main.BasicResponse: + properties: + message: + type: string + result: {} + status: + type: boolean + type: object main.CreateFTRequest: properties: did: @@ -62,7 +70,7 @@ definitions: type: string quorumType: type: integer - rbtamount: + rbtAmount: type: integer smartContractToken: type: string @@ -233,17 +241,15 @@ paths: "200": description: OK schema: - additionalProperties: - type: string - type: object + $ref: '#/definitions/main.BasicResponse' "400": description: Bad Request schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' "401": description: Unauthorized schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' security: - BearerAuth: [] summary: Add peer to a DID quorum @@ -302,17 +308,15 @@ paths: "200": description: OK schema: - additionalProperties: - type: string - type: object + $ref: '#/definitions/main.BasicResponse' "400": description: Bad Request schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' "401": description: Unauthorized schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' security: - BearerAuth: [] summary: Create fungible tokens @@ -341,17 +345,15 @@ paths: "200": description: OK schema: - additionalProperties: - type: string - type: object + $ref: '#/definitions/main.BasicResponse' "400": description: Bad Request schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' "401": description: Unauthorized schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' security: - BearerAuth: [] summary: Create a non-fungible token @@ -417,17 +419,15 @@ paths: "200": description: OK schema: - additionalProperties: - type: string - type: object + $ref: '#/definitions/main.BasicResponse' "400": description: Bad Request schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' "401": description: Unauthorized schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' security: - BearerAuth: [] summary: Deploy a smart contract @@ -456,17 +456,15 @@ paths: "200": description: OK schema: - additionalProperties: - type: string - type: object + $ref: '#/definitions/main.BasicResponse' "400": description: Bad Request schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' "401": description: Unauthorized schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' security: - BearerAuth: [] summary: Deploy an NFT @@ -500,17 +498,15 @@ paths: "200": description: OK schema: - additionalProperties: - type: string - type: object + $ref: '#/definitions/main.BasicResponse' "400": description: Bad Request schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' "401": description: Unauthorized schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' security: - BearerAuth: [] summary: Execute a smart contract @@ -539,17 +535,15 @@ paths: "200": description: OK schema: - additionalProperties: - type: string - type: object + $ref: '#/definitions/main.BasicResponse' "400": description: Bad Request schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' "401": description: Unauthorized schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' security: - BearerAuth: [] summary: Execute an NFT @@ -598,17 +592,15 @@ paths: "200": description: OK schema: - additionalProperties: - type: string - type: object + $ref: '#/definitions/main.BasicResponse' "400": description: Bad Request schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' "401": description: Unauthorized schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' security: - BearerAuth: [] summary: Generate a smart contract @@ -636,16 +628,15 @@ paths: "200": description: OK schema: - additionalProperties: true - type: object + $ref: '#/definitions/main.BasicResponse' "400": description: Bad Request schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' "401": description: Unauthorized schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' security: - BearerAuth: [] summary: Get all fungible tokens @@ -673,16 +664,15 @@ paths: "200": description: OK schema: - additionalProperties: true - type: object + $ref: '#/definitions/main.BasicResponse' "400": description: Bad Request schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' "401": description: Unauthorized schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' security: - BearerAuth: [] summary: Get all NFTs @@ -710,16 +700,15 @@ paths: "200": description: OK schema: - additionalProperties: true - type: object + $ref: '#/definitions/main.BasicResponse' "400": description: Bad Request schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' "401": description: Unauthorized schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' security: - BearerAuth: [] summary: Get fungible token chain @@ -747,16 +736,15 @@ paths: "200": description: OK schema: - additionalProperties: true - type: object + $ref: '#/definitions/main.BasicResponse' "400": description: Bad Request schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' "401": description: Unauthorized schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' security: - BearerAuth: [] summary: Get NFT details @@ -784,16 +772,15 @@ paths: "200": description: OK schema: - additionalProperties: true - type: object + $ref: '#/definitions/main.BasicResponse' "400": description: Bad Request schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' "401": description: Unauthorized schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' security: - BearerAuth: [] summary: Get NFT chain @@ -879,17 +866,15 @@ paths: "200": description: OK schema: - additionalProperties: - type: string - type: object + $ref: '#/definitions/main.BasicResponse' "400": description: Bad Request schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' "401": description: Unauthorized schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' security: - BearerAuth: [] summary: Unpledge RBT tokens @@ -918,17 +903,15 @@ paths: "200": description: OK schema: - additionalProperties: - type: string - type: object + $ref: '#/definitions/main.BasicResponse' "400": description: Bad Request schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' "401": description: Unauthorized schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' security: - BearerAuth: [] summary: Register DID @@ -956,16 +939,15 @@ paths: "200": description: OK schema: - additionalProperties: true - type: object + $ref: '#/definitions/main.BasicResponse' "400": description: Bad Request schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' "401": description: Unauthorized schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' security: - BearerAuth: [] summary: Get RBT balance @@ -994,16 +976,15 @@ paths: "200": description: OK schema: - additionalProperties: true - type: object + $ref: '#/definitions/main.BasicResponse' "400": description: Bad Request schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' "401": description: Unauthorized schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' security: - BearerAuth: [] summary: Request a transaction @@ -1032,17 +1013,15 @@ paths: "200": description: OK schema: - additionalProperties: - type: string - type: object + $ref: '#/definitions/main.BasicResponse' "400": description: Bad Request schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' "401": description: Unauthorized schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' security: - BearerAuth: [] summary: Setup Quorum @@ -1066,15 +1045,15 @@ paths: "200": description: OK schema: - $ref: '#/definitions/main.SignRequest' + $ref: '#/definitions/main.BasicResponse' "400": description: Bad Request schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' "401": description: Unauthorized schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' security: - BearerAuth: [] summary: Sign a transaction @@ -1103,17 +1082,15 @@ paths: "200": description: OK schema: - additionalProperties: - type: string - type: object + $ref: '#/definitions/main.BasicResponse' "400": description: Bad Request schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' "401": description: Unauthorized schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' security: - BearerAuth: [] summary: Subscribe to an NFT @@ -1142,17 +1119,15 @@ paths: "200": description: OK schema: - additionalProperties: - type: string - type: object + $ref: '#/definitions/main.BasicResponse' "400": description: Bad Request schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' "401": description: Unauthorized schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' security: - BearerAuth: [] summary: Create test RBT tokens @@ -1181,17 +1156,15 @@ paths: "200": description: OK schema: - additionalProperties: - type: string - type: object + $ref: '#/definitions/main.BasicResponse' "400": description: Bad Request schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' "401": description: Unauthorized schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' security: - BearerAuth: [] summary: Transfer fungible tokens @@ -1231,16 +1204,15 @@ paths: "200": description: OK schema: - additionalProperties: true - type: object + $ref: '#/definitions/main.BasicResponse' "400": description: Bad Request schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' "401": description: Unauthorized schema: - $ref: '#/definitions/main.ErrorResponse' + $ref: '#/definitions/main.BasicResponse' security: - BearerAuth: [] summary: Get transactions by DID diff --git a/main.go b/main.go index 73776d8..1633d83 100644 --- a/main.go +++ b/main.go @@ -180,11 +180,11 @@ type ExecuteNFTRequest struct { } type DeploySmartContractRequest struct { - SmartContractToken string - DeployerAddr string - RBTAmount int - QuorumType int - Comment string + SmartContractToken string `json:"smartContractToken"` + DeployerAddr string `json:"deployerAddr"` + RBTAmount int `json:"rbtAmount"` + QuorumType int `json:"quorumType"` + Comment string `json:"comment"` } type GenerateSmartContractRequest struct { @@ -202,6 +202,19 @@ type ExecuteSmartContractRequest struct { SmartContractData string `json:"smartContractData" binding:"required"` } +// subscribe SmartContract request +type SubscribeSmartContractRequest struct { + DID string `json:"did"` + SmartContractToken string `json:"smartContractToken"` +} + +// general response by all handlers +type BasicResponse struct { + Status bool `json:"status"` + Message string `json:"message"` + Result interface{} `json:"result"` +} + // @title Wallet API Documentation // @version 1.0 // @description API documentation for the Wallet application. @@ -268,6 +281,7 @@ func main() { r.POST("/generate-smart-contract", generateSmartContractHandler) r.POST("/deploy-smart-contract", deploySmartContractHandler) r.POST("/execute-smart-contract", executeSmartContractHandler) + r.POST("/subscribe-smart-contract", subscribeSmartContractHandler) r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) @@ -615,23 +629,12 @@ func createWalletHandler(c *gin.Context) { mnemonic, _ := bip39.NewMnemonic(entropy) privateKey, publicKey := generateKeyPair(mnemonic) - pubKeyStr := hex.EncodeToString(publicKey.SerializeCompressed()) + pubKeyStr := hex.EncodeToString(publicKey.SerializeUncompressed()) // Request user DID from Rubix node did, err := didRequest(pubKeyStr, strconv.Itoa(req.Port)) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Invalid request, " + err.Error()}) - fmt.Println(err) - // Add a newline to the response body - c.Writer.Write([]byte("\n")) - return - } - - // Verify the returned public key - pubKeyBytes, _ := hex.DecodeString(pubKeyStr) - reconstructedPubKey, _ := secp256k1.ParsePubKey(pubKeyBytes) - if !publicKey.IsEqual(reconstructedPubKey) { - c.JSON(http.StatusBadRequest, gin.H{"error": "Public key mismatch \n"}) // Add a newline to the response body c.Writer.Write([]byte("\n")) return @@ -659,16 +662,21 @@ func createWalletHandler(c *gin.Context) { // @Accept json // @Produce json // @Param request body ReqToRubixNode true "DID" -// @Success 200 {object} map[string]string -// @Failure 400 {object} ErrorResponse -// @Failure 401 {object} ErrorResponse +// @Success 200 {object} BasicResponse +// @Failure 400 {object} BasicResponse +// @Failure 401 {object} BasicResponse // @Security BearerAuth // @Param Authorization header string true "Authorization token (Bearer )" // @Router /register_did [post] func registerDIDHandler(c *gin.Context) { + basicResponse := BasicResponse{ + Status: false, + } tokenString := c.GetHeader("Authorization") if tokenString == "" { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Token is required"}) + basicResponse.Message = "Token is required" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -683,7 +691,9 @@ func registerDIDHandler(c *gin.Context) { }) if err != nil || !token.Valid { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"}) + basicResponse.Message = "Invalid token " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -692,20 +702,25 @@ func registerDIDHandler(c *gin.Context) { claims := token.Claims.(jwt.MapClaims) did, ok := claims["sub"].(string) if !ok { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token: missing or invalid DID"}) + basicResponse.Message = "Invalid token: missing or invalid DID" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) return } - // Optionally, verify the DID exists in the database + // verify the DID exists in the database user, err := storage.GetUserByDID(did) if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{"error": "User not found"}) + basicResponse.Message = "User not found" + c.JSON(http.StatusInternalServerError, basicResponse) + c.Writer.Write([]byte("\n")) return } var req ReqToRubixNode if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid input"}) + basicResponse.Message = "Invalid input" + c.JSON(http.StatusBadRequest, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) return @@ -713,36 +728,45 @@ func registerDIDHandler(c *gin.Context) { // Ensure the DID from the token matches the one in the request body if req.DID != did { - c.JSON(http.StatusForbidden, gin.H{"error": "DID mismatch"}) + basicResponse.Message = "DID mismatch" + c.JSON(http.StatusForbidden, basicResponse) c.Writer.Write([]byte("\n")) return } - // // Initialize or retrieve an existing channel for the DID - // didChannel, _ := getOrCreateDIDChannel(did) - response, err := registerDIDRequest(did, strconv.Itoa(user.Port)) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "error": err.Error(), - }) + basicResponse.Message = err.Error() + c.JSON(http.StatusInternalServerError, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) return } - respMsg, err := callSignHandler(response, did) - if err != nil { - log.Println("failed to call sign handler, err:", err.Error()) - c.JSON(http.StatusBadRequest, gin.H{ - "error": err.Error(), - }) + respMsg := response["message"].(string) + // sign, if the message says 'signature needed' + if strings.Contains(respMsg, "Signature needed") { + respMsg, err = callSignHandler(response, did) + if err != nil { + basicResponse.Message = err.Error() + c.JSON(http.StatusInternalServerError, basicResponse) + // Add a newline to the response body if required + c.Writer.Write([]byte("\n")) + return + } + } else { + basicResponse.Status = response["status"].(bool) + basicResponse.Message = respMsg + c.JSON(http.StatusInternalServerError, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) return } - c.JSON(http.StatusOK, respMsg) + // prepare response + basicResponse.Status = true + basicResponse.Message = respMsg + c.JSON(http.StatusOK, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) } @@ -753,16 +777,21 @@ func registerDIDHandler(c *gin.Context) { // @Accept json // @Produce json // @Param request body ReqToRubixNode true "DID" -// @Success 200 {object} map[string]string -// @Failure 400 {object} ErrorResponse -// @Failure 401 {object} ErrorResponse +// @Success 200 {object} BasicResponse +// @Failure 400 {object} BasicResponse +// @Failure 401 {object} BasicResponse // @Security BearerAuth // @Param Authorization header string true "Authorization token (Bearer )" // @Router /setup_quorum [post] func setupQuorumHandler(c *gin.Context) { + basicResponse := BasicResponse{ + Status: false, + } tokenString := c.GetHeader("Authorization") if tokenString == "" { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Token is required"}) + basicResponse.Message = "Token is required" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -777,7 +806,9 @@ func setupQuorumHandler(c *gin.Context) { }) if err != nil || !token.Valid { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"}) + basicResponse.Message = "Invalid token, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -786,20 +817,25 @@ func setupQuorumHandler(c *gin.Context) { claims := token.Claims.(jwt.MapClaims) did, ok := claims["sub"].(string) if !ok { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token: missing or invalid DID"}) + basicResponse.Message = "Invalid token: missing or invalid DID" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) return } // Optionally, verify the DID exists in the database user, err := storage.GetUserByDID(did) if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{"error": "User not found"}) + basicResponse.Message = "User not found, " + err.Error() + c.JSON(http.StatusInternalServerError, basicResponse) + c.Writer.Write([]byte("\n")) return } var req ReqToRubixNode if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid input"}) + basicResponse.Message = "Invalid input" + c.JSON(http.StatusBadRequest, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) return @@ -807,21 +843,25 @@ func setupQuorumHandler(c *gin.Context) { // Ensure the DID from the token matches the one in the request body if req.DID != did { - c.JSON(http.StatusForbidden, gin.H{"error": "DID mismatch"}) + basicResponse.Message = "DID mismatch" + c.JSON(http.StatusForbidden, basicResponse) c.Writer.Write([]byte("\n")) return } resp, err := setupQuorumRequest(req.DID, strconv.Itoa(user.Port)) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "error": err.Error(), - }) + basicResponse.Message = err.Error() + c.JSON(http.StatusInternalServerError, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) + return } - c.JSON(http.StatusOK, resp) + // prepare response + basicResponse.Status = true + basicResponse.Message = resp + c.JSON(http.StatusOK, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) } @@ -883,16 +923,21 @@ func setupQuorumRequest(did string, rubixNodePort string) (string, error) { // @Accept json // @Produce json // @Param request body DIDPeerMap true "Peer details" -// @Success 200 {object} map[string]string -// @Failure 400 {object} ErrorResponse -// @Failure 401 {object} ErrorResponse +// @Success 200 {object} BasicResponse +// @Failure 400 {object} BasicResponse +// @Failure 401 {object} BasicResponse // @Security BearerAuth // @Param Authorization header string true "Authorization token (Bearer )" // @Router /add_peer [post] func addPeerHandler(c *gin.Context) { + basicResponse := BasicResponse{ + Status: false, + } tokenString := c.GetHeader("Authorization") if tokenString == "" { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Token is required"}) + basicResponse.Message = "Token is required" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -907,7 +952,9 @@ func addPeerHandler(c *gin.Context) { }) if err != nil || !token.Valid { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"}) + basicResponse.Message = "Invalid token, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -916,20 +963,25 @@ func addPeerHandler(c *gin.Context) { claims := token.Claims.(jwt.MapClaims) did, ok := claims["sub"].(string) if !ok { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token: missing or invalid DID"}) + basicResponse.Message = "Invalid token: missing or invalid DID" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) return } // Optionally, verify the DID exists in the database user, err := storage.GetUserByDID(did) if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{"error": "User not found"}) + basicResponse.Message = "User not found, " + err.Error() + c.JSON(http.StatusInternalServerError, basicResponse) + c.Writer.Write([]byte("\n")) return } var req DIDPeerMap if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid input"}) + basicResponse.Message = "Invalid input, " + err.Error() + c.JSON(http.StatusBadRequest, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) return @@ -937,21 +989,25 @@ func addPeerHandler(c *gin.Context) { // Ensure the DID from the token matches the one in the request body if req.SelfDID != did { - c.JSON(http.StatusForbidden, gin.H{"error": "DID mismatch"}) + basicResponse.Message = "DID mismatch" + c.JSON(http.StatusForbidden, basicResponse) c.Writer.Write([]byte("\n")) return } resp, err := addPeerRequest(req, strconv.Itoa(user.Port)) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "error": err.Error(), - }) + basicResponse.Message = err.Error() + c.JSON(http.StatusInternalServerError, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) + return } - c.JSON(http.StatusOK, resp) + // prepare response + basicResponse.Status = true + basicResponse.Message = resp + c.JSON(http.StatusOK, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) } @@ -1009,41 +1065,53 @@ func addPeerRequest(data DIDPeerMap, rubixNodePort string) (string, error) { // @Accept json // @Produce json // @Param request body SignRequest true "Transaction signing request" -// @Success 200 {object} SignResponse -// @Failure 400 {object} ErrorResponse -// @Failure 401 {object} ErrorResponse +// @Success 200 {object} BasicResponse +// @Failure 400 {object} BasicResponse +// @Failure 401 {object} BasicResponse // @Security BearerAuth // @Router /sign [post] func signTransactionHandler(c *gin.Context) { + basicResponse := BasicResponse{ + Status: false, + } var req SignRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid input"}) + basicResponse.Message = "Invalid input, " + err.Error() + c.JSON(http.StatusBadRequest, basicResponse) + c.Writer.Write([]byte("\n")) return } // Decode the Base64 string back to the byte array decodedBytes, err := base64.StdEncoding.DecodeString(req.Data.Hash) if err != nil { - fmt.Println("Error decoding Base64 string:", err) + basicResponse.Message = "Error decoding Base64 string, " + err.Error() + c.JSON(http.StatusInternalServerError, basicResponse) + c.Writer.Write([]byte("\n")) return } - log.Println("2-decoded bytes:", decodedBytes) user, err := storage.GetUserByDID(req.DID) if err != nil { - c.JSON(http.StatusNotFound, gin.H{"error": "User not found"}) + basicResponse.Message = "User not found, " + err.Error() + c.JSON(http.StatusNotFound, basicResponse) + c.Writer.Write([]byte("\n")) return } signature, err := signData(user.PrivateKey.ToECDSA(), decodedBytes) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to sign data"}) + basicResponse.Message = err.Error() + c.JSON(http.StatusInternalServerError, basicResponse) + c.Writer.Write([]byte("\n")) return } // Verify signature if !verifySignature(user.PublicKey, decodedBytes, signature) { - c.JSON(http.StatusInternalServerError, gin.H{"error": "Signature verification failed"}) + basicResponse.Message = "Signature verification failed" + c.JSON(http.StatusInternalServerError, basicResponse) + c.Writer.Write([]byte("\n")) return } @@ -1057,11 +1125,17 @@ func signTransactionHandler(c *gin.Context) { } resp, err := signResponse(signResp, user.Port) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + basicResponse.Message = err.Error() + c.JSON(http.StatusInternalServerError, basicResponse) + c.Writer.Write([]byte("\n")) return } - c.JSON(http.StatusOK, resp) + // prepare response + basicResponse.Status = resp["status"].(bool) + basicResponse.Message = resp["message"].(string) + basicResponse.Result = resp["result"] + c.JSON(http.StatusOK, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) } @@ -1073,13 +1147,6 @@ func callSignHandler(response map[string]interface{}, did string) (string, error id := respResult["id"].(string) mode := respResult["mode"].(float64) - // Decode the Base64 string back to the byte array - decodedBytes, err := base64.StdEncoding.DecodeString(hashStr) - if err != nil { - fmt.Println("Error decoding Base64 string:", err) - } - log.Println("1-decoded bytes:", decodedBytes) - // prepare sign request signReq := SignRequest{ DID: did, @@ -1117,7 +1184,7 @@ func callSignHandler(response map[string]interface{}, did string) (string, error log.Printf("Error reading response body: %v", err) return "", err } - log.Printf("Raw response from /sign: %s", string(body)) + if len(body) == 0 { return "", fmt.Errorf("empty response from /sign") } @@ -1146,16 +1213,21 @@ func callSignHandler(response map[string]interface{}, did string) (string, error // @Accept json // @Produce json // @Param request body TxnRequest true "Transaction details" -// @Success 200 {object} map[string]interface{} -// @Failure 400 {object} ErrorResponse -// @Failure 401 {object} ErrorResponse +// @Success 200 {object} BasicResponse +// @Failure 400 {object} BasicResponse +// @Failure 401 {object} BasicResponse // @Security BearerAuth // @Param Authorization header string true "Authorization token (Bearer )" // @Router /request_txn [post] func requestTransactionHandler(c *gin.Context) { + basicResponse := BasicResponse{ + Status: false, + } tokenString := c.GetHeader("Authorization") if tokenString == "" { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Token is required"}) + basicResponse.Message = "Token is required" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -1170,7 +1242,9 @@ func requestTransactionHandler(c *gin.Context) { }) if err != nil || !token.Valid { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"}) + basicResponse.Message = "Invalid token, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -1179,53 +1253,80 @@ func requestTransactionHandler(c *gin.Context) { claims := token.Claims.(jwt.MapClaims) did, ok := claims["sub"].(string) if !ok { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token: missing or invalid DID"}) + basicResponse.Message = "Invalid token: missing or invalid DID" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) return } // Optionally, verify the DID exists in the database user, err := storage.GetUserByDID(did) if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{"error": "User not found"}) + basicResponse.Message = "User not found, " + err.Error() + c.JSON(http.StatusInternalServerError, basicResponse) + c.Writer.Write([]byte("\n")) return } var req TxnRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid input"}) + basicResponse.Message = "Invalid input, " + err.Error() + c.JSON(http.StatusBadRequest, basicResponse) + c.Writer.Write([]byte("\n")) return } // Ensure the DID from the token matches the one in the request body if req.DID != did { - c.JSON(http.StatusForbidden, gin.H{"error": "DID mismatch"}) + basicResponse.Message = "DID mismatch" + c.JSON(http.StatusForbidden, basicResponse) c.Writer.Write([]byte("\n")) return } jwtToken, err := GenerateJWT(req.DID, req.ReceiverDID, req.RBTAmount) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to generate JWT"}) + basicResponse.Message = "Failed to generate JWT, " + err.Error() + c.JSON(http.StatusInternalServerError, basicResponse) + c.Writer.Write([]byte("\n")) return } isValid, claims, err := VerifyToken(jwtToken, user.PublicKey.ToECDSA()) if !isValid { - c.JSON(http.StatusUnauthorized, gin.H{"error": err}) + basicResponse.Message = err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) return } log.Println("Token claims:", claims) - result := SendAuthRequest(jwtToken, strconv.Itoa(user.Port)) + response := SendAuthRequest(jwtToken, strconv.Itoa(user.Port)) - // sign response - respMsg, err := callSignHandler(result, did) + respMsg := response["message"].(string) + // sign, if the message says 'signature needed' + if strings.Contains(respMsg, "Signature needed") { + respMsg, err = callSignHandler(response, did) + if err != nil { + basicResponse.Message = err.Error() + c.JSON(http.StatusInternalServerError, basicResponse) + // Add a newline to the response body if required + c.Writer.Write([]byte("\n")) + return + } + } else { + basicResponse.Status = response["status"].(bool) + basicResponse.Message = respMsg + c.JSON(http.StatusInternalServerError, basicResponse) + // Add a newline to the response body if required + c.Writer.Write([]byte("\n")) + return + } - c.JSON(http.StatusOK, gin.H{ - "did": req.DID, - "jwt": jwtToken, - "status": respMsg, - }) + // prepare response + basicResponse.Status = true + basicResponse.Message = respMsg + c.JSON(http.StatusOK, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) } @@ -1236,16 +1337,21 @@ func requestTransactionHandler(c *gin.Context) { // @Accept json // @Produce json // @Param did query string true "DID of the user" -// @Success 200 {object} map[string]interface{} -// @Failure 400 {object} ErrorResponse -// @Failure 401 {object} ErrorResponse +// @Success 200 {object} BasicResponse +// @Failure 400 {object} BasicResponse +// @Failure 401 {object} BasicResponse // @Security BearerAuth // @Param Authorization header string true "Authorization token (Bearer )" // @Router /request_balance [get] func requestBalanceHandler(c *gin.Context) { + basicResponse := BasicResponse{ + Status: false, + } tokenString := c.GetHeader("Authorization") if tokenString == "" { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Token is required"}) + basicResponse.Message = "Token is required" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -1260,7 +1366,9 @@ func requestBalanceHandler(c *gin.Context) { }) if err != nil || !token.Valid { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"}) + basicResponse.Message = "Invalid token, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -1269,40 +1377,52 @@ func requestBalanceHandler(c *gin.Context) { claims := token.Claims.(jwt.MapClaims) did, ok := claims["sub"].(string) if !ok { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token: missing or invalid DID"}) + basicResponse.Message = "Invalid token: missing or invalid DID" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) return } // Optionally, verify the DID exists in the database user, err := storage.GetUserByDID(did) if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{"error": "User not found"}) + basicResponse.Message = "User not found" + c.JSON(http.StatusInternalServerError, basicResponse) + c.Writer.Write([]byte("\n")) return } userDID := c.Query("did") if userDID == "" { - c.JSON(http.StatusBadRequest, gin.H{"error": "Missing required parameter: did"}) + basicResponse.Message = "Missing required parameter: did" + c.JSON(http.StatusBadRequest, basicResponse) + c.Writer.Write([]byte("\n")) return } // Ensure the DID from the token matches the one in the request body if userDID != did { - c.JSON(http.StatusForbidden, gin.H{"error": "DID mismatch"}) + basicResponse.Message = "DID mismatch" + c.JSON(http.StatusForbidden, basicResponse) c.Writer.Write([]byte("\n")) return } result, err := RequestBalance(did, strconv.Itoa(user.Port)) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": err}) + basicResponse.Message = err.Error() + c.JSON(http.StatusBadRequest, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) return } - c.JSON(http.StatusOK, result) + // prepare response + basicResponse.Status = result["status"].(bool) + basicResponse.Message = result["message"].(string) + basicResponse.Result = result["account_info"] + c.JSON(http.StatusOK, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) } @@ -1313,16 +1433,21 @@ func requestBalanceHandler(c *gin.Context) { // @Accept json // @Produce json // @Param request body GenerateTestRBTRequest true "Request to generate test RBTs" -// @Success 200 {object} map[string]string -// @Failure 400 {object} ErrorResponse -// @Failure 401 {object} ErrorResponse +// @Success 200 {object} BasicResponse +// @Failure 400 {object} BasicResponse +// @Failure 401 {object} BasicResponse // @Security BearerAuth // @Param Authorization header string true "Authorization token (Bearer )" // @Router /testrbt/create [post] func createTestRBTHandler(c *gin.Context) { + basicResponse := BasicResponse{ + Status: false, + } tokenString := c.GetHeader("Authorization") if tokenString == "" { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Token is required"}) + basicResponse.Message = "Token is required" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -1337,7 +1462,9 @@ func createTestRBTHandler(c *gin.Context) { }) if err != nil || !token.Valid { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"}) + basicResponse.Message = "Invalid token" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -1346,21 +1473,25 @@ func createTestRBTHandler(c *gin.Context) { claims := token.Claims.(jwt.MapClaims) did, ok := claims["sub"].(string) if !ok { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token: missing or invalid DID"}) + basicResponse.Message = "Invalid token: missing or invalid DID" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) return } // Optionally, verify the DID exists in the database user, err := storage.GetUserByDID(did) if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{"error": "User not found"}) + basicResponse.Message = "User not found, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) c.Writer.Write([]byte("\n")) return } var req GenerateTestRBTRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid input"}) + basicResponse.Message = "Invalid input, " + err.Error() + c.JSON(http.StatusBadRequest, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) return @@ -1368,25 +1499,45 @@ func createTestRBTHandler(c *gin.Context) { // Ensure the DID from the token matches the one in the request body if req.DID != did { - c.JSON(http.StatusForbidden, gin.H{"error": "DID mismatch"}) + basicResponse.Message = "DID mismatch" + c.JSON(http.StatusForbidden, basicResponse) c.Writer.Write([]byte("\n")) return } - resp, err := GenerateTestRBT(req, strconv.Itoa(user.Port)) + response, err := GenerateTestRBT(req, strconv.Itoa(user.Port)) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "error": err.Error(), - }) + basicResponse.Message = err.Error() + c.JSON(http.StatusBadRequest, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) + return } - log.Println("response body:", resp) - // sign response - respMsg, err := callSignHandler(resp, did) + respMsg := response["message"].(string) + // sign, if the message says 'signature needed' + if strings.Contains(respMsg, "Signature needed") { + respMsg, err = callSignHandler(response, did) + if err != nil { + basicResponse.Message = err.Error() + c.JSON(http.StatusInternalServerError, basicResponse) + // Add a newline to the response body if required + c.Writer.Write([]byte("\n")) + return + } + } else { + basicResponse.Status = response["status"].(bool) + basicResponse.Message = respMsg + c.JSON(http.StatusInternalServerError, basicResponse) + // Add a newline to the response body if required + c.Writer.Write([]byte("\n")) + return + } - c.JSON(http.StatusOK, respMsg) + // prepare response + basicResponse.Status = true + basicResponse.Message = respMsg + c.JSON(http.StatusOK, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) } @@ -1400,16 +1551,21 @@ func createTestRBTHandler(c *gin.Context) { // @Param role query string false "Role in the transaction (e.g., sender, receiver)" // @Param startDate query string false "Start date for filtering transactions" // @Param endDate query string false "End date for filtering transactions" -// @Success 200 {object} map[string]interface{} -// @Failure 400 {object} ErrorResponse -// @Failure 401 {object} ErrorResponse +// @Success 200 {object} BasicResponse +// @Failure 400 {object} BasicResponse +// @Failure 401 {object} BasicResponse // @Security BearerAuth // @Param Authorization header string true "Authorization token (Bearer )" // @Router /txn/by_did [get] func getTxnByDIDHandler(c *gin.Context) { + basicResponse := BasicResponse{ + Status: false, + } tokenString := c.GetHeader("Authorization") if tokenString == "" { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Token is required"}) + basicResponse.Message = "Token is required" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -1424,7 +1580,9 @@ func getTxnByDIDHandler(c *gin.Context) { }) if err != nil || !token.Valid { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"}) + basicResponse.Message = "Invalid token, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -1433,14 +1591,17 @@ func getTxnByDIDHandler(c *gin.Context) { claims := token.Claims.(jwt.MapClaims) did, ok := claims["sub"].(string) if !ok { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token: missing or invalid DID"}) + basicResponse.Message = "Invalid token: missing or invalid DID" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) return } // Optionally, verify the DID exists in the database user, err := storage.GetUserByDID(did) if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{"error": "User not found"}) + basicResponse.Message = "User nopt found, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) c.Writer.Write([]byte("\n")) return } @@ -1448,13 +1609,16 @@ func getTxnByDIDHandler(c *gin.Context) { userDID := c.Query("did") if userDID == "" { - c.JSON(http.StatusBadRequest, gin.H{"error": "Missing required parameter: did \n"}) + basicResponse.Message = "Missing required parameter: did" + c.JSON(http.StatusInternalServerError, basicResponse) + c.Writer.Write([]byte("\n")) return } // Ensure the DID from the token matches the one in the request body if userDID != did { - c.JSON(http.StatusForbidden, gin.H{"error": "DID mismatch"}) + basicResponse.Message = "DID mismatch" + c.JSON(http.StatusForbidden, basicResponse) c.Writer.Write([]byte("\n")) return } @@ -1465,13 +1629,18 @@ func getTxnByDIDHandler(c *gin.Context) { result, err := RequestTxnsByDID(did, role, startDate, endDate, strconv.Itoa(user.Port)) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": err}) + basicResponse.Message = err.Error() + c.JSON(http.StatusBadRequest, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) return } - c.JSON(http.StatusOK, result) + // prepare response + basicResponse.Status = result["status"].(bool) + basicResponse.Message = result["message"].(string) + basicResponse.Result = result["TxnDetails"] + c.JSON(http.StatusOK, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) } @@ -1802,8 +1971,6 @@ func registerDIDRequest(did string, rubixNodePort string) (map[string]interface{ return nil, err } - fmt.Println("response data after unmarshal : ", response) - respMsg := response["message"].(string) respStatus := response["status"].(bool) @@ -1820,16 +1987,21 @@ func registerDIDRequest(did string, rubixNodePort string) (map[string]interface{ // @Accept json // @Produce json // @Param request body ReqToRubixNode true "Request to unpledge RBTs" -// @Success 200 {object} map[string]string -// @Failure 400 {object} ErrorResponse -// @Failure 401 {object} ErrorResponse +// @Success 200 {object} BasicResponse +// @Failure 400 {object} BasicResponse +// @Failure 401 {object} BasicResponse // @Security BearerAuth // @Param Authorization header string true "Authorization token (Bearer )" // @Router /rbt/unpledge [post] func unpledgeRBTHandler(c *gin.Context) { + basicResponse := BasicResponse{ + Status: false, + } tokenString := c.GetHeader("Authorization") if tokenString == "" { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Token is required"}) + basicResponse.Message = "Token is required" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -1844,7 +2016,9 @@ func unpledgeRBTHandler(c *gin.Context) { }) if err != nil || !token.Valid { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"}) + basicResponse.Message = "Invalid token, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -1853,21 +2027,25 @@ func unpledgeRBTHandler(c *gin.Context) { claims := token.Claims.(jwt.MapClaims) did, ok := claims["sub"].(string) if !ok { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token: missing or invalid DID"}) + basicResponse.Message = "Invalid token: missing or invalid DID" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) return } // Optionally, verify the DID exists in the database user, err := storage.GetUserByDID(did) if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{"error": "User not found"}) + basicResponse.Message = "User not found, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) c.Writer.Write([]byte("\n")) return } var req ReqToRubixNode if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid input"}) + basicResponse.Message = "Invalid input, " + err.Error() + c.JSON(http.StatusBadRequest, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) return @@ -1875,21 +2053,25 @@ func unpledgeRBTHandler(c *gin.Context) { // Ensure the DID from the token matches the one in the request body if req.DID != did { - c.JSON(http.StatusForbidden, gin.H{"error": "DID mismatch"}) + basicResponse.Message = "DID mismatch" + c.JSON(http.StatusForbidden, basicResponse) c.Writer.Write([]byte("\n")) return } resp, err := unpledgeRBTRequest(req, strconv.Itoa(user.Port)) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "error": err.Error(), - }) + basicResponse.Message = err.Error() + c.JSON(http.StatusBadRequest, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) + return } - c.JSON(http.StatusOK, resp) + // prepare response + basicResponse.Status = true + basicResponse.Message = resp + c.JSON(http.StatusOK, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) } @@ -1949,16 +2131,21 @@ func unpledgeRBTRequest(data ReqToRubixNode, rubixNodePort string) (string, erro // @Accept json // @Produce json // @Param request body CreateFTRequest true "Fungible token creation details" -// @Success 200 {object} map[string]string -// @Failure 400 {object} ErrorResponse -// @Failure 401 {object} ErrorResponse +// @Success 200 {object} BasicResponse +// @Failure 400 {object} BasicResponse +// @Failure 401 {object} BasicResponse // @Security BearerAuth // @Param Authorization header string true "Authorization token (Bearer )" // @Router /create_ft [post] func createFTHandler(c *gin.Context) { + basicResponse := BasicResponse{ + Status: false, + } tokenString := c.GetHeader("Authorization") if tokenString == "" { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Token is required"}) + basicResponse.Message = "Token is required" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -1973,7 +2160,9 @@ func createFTHandler(c *gin.Context) { }) if err != nil || !token.Valid { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"}) + basicResponse.Message = "Invalid token, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -1982,52 +2171,70 @@ func createFTHandler(c *gin.Context) { claims := token.Claims.(jwt.MapClaims) did, ok := claims["sub"].(string) if !ok { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token: missing or invalid DID"}) + basicResponse.Message = "Invalid token: missing or invalid DID" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) return } // Optionally, verify the DID exists in the database user, err := storage.GetUserByDID(did) if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{"error": "User not found"}) + basicResponse.Message = "User not found, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) c.Writer.Write([]byte("\n")) return } var req CreateFTRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid input"}) + basicResponse.Message = "Invalid input, " + err.Error() + c.JSON(http.StatusBadRequest, basicResponse) + c.Writer.Write([]byte("\n")) return } // Ensure the DID from the token matches the one in the request body if req.DID != did { - c.JSON(http.StatusForbidden, gin.H{"error": "DID mismatch"}) + basicResponse.Message = "DID mismatch" + c.JSON(http.StatusForbidden, basicResponse) c.Writer.Write([]byte("\n")) return } response, err := createFTReq(req, strconv.Itoa(user.Port)) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "error": err.Error(), - }) + basicResponse.Message = err.Error() + c.JSON(http.StatusBadRequest, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) + return } - respMsg, err := callSignHandler(response, did) - if err != nil { - log.Println("failed to call sign handler, err:", err.Error()) - c.JSON(http.StatusBadRequest, gin.H{ - "error": err.Error(), - }) + respMsg := response["message"].(string) + // sign, if the message says 'signature needed' + if strings.Contains(respMsg, "Signature needed") { + respMsg, err = callSignHandler(response, did) + if err != nil { + basicResponse.Message = err.Error() + c.JSON(http.StatusInternalServerError, basicResponse) + // Add a newline to the response body if required + c.Writer.Write([]byte("\n")) + return + } + } else { + basicResponse.Status = response["status"].(bool) + basicResponse.Message = respMsg + c.JSON(http.StatusInternalServerError, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) return } - c.JSON(http.StatusOK, respMsg) + // prepare response + basicResponse.Status = true + basicResponse.Message = respMsg + c.JSON(http.StatusOK, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) } @@ -2086,16 +2293,21 @@ func createFTReq(data CreateFTRequest, rubixNodePort string) (map[string]interfa // @Accept json // @Produce json // @Param request body TransferFTReq true "Fungible token transfer details" -// @Success 200 {object} map[string]string -// @Failure 400 {object} ErrorResponse -// @Failure 401 {object} ErrorResponse +// @Success 200 {object} BasicResponse +// @Failure 400 {object} BasicResponse +// @Failure 401 {object} BasicResponse // @Security BearerAuth // @Param Authorization header string true "Authorization token (Bearer )" // @Router /transfer_ft [post] func transferFTHandler(c *gin.Context) { + basicResponse := BasicResponse{ + Status: false, + } tokenString := c.GetHeader("Authorization") if tokenString == "" { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Token is required"}) + basicResponse.Message = "Token is required" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -2110,7 +2322,9 @@ func transferFTHandler(c *gin.Context) { }) if err != nil || !token.Valid { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"}) + basicResponse.Message = "Invalid token, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -2119,53 +2333,70 @@ func transferFTHandler(c *gin.Context) { claims := token.Claims.(jwt.MapClaims) did, ok := claims["sub"].(string) if !ok { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token: missing or invalid DID"}) + basicResponse.Message = "Invalid token: missing or invalid DID" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) return } // Optionally, verify the DID exists in the database user, err := storage.GetUserByDID(did) if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{"error": "User not found"}) + basicResponse.Message = "User not found, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) c.Writer.Write([]byte("\n")) return } var req TransferFTReq if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid input"}) + basicResponse.Message = "Invalid input, " + err.Error() + c.JSON(http.StatusBadRequest, basicResponse) + c.Writer.Write([]byte("\n")) return } // Ensure the DID from the token matches the one in the request body if req.Sender != did { - c.JSON(http.StatusForbidden, gin.H{"error": "DID mismatch"}) + basicResponse.Message = "DID mismatch" + c.JSON(http.StatusForbidden, basicResponse) c.Writer.Write([]byte("\n")) return } - resp, err := transferFTRequest(req, strconv.Itoa(user.Port)) + response, err := transferFTRequest(req, strconv.Itoa(user.Port)) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "error": err.Error(), - }) + basicResponse.Message = err.Error() + c.JSON(http.StatusBadRequest, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) + return } - // sign response - respMsg, err := callSignHandler(resp, did) - if err != nil { - log.Println("failed to call sign handler, err:", err.Error()) - c.JSON(http.StatusBadRequest, gin.H{ - "error": err.Error(), - }) + respMsg := response["message"].(string) + // sign, if the message says 'signature needed' + if strings.Contains(respMsg, "Signature needed") { + respMsg, err = callSignHandler(response, did) + if err != nil { + basicResponse.Message = err.Error() + c.JSON(http.StatusInternalServerError, basicResponse) + // Add a newline to the response body if required + c.Writer.Write([]byte("\n")) + return + } + } else { + basicResponse.Status = response["status"].(bool) + basicResponse.Message = respMsg + c.JSON(http.StatusInternalServerError, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) return } - c.JSON(http.StatusOK, respMsg) + // prepare response + basicResponse.Status = true + basicResponse.Message = respMsg + c.JSON(http.StatusOK, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) } @@ -2224,16 +2455,21 @@ func transferFTRequest(data TransferFTReq, rubixNodePort string) (map[string]int // @Accept json // @Produce json // @Param did query string true "DID of the user" -// @Success 200 {object} map[string]interface{} -// @Failure 400 {object} ErrorResponse -// @Failure 401 {object} ErrorResponse +// @Success 200 {object} BasicResponse +// @Failure 400 {object} BasicResponse +// @Failure 401 {object} BasicResponse // @Security BearerAuth // @Param Authorization header string true "Authorization token (Bearer )" // @Router /get_all_ft [get] func getAllFTHandler(c *gin.Context) { + basicResponse := BasicResponse{ + Status: false, + } tokenString := c.GetHeader("Authorization") if tokenString == "" { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Token is required"}) + basicResponse.Message = "Token is required" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -2248,7 +2484,9 @@ func getAllFTHandler(c *gin.Context) { }) if err != nil || !token.Valid { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"}) + basicResponse.Message = "Invalid token, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -2257,14 +2495,17 @@ func getAllFTHandler(c *gin.Context) { claims := token.Claims.(jwt.MapClaims) did, ok := claims["sub"].(string) if !ok { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token: missing or invalid DID"}) + basicResponse.Message = "Invalid token: missing or invalid DID" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) return } // Optionally, verify the DID exists in the database user, err := storage.GetUserByDID(did) if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{"error": "User not found"}) + basicResponse.Message = "User not found, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) c.Writer.Write([]byte("\n")) return } @@ -2272,27 +2513,33 @@ func getAllFTHandler(c *gin.Context) { userDID := c.Query("did") if userDID == "" { - c.JSON(http.StatusBadRequest, gin.H{"error": "Missing required parameter: did"}) + basicResponse.Message = "Missing required parameter: did" + c.JSON(http.StatusBadRequest, basicResponse) + c.Writer.Write([]byte("\n")) return } // Ensure the DID from the token matches the one in the request body if userDID != did { - c.JSON(http.StatusForbidden, gin.H{"error": "DID mismatch"}) + basicResponse.Message = "DID mismatch" + c.JSON(http.StatusForbidden, basicResponse) c.Writer.Write([]byte("\n")) return } resp, err := getAllFTRequest(did, strconv.Itoa(user.Port)) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "error": err.Error(), - }) + basicResponse.Message = err.Error() + c.JSON(http.StatusBadRequest, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) } - c.JSON(http.StatusOK, resp) + // prepare response + basicResponse.Status = resp["status"].(bool) + basicResponse.Message = resp["message"].(string) + basicResponse.Result = resp["ft_info"] + c.JSON(http.StatusOK, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) } @@ -2337,16 +2584,21 @@ func getAllFTRequest(did string, rubixNodePort string) (map[string]interface{}, // @Accept json // @Produce json // @Param tokenID query string true "Token ID" -// @Success 200 {object} map[string]interface{} -// @Failure 400 {object} ErrorResponse -// @Failure 401 {object} ErrorResponse +// @Success 200 {object} BasicResponse +// @Failure 400 {object} BasicResponse +// @Failure 401 {object} BasicResponse // @Security BearerAuth // @Param Authorization header string true "Authorization token (Bearer )" // @Router /get_ft_chain [get] func getFTChainHandler(c *gin.Context) { + basicResponse := BasicResponse{ + Status: false, + } tokenString := c.GetHeader("Authorization") if tokenString == "" { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Token is required"}) + basicResponse.Message = "Token is required" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -2361,7 +2613,9 @@ func getFTChainHandler(c *gin.Context) { }) if err != nil || !token.Valid { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"}) + basicResponse.Message = "Invalid token, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -2370,14 +2624,17 @@ func getFTChainHandler(c *gin.Context) { claims := token.Claims.(jwt.MapClaims) did, ok := claims["sub"].(string) if !ok { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token: missing or invalid DID"}) + basicResponse.Message = "Invalid token: missing or invalid DID" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) return } // Optionally, verify the DID exists in the database user, err := storage.GetUserByDID(did) if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{"error": "User not found"}) + basicResponse.Message = "User not found, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) c.Writer.Write([]byte("\n")) return } @@ -2385,12 +2642,15 @@ func getFTChainHandler(c *gin.Context) { userDID := c.Query("did") if userDID == "" { - c.JSON(http.StatusBadRequest, gin.H{"error": "Missing required parameter: did"}) + basicResponse.Message = "Missing required parameter: did" + c.JSON(http.StatusBadRequest, basicResponse) + c.Writer.Write([]byte("\n")) return } // Ensure the DID from the token matches the one in the request body if userDID != did { - c.JSON(http.StatusForbidden, gin.H{"error": "DID mismatch"}) + basicResponse.Message = "DID mismatch" + c.JSON(http.StatusForbidden, basicResponse) c.Writer.Write([]byte("\n")) return } @@ -2398,20 +2658,25 @@ func getFTChainHandler(c *gin.Context) { tokenID := c.Query("tokenID") if tokenID == "" { - c.JSON(http.StatusBadRequest, gin.H{"error": "Missing required parameter: tokenID"}) + basicResponse.Message = "Missing required parameter: tokenID" + c.JSON(http.StatusBadRequest, basicResponse) + c.Writer.Write([]byte("\n")) return } resp, err := getFTChainRequest(tokenID, strconv.Itoa(user.Port)) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "error": err.Error(), - }) + basicResponse.Message = err.Error() + c.JSON(http.StatusBadRequest, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) } - c.JSON(http.StatusOK, resp) + //prepare response + basicResponse.Status = resp["status"].(bool) + basicResponse.Message = resp["message"].(string) + basicResponse.Result = resp["TokenChainData"] + c.JSON(http.StatusOK, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) } @@ -2458,16 +2723,21 @@ func getFTChainRequest(tokenID string, rubixNodePort string) (map[string]interfa // @Accept json // @Produce json // @Param request body CreateNFTRequest true "NFT creation details" -// @Success 200 {object} map[string]string -// @Failure 400 {object} ErrorResponse -// @Failure 401 {object} ErrorResponse +// @Success 200 {object} BasicResponse +// @Failure 400 {object} BasicResponse +// @Failure 401 {object} BasicResponse // @Security BearerAuth // @Param Authorization header string true "Authorization token (Bearer )" // @Router /create_nft [post] func createNFTHandler(c *gin.Context) { + basicResponse := BasicResponse{ + Status: false, + } tokenString := c.GetHeader("Authorization") if tokenString == "" { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Token is required"}) + basicResponse.Message = "Token is required" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -2482,7 +2752,9 @@ func createNFTHandler(c *gin.Context) { }) if err != nil || !token.Valid { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"}) + basicResponse.Message = "Invalid token, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -2491,40 +2763,49 @@ func createNFTHandler(c *gin.Context) { claims := token.Claims.(jwt.MapClaims) did, ok := claims["sub"].(string) if !ok { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token: missing or invalid DID"}) + basicResponse.Message = "Invalid token: missing or invalid DID" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) return } // Optionally, verify the DID exists in the database user, err := storage.GetUserByDID(did) if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{"error": "User not found"}) + basicResponse.Message = "User not found, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) c.Writer.Write([]byte("\n")) return } var req CreateNFTRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid input"}) + basicResponse.Message = "Invalid input, " + err.Error() + c.JSON(http.StatusBadRequest, basicResponse) + c.Writer.Write([]byte("\n")) return } // Ensure the DID from the token matches the one in the request body if req.DID != did { - c.JSON(http.StatusForbidden, gin.H{"error": "DID mismatch"}) + basicResponse.Message = "DID mismatch" + c.JSON(http.StatusForbidden, basicResponse) c.Writer.Write([]byte("\n")) return } resp, err := createNFTReq(req, strconv.Itoa(user.Port)) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "error": err.Error(), - }) + basicResponse.Message = err.Error() + c.JSON(http.StatusBadRequest, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) + return } - c.JSON(http.StatusOK, resp) + // prepare response + basicResponse.Status = true + basicResponse.Message = resp + c.JSON(http.StatusOK, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) } @@ -2635,16 +2916,21 @@ func createNFTReq(data CreateNFTRequest, rubixNodePort string) (string, error) { // @Accept json // @Produce json // @Param request body SubscribeNFTRequest true "NFT subscription details" -// @Success 200 {object} map[string]string -// @Failure 400 {object} ErrorResponse -// @Failure 401 {object} ErrorResponse +// @Success 200 {object} BasicResponse +// @Failure 400 {object} BasicResponse +// @Failure 401 {object} BasicResponse // @Security BearerAuth // @Param Authorization header string true "Authorization token (Bearer )" // @Router /subscribe_nft [post] func subscribeNFTHandler(c *gin.Context) { + basicResponse := BasicResponse{ + Status: false, + } tokenString := c.GetHeader("Authorization") if tokenString == "" { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Token is required"}) + basicResponse.Message = "Token is required" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -2659,7 +2945,9 @@ func subscribeNFTHandler(c *gin.Context) { }) if err != nil || !token.Valid { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"}) + basicResponse.Message = "Invalid token, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -2668,41 +2956,50 @@ func subscribeNFTHandler(c *gin.Context) { claims := token.Claims.(jwt.MapClaims) did, ok := claims["sub"].(string) if !ok { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token: missing or invalid DID"}) + basicResponse.Message = "Invalid token: missing or invalid DID" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) return } // Optionally, verify the DID exists in the database user, err := storage.GetUserByDID(did) if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{"error": "User not found"}) + basicResponse.Message = "User not found, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) c.Writer.Write([]byte("\n")) return } var req SubscribeNFTRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid input"}) + basicResponse.Message = "Invalid input, " + err.Error() + c.JSON(http.StatusBadRequest, basicResponse) + c.Writer.Write([]byte("\n")) return } // Ensure the DID from the token matches the one in the request body if req.DID != did { - c.JSON(http.StatusForbidden, gin.H{"error": "DID mismatch"}) + basicResponse.Message = "DID mismatch" + c.JSON(http.StatusForbidden, basicResponse) c.Writer.Write([]byte("\n")) return } resp, err := subscribeNFTRequest(req.NFT, strconv.Itoa(user.Port)) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "error": err.Error(), - }) + basicResponse.Message = err.Error() + c.JSON(http.StatusBadRequest, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) + return } - c.JSON(http.StatusOK, resp) + // preapre response + basicResponse.Status = true + basicResponse.Message = resp + c.JSON(http.StatusOK, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) } @@ -2763,16 +3060,21 @@ func subscribeNFTRequest(nft string, rubixNodePort string) (string, error) { // @Accept json // @Produce json // @Param request body DeployNFTRequest true "NFT deployment details" -// @Success 200 {object} map[string]string -// @Failure 400 {object} ErrorResponse -// @Failure 401 {object} ErrorResponse +// @Success 200 {object} BasicResponse +// @Failure 400 {object} BasicResponse +// @Failure 401 {object} BasicResponse // @Security BearerAuth // @Param Authorization header string true "Authorization token (Bearer )" // @Router /deploy_nft [post] func deployNFTHandler(c *gin.Context) { + basicResponse := BasicResponse{ + Status: false, + } tokenString := c.GetHeader("Authorization") if tokenString == "" { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Token is required"}) + basicResponse.Message = "Token is required" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -2787,7 +3089,9 @@ func deployNFTHandler(c *gin.Context) { }) if err != nil || !token.Valid { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"}) + basicResponse.Message = "Invalid token, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -2796,53 +3100,70 @@ func deployNFTHandler(c *gin.Context) { claims := token.Claims.(jwt.MapClaims) did, ok := claims["sub"].(string) if !ok { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token: missing or invalid DID"}) + basicResponse.Message = "Invalid token: missing or invalid DID" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) return } // Optionally, verify the DID exists in the database user, err := storage.GetUserByDID(did) if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{"error": "User not found"}) + basicResponse.Message = "User not found, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) c.Writer.Write([]byte("\n")) return } var req DeployNFTRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid input"}) + basicResponse.Message = "Invalid input, " + err.Error() + c.JSON(http.StatusBadRequest, basicResponse) + c.Writer.Write([]byte("\n")) return } // Ensure the DID from the token matches the one in the request body if req.DID != did { - c.JSON(http.StatusForbidden, gin.H{"error": "DID mismatch"}) + basicResponse.Message = "DID mismatch" + c.JSON(http.StatusForbidden, basicResponse) c.Writer.Write([]byte("\n")) return } - resp, err := deployNFTRequest(req, strconv.Itoa(user.Port)) + response, err := deployNFTRequest(req, strconv.Itoa(user.Port)) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "error": err.Error(), - }) + basicResponse.Message = err.Error() + c.JSON(http.StatusInternalServerError, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) + return } - // sign response - respMsg, err := callSignHandler(resp, did) - if err != nil { - log.Println("failed to call sign handler, err:", err.Error()) - c.JSON(http.StatusBadRequest, gin.H{ - "error": err.Error(), - }) + respMsg := response["message"].(string) + // sign, if the message says 'signature needed' + if strings.Contains(respMsg, "Signature needed") { + respMsg, err = callSignHandler(response, did) + if err != nil { + basicResponse.Message = err.Error() + c.JSON(http.StatusInternalServerError, basicResponse) + // Add a newline to the response body if required + c.Writer.Write([]byte("\n")) + return + } + } else { + basicResponse.Status = response["status"].(bool) + basicResponse.Message = respMsg + c.JSON(http.StatusInternalServerError, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) return } - c.JSON(http.StatusOK, respMsg) + // prepare response + basicResponse.Status = true + basicResponse.Message = respMsg + c.JSON(http.StatusOK, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) } @@ -2901,16 +3222,21 @@ func deployNFTRequest(data DeployNFTRequest, rubixNodePort string) (map[string]i // @Accept json // @Produce json // @Param request body ExecuteNFTRequest true "NFT execution details" -// @Success 200 {object} map[string]string -// @Failure 400 {object} ErrorResponse -// @Failure 401 {object} ErrorResponse +// @Success 200 {object} BasicResponse +// @Failure 400 {object} BasicResponse +// @Failure 401 {object} BasicResponse // @Security BearerAuth // @Param Authorization header string true "Authorization token (Bearer )" // @Router /execute_nft [post] func executeNFTHandler(c *gin.Context) { + basicResponse := BasicResponse{ + Status: false, + } tokenString := c.GetHeader("Authorization") if tokenString == "" { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Token is required"}) + basicResponse.Message = "Token is required" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -2925,7 +3251,9 @@ func executeNFTHandler(c *gin.Context) { }) if err != nil || !token.Valid { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"}) + basicResponse.Message = "Invalid token, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -2934,53 +3262,70 @@ func executeNFTHandler(c *gin.Context) { claims := token.Claims.(jwt.MapClaims) did, ok := claims["sub"].(string) if !ok { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token: missing or invalid DID"}) + basicResponse.Message = "Invalid token: missing or invalid DID" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) return } // Optionally, verify the DID exists in the database user, err := storage.GetUserByDID(did) if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{"error": "User not found"}) + basicResponse.Message = "User not found, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) c.Writer.Write([]byte("\n")) return } var req ExecuteNFTRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid input"}) + basicResponse.Message = "Invalid input, " + err.Error() + c.JSON(http.StatusBadRequest, basicResponse) + c.Writer.Write([]byte("\n")) return } // Ensure the DID from the token matches the one in the request body if req.DID != did { - c.JSON(http.StatusForbidden, gin.H{"error": "DID mismatch"}) + basicResponse.Message = "DID mismatch" + c.JSON(http.StatusForbidden, basicResponse) c.Writer.Write([]byte("\n")) return } - resp, err := executeNFTRequest(req, strconv.Itoa(user.Port)) + response, err := executeNFTRequest(req, strconv.Itoa(user.Port)) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "error": err.Error(), - }) + basicResponse.Message = err.Error() + c.JSON(http.StatusBadRequest, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) + return } - // sign response - respMsg, err := callSignHandler(resp, did) - if err != nil { - log.Println("failed to call sign handler, err:", err.Error()) - c.JSON(http.StatusBadRequest, gin.H{ - "error": err.Error(), - }) + respMsg := response["message"].(string) + // sign, if the message says 'signature needed' + if strings.Contains(respMsg, "Signature needed") { + respMsg, err = callSignHandler(response, did) + if err != nil { + basicResponse.Message = err.Error() + c.JSON(http.StatusInternalServerError, basicResponse) + // Add a newline to the response body if required + c.Writer.Write([]byte("\n")) + return + } + } else { + basicResponse.Status = response["status"].(bool) + basicResponse.Message = respMsg + c.JSON(http.StatusInternalServerError, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) return } - c.JSON(http.StatusOK, respMsg) + // prepare response + basicResponse.Status = true + basicResponse.Message = respMsg + c.JSON(http.StatusOK, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) } @@ -3039,16 +3384,21 @@ func executeNFTRequest(data ExecuteNFTRequest, rubixNodePort string) (map[string // @Accept json // @Produce json // @Param nft query string true "NFT ID" -// @Success 200 {object} map[string]interface{} -// @Failure 400 {object} ErrorResponse -// @Failure 401 {object} ErrorResponse +// @Success 200 {object} BasicResponse +// @Failure 400 {object} BasicResponse +// @Failure 401 {object} BasicResponse // @Security BearerAuth // @Param Authorization header string true "Authorization token (Bearer )" // @Router /get_nft [get] func getNFTHandler(c *gin.Context) { + basicResponse := BasicResponse{ + Status: false, + } tokenString := c.GetHeader("Authorization") if tokenString == "" { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Token is required"}) + basicResponse.Message = "Token is required" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -3063,7 +3413,9 @@ func getNFTHandler(c *gin.Context) { }) if err != nil || !token.Valid { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"}) + basicResponse.Message = "Invalid token, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -3072,14 +3424,17 @@ func getNFTHandler(c *gin.Context) { claims := token.Claims.(jwt.MapClaims) did, ok := claims["sub"].(string) if !ok { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token: missing or invalid DID"}) + basicResponse.Message = "Invalid token: missing or invalid DID" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) return } // Optionally, verify the DID exists in the database user, err := storage.GetUserByDID(did) if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{"error": "User not found"}) + basicResponse.Message = "User not found, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) c.Writer.Write([]byte("\n")) return } @@ -3087,13 +3442,16 @@ func getNFTHandler(c *gin.Context) { userDID := c.Query("did") if userDID == "" { - c.JSON(http.StatusBadRequest, gin.H{"error": "Missing required parameter: did"}) + basicResponse.Message = "Missing required parameter: did" + c.JSON(http.StatusBadRequest, basicResponse) + c.Writer.Write([]byte("\n")) return } // Ensure the DID from the token matches the one in the request body if userDID != did { - c.JSON(http.StatusForbidden, gin.H{"error": "DID mismatch"}) + basicResponse.Message = "DID mismatch" + c.JSON(http.StatusForbidden, basicResponse) c.Writer.Write([]byte("\n")) return } @@ -3101,20 +3459,26 @@ func getNFTHandler(c *gin.Context) { nft := c.Query("nft") if nft == "" { - c.JSON(http.StatusBadRequest, gin.H{"error": "Missing required parameter: did"}) + basicResponse.Message = "Missing required parameter: nft" + c.JSON(http.StatusBadRequest, basicResponse) + c.Writer.Write([]byte("\n")) return } resp, err := getNFTRequest(nft, strconv.Itoa(user.Port)) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "error": err.Error(), - }) + basicResponse.Message = err.Error() + c.JSON(http.StatusInternalServerError, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) + return } - c.JSON(http.StatusOK, resp) + // prepare response + basicResponse.Status = resp["status"].(bool) + basicResponse.Message = resp["message"].(string) + basicResponse.Result = resp["result"] + c.JSON(http.StatusOK, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) } @@ -3159,16 +3523,21 @@ func getNFTRequest(nft string, rubixNodePort string) (map[string]interface{}, er // @Accept json // @Produce json // @Param nft query string true "NFT ID" -// @Success 200 {object} map[string]interface{} -// @Failure 400 {object} ErrorResponse -// @Failure 401 {object} ErrorResponse +// @Success 200 {object} BasicResponse +// @Failure 400 {object} BasicResponse +// @Failure 401 {object} BasicResponse // @Security BearerAuth // @Param Authorization header string true "Authorization token (Bearer )" // @Router /get_nft_chain [get] func getNFTChainHandler(c *gin.Context) { + basicResponse := BasicResponse{ + Status: false, + } tokenString := c.GetHeader("Authorization") if tokenString == "" { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Token is required"}) + basicResponse.Message = "Token is required" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -3183,7 +3552,9 @@ func getNFTChainHandler(c *gin.Context) { }) if err != nil || !token.Valid { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"}) + basicResponse.Message = "Invalid token, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -3192,14 +3563,17 @@ func getNFTChainHandler(c *gin.Context) { claims := token.Claims.(jwt.MapClaims) did, ok := claims["sub"].(string) if !ok { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token: missing or invalid DID"}) + basicResponse.Message = "Invalid token: missing or invalid DID" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) return } // Optionally, verify the DID exists in the database user, err := storage.GetUserByDID(did) if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{"error": "User not found"}) + basicResponse.Message = "User not found, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) c.Writer.Write([]byte("\n")) return } @@ -3207,13 +3581,16 @@ func getNFTChainHandler(c *gin.Context) { userDID := c.Query("did") if userDID == "" { - c.JSON(http.StatusBadRequest, gin.H{"error": "Missing required parameter: did"}) + basicResponse.Message = "Missing required parameter: did" + c.JSON(http.StatusBadRequest, basicResponse) + c.Writer.Write([]byte("\n")) return } // Ensure the DID from the token matches the one in the request body if userDID != did { - c.JSON(http.StatusForbidden, gin.H{"error": "DID mismatch"}) + basicResponse.Message = "DID mismatch" + c.JSON(http.StatusForbidden, basicResponse) c.Writer.Write([]byte("\n")) return } @@ -3221,7 +3598,9 @@ func getNFTChainHandler(c *gin.Context) { nft := c.Query("nft") if nft == "" { - c.JSON(http.StatusBadRequest, gin.H{"error": "Missing required parameter: tokenID"}) + basicResponse.Message = "Missing required parameter: tokenID" + c.JSON(http.StatusBadRequest, basicResponse) + c.Writer.Write([]byte("\n")) return } @@ -3229,14 +3608,18 @@ func getNFTChainHandler(c *gin.Context) { resp, err := getNFTChainRequest(nft, latest, strconv.Itoa(user.Port)) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "error": err.Error(), - }) + basicResponse.Message = err.Error() + c.JSON(http.StatusBadRequest, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) + return } - c.JSON(http.StatusOK, resp) + //prepare response + basicResponse.Status = resp["status"].(bool) + basicResponse.Message = resp["message"].(string) + basicResponse.Result = resp["NFTDataReply"] + c.JSON(http.StatusOK, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) } @@ -3281,16 +3664,21 @@ func getNFTChainRequest(nft string, latest string, rubixNodePort string) (map[st // @Accept json // @Produce json // @Param did query string true "DID of the user" -// @Success 200 {object} map[string]interface{} -// @Failure 400 {object} ErrorResponse -// @Failure 401 {object} ErrorResponse +// @Success 200 {object} BasicResponse +// @Failure 400 {object} BasicResponse +// @Failure 401 {object} BasicResponse // @Security BearerAuth // @Param Authorization header string true "Authorization token (Bearer )" // @Router /get_all_nft [get] func getAllNFTHandler(c *gin.Context) { + basicResponse := BasicResponse{ + Status: false, + } tokenString := c.GetHeader("Authorization") if tokenString == "" { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Token is required"}) + basicResponse.Message = "Token is required" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -3305,7 +3693,9 @@ func getAllNFTHandler(c *gin.Context) { }) if err != nil || !token.Valid { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"}) + basicResponse.Message = "Invalid token, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -3314,14 +3704,17 @@ func getAllNFTHandler(c *gin.Context) { claims := token.Claims.(jwt.MapClaims) did, ok := claims["sub"].(string) if !ok { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token: missing or invalid DID"}) + basicResponse.Message = "Invalid token: missing or invalid DID" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) return } // Optionally, verify the DID exists in the database user, err := storage.GetUserByDID(did) if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{"error": "User not found"}) + basicResponse.Message = "User not found, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) c.Writer.Write([]byte("\n")) return } @@ -3329,27 +3722,34 @@ func getAllNFTHandler(c *gin.Context) { userDID := c.Query("did") if userDID == "" { - c.JSON(http.StatusBadRequest, gin.H{"error": "Missing required parameter: did"}) + basicResponse.Message = "Missing required parameter: did" + c.JSON(http.StatusBadRequest, basicResponse) + c.Writer.Write([]byte("\n")) return } // Ensure the DID from the token matches the one in the request body if userDID != did { - c.JSON(http.StatusForbidden, gin.H{"error": "DID mismatch"}) + basicResponse.Message = "DID mismatch" + c.JSON(http.StatusForbidden, basicResponse) c.Writer.Write([]byte("\n")) return } resp, err := getAllNFTRequest(did, strconv.Itoa(user.Port)) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "error": err.Error(), - }) + basicResponse.Message = err.Error() + c.JSON(http.StatusBadRequest, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) + return } - c.JSON(http.StatusOK, resp) + // prepare response + basicResponse.Status = resp["status"].(bool) + basicResponse.Message = resp["message"].(string) + basicResponse.Result = resp["nfts"] + c.JSON(http.StatusOK, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) } @@ -3396,16 +3796,21 @@ func getAllNFTRequest(did string, rubixNodePort string) (map[string]interface{}, // @Produce json // @Param rubixNodePort query string true "Rubix node port" // @Param request body DeploySmartContractRequest true "Smart contract deployment details" -// @Success 200 {object} map[string]string -// @Failure 400 {object} ErrorResponse -// @Failure 401 {object} ErrorResponse +// @Success 200 {object} BasicResponse +// @Failure 400 {object} BasicResponse +// @Failure 401 {object} BasicResponse // @Security BearerAuth // @Param Authorization header string true "Authorization token (Bearer )" // @Router /deploy-smart-contract [post] func deploySmartContractHandler(c *gin.Context) { + basicResponse := BasicResponse{ + Status: false, + } tokenString := c.GetHeader("Authorization") if tokenString == "" { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Token is required"}) + basicResponse.Message = "Token is required" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -3420,43 +3825,69 @@ func deploySmartContractHandler(c *gin.Context) { }) if err != nil || !token.Valid { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"}) + basicResponse.Message = "Invalid token, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } - rubixNodePort := c.Query("rubixNodePort") - if rubixNodePort == "" { - c.JSON(http.StatusBadRequest, gin.H{"error": "Rubix node port is required"}) - return - } + // rubixNodePort := c.Query("rubixNodePort") + // if rubixNodePort == "" { + // basicResponse.Message = "Rubix node port is required" + // c.JSON(http.StatusBadRequest, basicResponse) + // c.Writer.Write([]byte("\n")) + // return + // } var req DeploySmartContractRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid input"}) + basicResponse.Message = "Invalid input, " + err.Error() + c.JSON(http.StatusBadRequest, basicResponse) + c.Writer.Write([]byte("\n")) return } - resp, err := deploySmartContractReq(req, rubixNodePort) + user, err := storage.GetUserByDID(req.DeployerAddr) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + basicResponse.Message = "User not found, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) c.Writer.Write([]byte("\n")) return } - // sign response - respMsg, err := callSignHandler(resp, req.DeployerAddr) + response, err := deploySmartContractReq(req, strconv.Itoa(user.Port)) if err != nil { - log.Println("failed to call sign handler, err:", err.Error()) - c.JSON(http.StatusBadRequest, gin.H{ - "error": err.Error(), - }) + basicResponse.Message = err.Error() + c.JSON(http.StatusBadRequest, basicResponse) + c.Writer.Write([]byte("\n")) + return + } + + respMsg := response["message"].(string) + // sign, if the message says 'signature needed' + if strings.Contains(respMsg, "Signature needed") { + respMsg, err = callSignHandler(response, req.DeployerAddr) + if err != nil { + basicResponse.Message = err.Error() + c.JSON(http.StatusInternalServerError, basicResponse) + // Add a newline to the response body if required + c.Writer.Write([]byte("\n")) + return + } + } else { + basicResponse.Status = response["status"].(bool) + basicResponse.Message = respMsg + c.JSON(http.StatusInternalServerError, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) return } - c.JSON(http.StatusOK, respMsg) + //prepare response + basicResponse.Status = true + basicResponse.Message = respMsg + c.JSON(http.StatusOK, basicResponse) c.Writer.Write([]byte("\n")) } @@ -3518,16 +3949,21 @@ func deploySmartContractReq(data DeploySmartContractRequest, rubixNodePort strin // @Param binaryCodePath formData file true "Binary code file" // @Param rawCodePath formData file true "Raw code file" // @Param schemaFilePath formData file true "Schema file" -// @Success 200 {object} map[string]string -// @Failure 400 {object} ErrorResponse -// @Failure 401 {object} ErrorResponse +// @Success 200 {object} BasicResponse +// @Failure 400 {object} BasicResponse +// @Failure 401 {object} BasicResponse // @Security BearerAuth // @Param Authorization header string true "Authorization token (Bearer )" // @Router /generate-smart-contract [post] func generateSmartContractHandler(c *gin.Context) { + basicResponse := BasicResponse{ + Status: false, + } tokenString := c.GetHeader("Authorization") if tokenString == "" { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Token is required"}) + basicResponse.Message = "Token is required" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -3542,41 +3978,45 @@ func generateSmartContractHandler(c *gin.Context) { }) if err != nil || !token.Valid { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"}) + basicResponse.Message = "Invalid token, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } - rubixNodePort := c.Query("rubixNodePort") - if rubixNodePort == "" { - c.JSON(http.StatusBadRequest, gin.H{"error": "Rubix node port is required"}) - return - } - err = c.Request.ParseMultipartForm(10 << 20) // Limit to 10 MB if err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "Unable to parse form data"}) + basicResponse.Message = "Unable to parse form data, " + err.Error() + c.JSON(http.StatusBadRequest, basicResponse) + c.Writer.Write([]byte("\n")) return } // Save the files to the server's file system binaryFile, _, err := c.Request.FormFile("binaryCodePath") if err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "Error reading binary file"}) + basicResponse.Message = "Error reading binary file, " + err.Error() + c.JSON(http.StatusBadRequest, basicResponse) + c.Writer.Write([]byte("\n")) return } defer binaryFile.Close() rawFile, _, err := c.Request.FormFile("rawCodePath") if err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "Error reading raw file"}) + basicResponse.Message = "Error reading raw file" + c.JSON(http.StatusBadRequest, basicResponse) + c.Writer.Write([]byte("\n")) return } defer rawFile.Close() schemaFile, _, err := c.Request.FormFile("schemaFilePath") if err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "Error reading schema file"}) + basicResponse.Message = "Error reading schema file" + c.JSON(http.StatusBadRequest, basicResponse) + c.Writer.Write([]byte("\n")) return } defer schemaFile.Close() @@ -3593,37 +4033,49 @@ func generateSmartContractHandler(c *gin.Context) { binaryOut, err := os.Create(binaryFilePath) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": "Error saving binary file"}) + basicResponse.Message = "Error saving baniry file" + c.JSON(http.StatusInternalServerError, basicResponse) + c.Writer.Write([]byte("\n")) return } defer binaryOut.Close() _, err = io.Copy(binaryOut, binaryFile) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": "Error saving binary file"}) + basicResponse.Message = "Error saving binary file" + c.JSON(http.StatusInternalServerError, basicResponse) + c.Writer.Write([]byte("\n")) return } rawOut, err := os.Create(rawFilePath) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": "Error saving raw file"}) + basicResponse.Message = "Error saving raw file" + c.JSON(http.StatusInternalServerError, basicResponse) + c.Writer.Write([]byte("\n")) return } defer rawOut.Close() _, err = io.Copy(rawOut, rawFile) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": "Error saving raw file"}) + basicResponse.Message = "Error saving raw file" + c.JSON(http.StatusInternalServerError, basicResponse) + c.Writer.Write([]byte("\n")) return } schemaOut, err := os.Create(schemaFilePath) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": "Error saving schema file"}) + basicResponse.Message = "Error saving schema file" + c.JSON(http.StatusInternalServerError, basicResponse) + c.Writer.Write([]byte("\n")) return } defer schemaOut.Close() _, err = io.Copy(schemaOut, schemaFile) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": "Error saving schema file"}) + basicResponse.Message = "Error saving schema file" + c.JSON(http.StatusInternalServerError, basicResponse) + c.Writer.Write([]byte("\n")) return } @@ -3635,20 +4087,34 @@ func generateSmartContractHandler(c *gin.Context) { SchemaFilePath: schemaFilePath, } + // get user details by did + user, err := storage.GetUserByDID(data.DID) + if err != nil { + basicResponse.Message = "User not found, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) + return + } + // Trigger Rubix Node call - respMsg, err := generateSmartContractReq(data, rubixNodePort) + respMsg, err := generateSmartContractReq(data, strconv.Itoa(user.Port)) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": "Error generating smart contract"}) + basicResponse.Message = "Error generating smart contract" + c.JSON(http.StatusInternalServerError, basicResponse) + c.Writer.Write([]byte("\n")) return } // Respond with the paths or stream the files back to the client - c.JSON(http.StatusOK, gin.H{ - "message": respMsg, // This will be the response from Rubix node + basicResponse.Status = true + basicResponse.Message = respMsg // This will be the response from Rubix node + basicResponse.Result = map[string]interface{}{ "binaryFilePath": binaryFilePath, "rawFilePath": rawFilePath, "schemaFilePath": schemaFilePath, - }) + } + c.JSON(http.StatusOK, basicResponse) + c.Writer.Write([]byte("\n")) // Stream the files back to the client (if required) // c.File(binaryFilePath) // Example of sending the binary file back @@ -3782,16 +4248,21 @@ func generateSmartContractReq(data GenerateSmartContractRequest, rubixNodePort s // @Produce json // @Param rubixNodePort query string true "Rubix node port" // @Param request body ExecuteSmartContractRequest true "Smart contract execution details" -// @Success 200 {object} map[string]string -// @Failure 400 {object} ErrorResponse -// @Failure 401 {object} ErrorResponse +// @Success 200 {object} BasicResponse +// @Failure 400 {object} BasicResponse +// @Failure 401 {object} BasicResponse // @Security BearerAuth // @Param Authorization header string true "Authorization token (Bearer )" // @Router /execute-smart-contract [post] func executeSmartContractHandler(c *gin.Context) { + basicResponse := BasicResponse{ + Status: false, + } tokenString := c.GetHeader("Authorization") if tokenString == "" { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Token is required"}) + basicResponse.Message = "Token is required" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } @@ -3806,43 +4277,62 @@ func executeSmartContractHandler(c *gin.Context) { }) if err != nil || !token.Valid { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"}) + basicResponse.Message = "Invalid token, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) c.Abort() return } - rubixNodePort := c.Query("rubixNodePort") - if rubixNodePort == "" { - c.JSON(http.StatusBadRequest, gin.H{"error": "Rubix node port is required"}) - return - } - var req ExecuteSmartContractRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid input"}) + basicResponse.Message = "Invalid input, " + err.Error() + c.JSON(http.StatusBadRequest, basicResponse) + c.Writer.Write([]byte("\n")) return } - resp, err := executeSmartContractReq(req, rubixNodePort) + // get user info by did + user, err := storage.GetUserByDID(req.ExecutorAddr) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + basicResponse.Message = "User not found, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) c.Writer.Write([]byte("\n")) return } - // sign response - respMsg, err := callSignHandler(resp, req.ExecutorAddr) + response, err := executeSmartContractReq(req, strconv.Itoa(user.Port)) if err != nil { - log.Println("failed to call sign handler, err:", err.Error()) - c.JSON(http.StatusBadRequest, gin.H{ - "error": err.Error(), - }) + basicResponse.Message = err.Error() + c.JSON(http.StatusBadRequest, basicResponse) + c.Writer.Write([]byte("\n")) + return + } + + respMsg := response["message"].(string) + // sign, if the message says 'signature needed' + if strings.Contains(respMsg, "Signature needed") { + respMsg, err = callSignHandler(response, req.ExecutorAddr) + if err != nil { + basicResponse.Message = err.Error() + c.JSON(http.StatusInternalServerError, basicResponse) + // Add a newline to the response body if required + c.Writer.Write([]byte("\n")) + return + } + } else { + basicResponse.Status = response["status"].(bool) + basicResponse.Message = respMsg + c.JSON(http.StatusInternalServerError, basicResponse) // Add a newline to the response body if required c.Writer.Write([]byte("\n")) return } - c.JSON(http.StatusOK, respMsg) + // prepare response + basicResponse.Status = true + basicResponse.Message = respMsg + c.JSON(http.StatusOK, basicResponse) c.Writer.Write([]byte("\n")) } @@ -3893,3 +4383,147 @@ func executeSmartContractReq(data ExecuteSmartContractRequest, rubixNodePort str return response, nil } + +// @Summary Subscribe to an SmartContract +// @Description Subscribes a user to an SmartContract +// @Tags SmartContract +// @Accept json +// @Produce json +// @Param request body SubscribeSmartContractRequest true "SmartContract subscription details" +// @Success 200 {object} BasicResponse +// @Failure 400 {object} BasicResponse +// @Failure 401 {object} BasicResponse +// @Security BearerAuth +// @Param Authorization header string true "Authorization token (Bearer )" +// @Router /subscribe-smart-contract [post] +func subscribeSmartContractHandler(c *gin.Context) { + basicResponse := BasicResponse{ + Status: false, + } + tokenString := c.GetHeader("Authorization") + if tokenString == "" { + basicResponse.Message = "Token is required" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) + c.Abort() + return + } + + tokenString = tokenString[len("Bearer "):] + + token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { + if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { + return nil, fmt.Errorf("Unexpected signing method") + } + return jwtSecret, nil + }) + + if err != nil || !token.Valid { + basicResponse.Message = "Invalid token, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) + c.Abort() + return + } + + // Extract the DID claim from the token + claims := token.Claims.(jwt.MapClaims) + did, ok := claims["sub"].(string) + if !ok { + basicResponse.Message = "Invalid token: missing or invalid DID" + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) + return + } + + // Optionally, verify the DID exists in the database + user, err := storage.GetUserByDID(did) + if err != nil { + basicResponse.Message = "User not found, " + err.Error() + c.JSON(http.StatusUnauthorized, basicResponse) + c.Writer.Write([]byte("\n")) + return + } + + var req SubscribeSmartContractRequest + if err := c.ShouldBindJSON(&req); err != nil { + basicResponse.Message = "Invalid input, " + err.Error() + c.JSON(http.StatusBadRequest, basicResponse) + c.Writer.Write([]byte("\n")) + return + } + + // Ensure the DID from the token matches the one in the request body + if req.DID != did { + basicResponse.Message = "DID mismatch" + c.JSON(http.StatusForbidden, basicResponse) + c.Writer.Write([]byte("\n")) + return + } + + resp, err := subscribeSmartContractRequest(req.SmartContractToken, strconv.Itoa(user.Port)) + if err != nil { + basicResponse.Message = err.Error() + c.JSON(http.StatusBadRequest, basicResponse) + // Add a newline to the response body if required + c.Writer.Write([]byte("\n")) + return + } + + // preapre response + basicResponse.Status = true + basicResponse.Message = resp + c.JSON(http.StatusOK, basicResponse) + // Add a newline to the response body if required + c.Writer.Write([]byte("\n")) +} + +// subscribeSmartContractRequest sends request to subscribe SmartContract +func subscribeSmartContractRequest(SmartContract string, rubixNodePort string) (string, error) { + data := map[string]interface{}{ + "smartContractToken": SmartContract, + } + bodyJSON, err := json.Marshal(data) + if err != nil { + fmt.Println("Error marshaling JSON:", err) + return "", err + } + + url := fmt.Sprintf("http://localhost:%s/api/subscribe-smart-contract", rubixNodePort) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyJSON)) + if err != nil { + fmt.Println("Error creating HTTP request:", err) + return "", err + } + + req.Header.Set("Content-Type", "application/json; charset=UTF-8") + + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + fmt.Println("Error sending HTTP request:", err) + return "", err + } + defer resp.Body.Close() + data2, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Printf("Error reading response body: %s\n", err) + return "", err + } + + // Process the data as needed + var response map[string]interface{} + err = json.Unmarshal(data2, &response) + if err != nil { + fmt.Println("Error unmarshaling response:", err) + } + + respMsg := response["message"].(string) + respStatus := response["status"].(bool) + + if !respStatus { + return "", fmt.Errorf("failed to subscribe SmartContract, %s", respMsg) + } + + return respMsg, nil +} From 22d86dfedb3f23e1126fb97003000125b0ff4aab Mon Sep 17 00:00:00 2001 From: maneeSHA-256 Date: Fri, 24 Jan 2025 10:52:44 +0530 Subject: [PATCH 2/6] updating gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 79301d6..57819f7 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ go.work.sum # env file .env wallet.db +uploads/ \ No newline at end of file From 658d3cdf14083a8933fa1f9cc879dc9e27cd481b Mon Sep 17 00:00:00 2001 From: maneeSHA-256 Date: Fri, 24 Jan 2025 16:33:29 +0530 Subject: [PATCH 3/6] update swagger docs for smart contracts --- docs/docs.go | 69 +++++++++++++++++++++++++++++++++++++++++++++++ docs/swagger.json | 69 +++++++++++++++++++++++++++++++++++++++++++++++ docs/swagger.yaml | 44 ++++++++++++++++++++++++++++++ 3 files changed, 182 insertions(+) diff --git a/docs/docs.go b/docs/docs.go index e430291..fa299b0 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -1325,6 +1325,64 @@ const docTemplate = `{ } } }, + "/subscribe-smart-contract": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Subscribes a user to an SmartContract", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SmartContract" + ], + "summary": "Subscribe to an SmartContract", + "parameters": [ + { + "description": "SmartContract subscription details", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/main.SubscribeSmartContractRequest" + } + }, + { + "type": "string", + "description": "Authorization token (Bearer \u003cyour_token\u003e)", + "name": "Authorization", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/main.BasicResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/main.BasicResponse" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/main.BasicResponse" + } + } + } + } + }, "/subscribe_nft": { "post": { "security": [ @@ -1825,6 +1883,17 @@ const docTemplate = `{ } } }, + "main.SubscribeSmartContractRequest": { + "type": "object", + "properties": { + "did": { + "type": "string" + }, + "smartContractToken": { + "type": "string" + } + } + }, "main.TokenResponse": { "type": "object", "properties": { diff --git a/docs/swagger.json b/docs/swagger.json index 5758b47..5d2d7c3 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -1319,6 +1319,64 @@ } } }, + "/subscribe-smart-contract": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Subscribes a user to an SmartContract", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SmartContract" + ], + "summary": "Subscribe to an SmartContract", + "parameters": [ + { + "description": "SmartContract subscription details", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/main.SubscribeSmartContractRequest" + } + }, + { + "type": "string", + "description": "Authorization token (Bearer \u003cyour_token\u003e)", + "name": "Authorization", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/main.BasicResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/main.BasicResponse" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/main.BasicResponse" + } + } + } + } + }, "/subscribe_nft": { "post": { "security": [ @@ -1819,6 +1877,17 @@ } } }, + "main.SubscribeSmartContractRequest": { + "type": "object", + "properties": { + "did": { + "type": "string" + }, + "smartContractToken": { + "type": "string" + } + } + }, "main.TokenResponse": { "type": "object", "properties": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 566a70e..880a062 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -163,6 +163,13 @@ definitions: nft: type: string type: object + main.SubscribeSmartContractRequest: + properties: + did: + type: string + smartContractToken: + type: string + type: object main.TokenResponse: properties: token: @@ -1059,6 +1066,43 @@ paths: summary: Sign a transaction tags: - Txn + /subscribe-smart-contract: + post: + consumes: + - application/json + description: Subscribes a user to an SmartContract + parameters: + - description: SmartContract subscription details + in: body + name: request + required: true + schema: + $ref: '#/definitions/main.SubscribeSmartContractRequest' + - description: Authorization token (Bearer ) + in: header + name: Authorization + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/main.BasicResponse' + "400": + description: Bad Request + schema: + $ref: '#/definitions/main.BasicResponse' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/main.BasicResponse' + security: + - BearerAuth: [] + summary: Subscribe to an SmartContract + tags: + - SmartContract /subscribe_nft: post: consumes: From 019699143ecf2e6b9e2c1aacc9f69dbc78af362b Mon Sep 17 00:00:00 2001 From: maneeSHA-256 Date: Wed, 29 Jan 2025 17:27:08 +0530 Subject: [PATCH 4/6] storing encrypted private key --- README.md | 8 ++-- aesutils/aes.go | 72 ++++++++++++++++++++++++++++++++ aesutils/aes_test.go | 33 +++++++++++++++ go.mod | 3 +- main.go | 99 ++++++++++++++++++++++++++++++++++---------- storage/storage.go | 17 ++------ 6 files changed, 191 insertions(+), 41 deletions(-) create mode 100644 aesutils/aes.go create mode 100644 aesutils/aes_test.go diff --git a/README.md b/README.md index 6c92f81..69b1195 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,13 @@ go run wallet.go ### Curl request to create a new user ``` -curl -X POST http://localhost:8080/create -d '{"email":"","password":"","name":""}' +curl -X POST http://localhost:8080/create -d '{"email":"","password":"","name":"","secret_key":""}' ``` +_**Note** : If `secret_key` is not provided explicitly, password will be used as `secret_key`_ + #### sample with valid request ``` -curl -X POST http://localhost:8080/create -d '{"email":"mani@p.com","password":"123","name":"mani"}' +curl -X POST http://localhost:8080/create -d '{"email":"mani@p.com","password":"123","name":"mani","secret_key":"abc123"}' ``` **Response:** ``` @@ -22,7 +24,7 @@ curl -X POST http://localhost:8080/create -d '{"email":"mani@p.com","password":" ``` #### sample with invalid request (invalid input format to name) ``` -curl -X POST http://localhost:8080/create -d '{"email":"jiya@p.com","password":"123","name":jiya}' +curl -X POST http://localhost:8080/create -d '{"email":"jiya@p.com","password":"123","name":jiya,"secret_key":"abc123"}' ``` **Response:** ``` diff --git a/aesutils/aes.go b/aesutils/aes.go new file mode 100644 index 0000000..a8ecefd --- /dev/null +++ b/aesutils/aes.go @@ -0,0 +1,72 @@ +package aesutils + +import ( + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "encoding/hex" + "fmt" +) + +// Encrypt the private key using AES-GCM +func EncryptPrivateKey(privateKey, secretKey string) (string, error) { + // Create an AES cipher + block, err := aes.NewCipher([]byte(secretKey)[:32]) + if err != nil { + fmt.Println("failed to create an aes cipher") + return "", err + } + + // Use AES-GCM for encryption + aesGCM, err := cipher.NewGCM(block) + if err != nil { + fmt.Println("failed to create aes gcm") + return "", err + } + + // Generate a random nonce + nonce := make([]byte, aesGCM.NonceSize()) + if _, err := rand.Read(nonce); err != nil { + fmt.Println("failed to create a random nonce") + return "", err + } + + // Encrypt the private key + ciphertext := aesGCM.Seal(nonce, nonce, []byte(privateKey), nil) + + // Return encrypted data as base64 + return hex.EncodeToString(ciphertext), nil +} + +// Decrypt the private key +func DecryptPrivateKey(encryptedKey, secretKey string) (string, error) { + ciphertext, err := hex.DecodeString(encryptedKey) + if err != nil { + return "", nil + } + + // Create an AES cipher + block, err := aes.NewCipher([]byte(secretKey)[:32]) + if err != nil { + return "", err + } + + // Use AES-GCM for decryption + aesGCM, err := cipher.NewGCM(block) + if err != nil { + return "", err + } + + // Since we know the ciphertext is actually nonce+ciphertext + // And len(nonce) == NonceSize(). We can separate the two. + nonceSize := aesGCM.NonceSize() + nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:] + + // Decrypt the private key + plaintext, err := aesGCM.Open(nil, nonce, ciphertext, nil) + if err != nil { + return "", err + } + + return string(plaintext), nil +} diff --git a/aesutils/aes_test.go b/aesutils/aes_test.go new file mode 100644 index 0000000..2be6935 --- /dev/null +++ b/aesutils/aes_test.go @@ -0,0 +1,33 @@ +package aesutils + +import ( + "testing" + + "golang.org/x/crypto/bcrypt" +) + +func AESTest(t *testing.T, privateKey string, secretKey string) { + hashedSecretKey, err := bcrypt.GenerateFromPassword([]byte(secretKey), bcrypt.DefaultCost) + if err != nil { + t.Fatal("could not hash secret key, err", err) + } + + key := string(hashedSecretKey[:32]) + + encryptedPrivateKey, err := EncryptPrivateKey(privateKey, key) + if err != nil { + t.Fatal("failed to encrypt private key, err:", err) + } + decryptedPrivateKey, err := DecryptPrivateKey(encryptedPrivateKey, key) + if err != nil { + t.Fatal("failed to decrypt private key, err:", err) + } + if decryptedPrivateKey != privateKey { + t.Fatal("mismatched decrypted private key") + } +} + +func TestAES(t *testing.T) { + AESTest(t, "04b82f061b69471dc877ffc828687970da99fd2d65c6da7f08b9d9a793bf7262", "N1PCdw3M2B1TfJhoaY2mL736p2vCUc47") + AESTest(t, "randomstring", "abc123") +} diff --git a/go.mod b/go.mod index 90482cb..313e53b 100644 --- a/go.mod +++ b/go.mod @@ -17,14 +17,13 @@ require ( golang.org/x/crypto v0.32.0 ) -require github.com/google/uuid v1.6.0 // indirect +require github.com/google/uuid v1.6.0 require ( github.com/KyleBanks/depth v1.2.1 // indirect github.com/bytedance/sonic v1.12.7 // indirect github.com/bytedance/sonic/loader v0.2.2 // indirect github.com/cloudwego/base64x v0.1.4 // indirect - github.com/cloudwego/iasm v0.2.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 github.com/gabriel-vasile/mimetype v1.4.8 // indirect github.com/gin-contrib/sse v1.0.0 // indirect diff --git a/main.go b/main.go index e5dbb82..dd38d00 100644 --- a/main.go +++ b/main.go @@ -24,6 +24,7 @@ import ( secp256k1 "github.com/decred/dcrd/dcrec/secp256k1/v4" "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" + "github.com/gklps/wallet-frontend/aesutils" _ "github.com/gklps/wallet-frontend/docs" // Local Swagger docs import "github.com/gklps/wallet-frontend/storage" "github.com/golang-jwt/jwt" @@ -64,20 +65,23 @@ type ErrorResponse struct { // CreateUserRequest represents the structure for creating a new user type CreateUserRequest struct { - Email string `json:"email"` - Password string `json:"password"` - Name string `json:"name"` + Email string `json:"email"` + Password string `json:"password"` + Name string `json:"name"` + SecretKey string `json:"secret_key"` } // did request type DIDRequest struct { - Port int `json:"port"` + Port int `json:"port"` + SecretKey string `json:"secret_key"` } // sign request type SignRequest struct { - Data SignReqData `json:"sign_data"` - DID string `json:"did"` + Data SignReqData `json:"sign_data"` + DID string `json:"did"` + SecretKey string `json:"secret_key"` } type SignReqData struct { @@ -321,10 +325,10 @@ func loginHandler(c *gin.Context) { } // Retrieve the hashed password and DID from the database for the user - var storedHashedPassword, did string + var storedHashedPassword, storedHashedSecretKey, did string var user User - row := db.QueryRow("SELECT id, email, name, password, did FROM walletUsers WHERE email = ?", creds.Email) - err := row.Scan(&user.ID, &user.Email, &user.Name, &storedHashedPassword, &did) + row := db.QueryRow("SELECT id, email, name, password, secret_key, did FROM walletUsers WHERE email = ?", creds.Email) + err := row.Scan(&user.ID, &user.Email, &user.Name, &storedHashedPassword, &storedHashedSecretKey, &did) if err != nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid credentials"}) return @@ -351,6 +355,7 @@ func loginHandler(c *gin.Context) { } c.JSON(http.StatusOK, gin.H{"token": tokenString}) + c.Writer.Write([]byte("\n")) } // CreateUser handler to create a new user and return the user profile @@ -378,6 +383,16 @@ func createUserHandler(c *gin.Context) { return } + // manage the secret key and hash it + if newUser.SecretKey == "" { + newUser.SecretKey = newUser.Password + } + hashedSecretKey, err := bcrypt.GenerateFromPassword([]byte(newUser.SecretKey), bcrypt.DefaultCost) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": "Could not hash secret key"}) + return + } + // Increment the port counter for each new user, until a running port is found var port int for { @@ -389,9 +404,17 @@ func createUserHandler(c *gin.Context) { } // Create the wallet and fetch the DID - walletRequest := `{"port":` + strconv.Itoa(port) + `}` - log.Printf("Sending request to /create_wallet: %s", walletRequest) - resp, err := http.Post("http://localhost:8080/create_wallet", "application/json", bytes.NewBuffer([]byte(walletRequest))) + data := DIDRequest{ + Port: port, + SecretKey: string(hashedSecretKey), // pass secret key to encrypt private key + } + walletRequest, err := json.Marshal(data) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": "Error marshaling JSON, " + err.Error()}) + return + } + + resp, err := http.Post("http://localhost:8080/create_wallet", "application/json", bytes.NewBuffer(walletRequest)) if err != nil { log.Printf("HTTP request error: %v", err) c.JSON(http.StatusInternalServerError, gin.H{"error": "Could not connect to wallet service"}) @@ -412,7 +435,6 @@ func createUserHandler(c *gin.Context) { c.JSON(http.StatusInternalServerError, gin.H{"error": "Could not read wallet response"}) return } - log.Printf("Raw response from /create_wallet: %s", string(body)) if len(body) == 0 { log.Printf("Empty response from /create_wallet") c.JSON(http.StatusInternalServerError, gin.H{"error": "Empty response from wallet service"}) @@ -435,7 +457,7 @@ func createUserHandler(c *gin.Context) { } // Insert new user into the database with DID - _, err = db.Exec("INSERT INTO walletUsers (email, password, name, did) VALUES (?, ?, ?, ?)", newUser.Email, string(hashedPassword), newUser.Name, didResponse.DID) + _, err = db.Exec("INSERT INTO walletUsers (email, password, secret_key, name, did) VALUES (?, ?, ?, ?, ?)", newUser.Email, string(hashedPassword), string(hashedSecretKey), newUser.Name, didResponse.DID) if err != nil { log.Printf("Database insert error: %v", err) c.JSON(http.StatusInternalServerError, gin.H{"error": "Could not create user"}) @@ -448,6 +470,7 @@ func createUserHandler(c *gin.Context) { "name": newUser.Name, "did": didResponse.DID, }) + c.Writer.Write([]byte("\n")) } // Middleware to authenticate the user via JWT @@ -610,7 +633,7 @@ func VerifyToken(tokenString string, publicKey *ecdsa.PublicKey) (bool, jwt.MapC // @Tags DID // @Accept json // @Produce json -// @Param request body DIDRequest true "Port for DID request" +// @Param request body DIDRequest true "Port for DID request and secret key" // @Success 200 {object} map[string]string // @Failure 400 {object} ErrorResponse // @Failure 500 {object} ErrorResponse @@ -641,9 +664,17 @@ func createWalletHandler(c *gin.Context) { return } - // Save user to database + // encrypt private key to store privKeyStr := hex.EncodeToString(privateKey.Serialize()) - err = storage.InsertUser(did, pubKeyStr, privKeyStr, mnemonic, req.Port) + encryptedPrivateKey, err := aesutils.EncryptPrivateKey(privKeyStr, req.SecretKey) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to encrypt private key, " + err.Error()}) + c.Writer.Write([]byte("\n")) + return + } + + // Save user to database + err = storage.InsertUser(did, pubKeyStr, encryptedPrivateKey, mnemonic, req.Port) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to store user data, " + err.Error()}) // Add a newline to the response body @@ -1100,7 +1131,35 @@ func signTransactionHandler(c *gin.Context) { return } - signature, err := signData(user.PrivateKey.ToECDSA(), decodedBytes) + // Retrieve the hashed secret key from the database for the user + var storedHashedSecretKey string + var userInfo User + row := db.QueryRow("SELECT id, secret_key FROM walletUsers WHERE did = ?", user.DID) + err = row.Scan(&userInfo.ID, &storedHashedSecretKey) + if err != nil { + c.JSON(http.StatusUnauthorized, gin.H{"error": "failed to get secret key of user"}) + return + } + + // decrypt the encrypted private key + decryptedPrivateKey, err := aesutils.DecryptPrivateKey(user.PrivateKey, storedHashedSecretKey) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to decrypt private key, " + err.Error()}) + c.Writer.Write([]byte("\n")) + return + } + + // Decode private key + privKeyBytes, err := hex.DecodeString(decryptedPrivateKey) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to decode private key, " + err.Error()}) + c.Writer.Write([]byte("\n")) + return + } + + privateKey := secp256k1.PrivKeyFromBytes(privKeyBytes) + + signature, err := signData(privateKey.ToECDSA(), decodedBytes) if err != nil { basicResponse.Message = err.Error() c.JSON(http.StatusInternalServerError, basicResponse) @@ -1166,7 +1225,6 @@ func callSignHandler(response map[string]interface{}, did string) (string, error return "", err } - // log.Printf("Sending request to /create_wallet: %s", walletRequest) resp, err := http.Post("http://localhost:8080/sign", "application/json", bytes.NewBuffer(bodyJSON)) if err != nil { log.Printf("HTTP request error: %v", err) @@ -1301,7 +1359,6 @@ func requestTransactionHandler(c *gin.Context) { return } - log.Println("Token claims:", claims) response := SendAuthRequest(jwtToken, strconv.Itoa(user.Port)) respMsg := response["message"].(string) @@ -1705,7 +1762,6 @@ func didRequest(pubKeyStr string, rubixNodePort string) (string, error) { // SendAuthRequest sends a JWT authentication request to the Rubix node func SendAuthRequest(jwtToken string, rubixNodePort string) map[string]interface{} { - log.Println("sending auth request to rubix node...") authURL := fmt.Sprintf("http://localhost:%s/api/send-jwt-from-wallet", rubixNodePort) req, err := http.NewRequest("POST", authURL, nil) if err != nil { @@ -1733,7 +1789,6 @@ func SendAuthRequest(jwtToken string, rubixNodePort string) map[string]interface return nil } - fmt.Printf("Response from Rubix Node: %s\n", body) // Process the data as needed var response map[string]interface{} err = json.Unmarshal(body, &response) diff --git a/storage/storage.go b/storage/storage.go index 9521a71..b6e3776 100644 --- a/storage/storage.go +++ b/storage/storage.go @@ -13,7 +13,7 @@ import ( type User struct { DID string // IPFS hash (simulated) PublicKey *secp256k1.PublicKey - PrivateKey *secp256k1.PrivateKey + PrivateKey string // ChildPath int Mnemonic string Port int @@ -54,6 +54,7 @@ func InitDatabase() (*sql.DB, error) { id INTEGER PRIMARY KEY, email TEXT, password TEXT, + secret_key TEXT, name TEXT, did TEXT ) @@ -71,8 +72,6 @@ func InitDatabase() (*sql.DB, error) { func InsertUser(did, publicKey, privateKey, mnemonic string, port int) error { if db == nil { log.Println("Database connection is nil") - } else { - log.Println("Database connection initialized successfully") } query := `INSERT INTO users (did, public_key, private_key, mnemonic, port) VALUES (?, ?, ?, ?, ?)` @@ -84,8 +83,6 @@ func InsertUser(did, publicKey, privateKey, mnemonic string, port int) error { func GetUserByDID(did string) (*User, error) { if db == nil { log.Println("Database connection is nil") - } else { - log.Println("Database connection initialized successfully") } query := `SELECT public_key, private_key, mnemonic, port FROM users WHERE did = ?` @@ -109,18 +106,10 @@ func GetUserByDID(did string) (*User, error) { return nil, fmt.Errorf("failed to parse public key: %v", err) } - // Decode private key - privKeyBytes, err := hex.DecodeString(privateKey) - if err != nil { - return nil, fmt.Errorf("failed to decode private key: %v", err) - } - - privKey := secp256k1.PrivKeyFromBytes(privKeyBytes) - return &User{ DID: did, PublicKey: pubKey, - PrivateKey: privKey, + PrivateKey: privateKey, Mnemonic: mnemonic, Port: port, }, nil From 6f751c6a4e39f7a29381ceacb3db2b364b8c055a Mon Sep 17 00:00:00 2001 From: Gokul P S Date: Tue, 11 Feb 2025 10:57:36 +0530 Subject: [PATCH 5/6] Ensuring all keys are there in database --- go.mod | 4 +- main.go | 6 +-- storage/storage.go | 109 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 113 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 313e53b..90038c2 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,10 @@ -module github.com/gklps/wallet-frontend +module github.com/gklps/SafePass go 1.22.0 toolchain go1.23.3 -replace github.com/gklps/wallet-frontend/docs => ./docs +replace github.com/gklps/SafePass/docs => ./docs require ( github.com/gin-contrib/cors v1.7.2 diff --git a/main.go b/main.go index dd38d00..5cd8234 100644 --- a/main.go +++ b/main.go @@ -24,9 +24,9 @@ import ( secp256k1 "github.com/decred/dcrd/dcrec/secp256k1/v4" "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" - "github.com/gklps/wallet-frontend/aesutils" - _ "github.com/gklps/wallet-frontend/docs" // Local Swagger docs import - "github.com/gklps/wallet-frontend/storage" + "github.com/gklps/SafePass/aesutils" + _ "github.com/gklps/SafePass/docs" // Local Swagger docs import + "github.com/gklps/SafePass/storage" "github.com/golang-jwt/jwt" "github.com/google/uuid" _ "github.com/mattn/go-sqlite3" // SQLite driver diff --git a/storage/storage.go b/storage/storage.go index b6e3776..4c6e425 100644 --- a/storage/storage.go +++ b/storage/storage.go @@ -1,7 +1,9 @@ package storage import ( + "crypto/rand" "database/sql" + "encoding/base64" "encoding/hex" "fmt" "log" @@ -22,10 +24,100 @@ type User struct { // sqlite database: manages tables for user data and jwt tokens var db *sql.DB +// EnsureTableColumns ensures the required columns exist in the given table +func EnsureTableColumns(tableName string, requiredColumns map[string]string) error { + query := fmt.Sprintf("PRAGMA table_info(%s);", tableName) + rows, err := db.Query(query) + if err != nil { + return fmt.Errorf("failed to get table info for %s: %v", tableName, err) + } + defer rows.Close() + + existingColumns := make(map[string]bool) + var name, columnType string + var cid, notnull, pk int + var dfltValue sql.NullString + + for rows.Next() { + if err := rows.Scan(&cid, &name, &columnType, ¬null, &dfltValue, &pk); err != nil { + return fmt.Errorf("error scanning table info for %s: %v", tableName, err) + } + existingColumns[name] = true + } + + for column, colType := range requiredColumns { + if !existingColumns[column] { + alterQuery := fmt.Sprintf("ALTER TABLE %s ADD COLUMN %s %s;", tableName, column, colType) + _, err := db.Exec(alterQuery) + if err != nil { + return fmt.Errorf("failed to add column %s to table %s: %v", column, tableName, err) + } + log.Printf("Added missing column %s to table %s", column, tableName) + } + } + return nil +} + +// GenerateSecretKey generates a random base64-encoded secret key +func GenerateSecretKey() (string, error) { + bytes := make([]byte, 32) + _, err := rand.Read(bytes) + if err != nil { + return "", err + } + return base64.StdEncoding.EncodeToString(bytes), nil +} + +// UpdateWalletUsersSecretKeys ensures all walletUsers have a secret_key +func UpdateWalletUsersSecretKeys() error { + tx, err := db.Begin() + if err != nil { + return fmt.Errorf("failed to start transaction: %v", err) + } + rows, err := tx.Query("SELECT id FROM walletUsers WHERE secret_key IS NULL OR secret_key = ''") + if err != nil { + tx.Rollback() + return fmt.Errorf("failed to fetch walletUsers without secret_key: %v", err) + } + defer rows.Close() + + stmt, err := tx.Prepare("UPDATE walletUsers SET secret_key = ? WHERE id = ?") + if err != nil { + tx.Rollback() + return fmt.Errorf("failed to prepare update statement: %v", err) + } + defer stmt.Close() + + var id int + for rows.Next() { + if err := rows.Scan(&id); err != nil { + tx.Rollback() + return fmt.Errorf("error scanning walletUsers: %v", err) + } + secretKey, err := GenerateSecretKey() + if err != nil { + tx.Rollback() + return fmt.Errorf("failed to generate secret key: %v", err) + } + _, err = tx.Exec("UPDATE walletUsers SET secret_key = ? WHERE id = ?", secretKey, id) + if err != nil { + tx.Rollback() + return fmt.Errorf("failed to update secret_key for walletUser %d: %v", id, err) + } + log.Printf("Updated secret_key for walletUser %d", id) + } + + if err := tx.Commit(); err != nil { + return fmt.Errorf("failed to commit transaction: %v", err) + } + + return nil +} + // initiate database func InitDatabase() (*sql.DB, error) { var err error - db, err = sql.Open("sqlite3", "./wallet.db") + db, err = sql.Open("sqlite3", "./wallet.db?_journal_mode=WAL&cache_size=-200000&temp_store=MEMORY&locking_mode=EXCLUSIVE") if err != nil { log.Fatal("Failed to connect to database:", err) } @@ -65,6 +157,21 @@ func InitDatabase() (*sql.DB, error) { log.Fatal("Failed to create tables:", err) } + err = EnsureTableColumns("walletUsers", map[string]string{ + "secret_key": "TEXT", + }) + if err != nil { + log.Fatal("Failed to ensure walletUsers columns:", err) + } + + // Update missing secret_keys + err = UpdateWalletUsersSecretKeys() + if err != nil { + log.Fatal("Failed to update walletUsers secret keys:", err) + } + // Optimize database performance + db.Exec("PRAGMA analyze;") + db.Exec("PRAGMA vacuum;") return db, nil } From 2da948bcbaa80d19ab32aaa2d25cc6c9d8890415 Mon Sep 17 00:00:00 2001 From: Gokul P S <94040889+gklps@users.noreply.github.com> Date: Wed, 12 Feb 2025 16:15:17 +0530 Subject: [PATCH 6/6] Delete wallet.db --- wallet.db | Bin 24576 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 wallet.db diff --git a/wallet.db b/wallet.db deleted file mode 100644 index 20200c26d583dc685df67484a90ef1f4d7cebef8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24576 zcmeI)$!^<57yw{O@)D;yQ?8uHHX9Egj$oVN#;wCPZ z6rd=SJVq})_tZz|3*9IhM9WilYXSpPY7U@3_#aYPVKcDHt3_;zxxf2vX{3MH5 zK{V+DsaBJ&5h6*_8L=&h?Km|=X70Ek_O%oF*JaO0s}F|D&A+Aj<+^n4&*tNEKQI3x zvY1c+1yBG5Pyhu`00mG01yJB$5SV^8zu3BXu{Qm&U~UK_7KTvl=aA(mvJ2Nc&RW+Y z-L>@{hn#32m(LQB0#3HtU1!tjkiE{yL_qA{juOKhMpditTy52yJQU)q#<<{qF8o zTby{qX^XIymX0q;+PhuS-rw1oRaRH3A~{tZ{YE8`d(w9_2rkfd)2`6VJPOQ2RRH&h&_0rICqNR zg~rP>-7DhEmFW+)#a63Td-O@wXLYsetA6VIs_M=3_S;)G_nlK(Y3YW6cQAknS>M@R zKi!rEM@$Usm5oshQ4$B<%YT40$zHY>Vk`B9);F!16vQ0HPZd~MBvtvK8rFeQ?PhcN z+5BEw7F*-}-=uSYEI$@IOelZ?D1ZVefC4Ch0w{n2DDa;Vc=&1KJ!#sQo}VsHzpA^; zpSV%bOUI0xoDB^~#{R%hA?Se_8%dTbmo~V7&EK}2DL(_l(*ox|^)YA-&gYCJx?#m$?#iU4jP#i)=xR^8Nga;lF7=u@e zhq4eC*@U=dmKUTCVJPxh;(19J5HDlifJ8|ojuFcdSr#N&n>_ru{tRd37{?v@K@s*w zc^K-h&!aHWT$ibFFp0-LW4+)g8I6)&Y^do-5Dq3sFqAdlvMKW|gIbEMcp9}qH7Iw% zc4bxeIe@O%s?Kza%iJ?8ZmCRDz_T>haxF`ximicSf&rQds?2ml2q_#a29{}nFZ+}; zPBm4rZJTpfrUo~`r!rHxZ-e2AX=@q9q)d~TL_#RxV(?`6VgCMRJVMt!a@r0yV zkc;EeEGfV%NS@9V^Fx+_@Qr&V2$~OT&uA_l(?Bu|Xn&BI>e!10#)Go&jz)o-9(Sy7{Ob<0mO~^|_3j$eVw#y7vw@puXZR#`2(<~d90nGA!abK9GL3J0zZQ`rq z?h;ar*#01BW03ZMWApa2S>01CV$aBXhdsJ+D^ zRO4g^Z?aHR|4u}(^fZDuS01BW03ZMWApa2S>z`G={ zRBNHV&Hu$q|Cmq!1yBG5Pyhu`00mG01yBG5PyhwqVS(BFzux>vYW^y|Frfen zpa2S>01BW03ZMWApa2S>!2e2MdcJ-}`eHiYnl^gLpbW2RX};e0sS z_0{d|wfm#J;jW!+ZeG1phQXbH?-a#o+fHxZILzDq>qlc%r(py;!P=dwqqlfhpj%s% zJ{KV^KZ)p6K>7EF8K2y~dn?P5-u7NFUZs5p{PkWee#Kz(s!^^UDnogq-FH^4upM{q Lh8z2ns-J%V`Kg_y