Skip to content

Commit

Permalink
fix[python]: surround sensitive information with leak-proof exception…
Browse files Browse the repository at this point in the history
… handling
  • Loading branch information
Montspy authored and sk33z3r committed Jun 23, 2022
1 parent ce208a4 commit 5a86351
Show file tree
Hide file tree
Showing 5 changed files with 254 additions and 181 deletions.
49 changes: 1 addition & 48 deletions python/LoopringMintService.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,6 @@ async def resolveENS(self, ens: str) -> str:
print(f"Error resolving ENS: {client_err}")
pprint(parsed)
self.last_error = parsed
except Exception as err:
print(f"An error ocurred resolving ENS: {err}")
pprint(parsed)
self.last_error = parsed

print(f"done!")
return address_resp
Expand All @@ -128,10 +124,6 @@ async def getAccountId(self, address: str) -> str:
print(f"Error getting account ID: {client_err}")
pprint(parsed)
self.last_error = parsed
except Exception as err:
print(f"An error ocurred getting account ID: {err}")
pprint(parsed)
self.last_error = parsed

return account_id

Expand All @@ -151,10 +143,6 @@ async def getAccountAddress(self, account_id: int) -> str:
print(f"Error getting user api key: {client_err}")
pprint(parsed)
self.last_error = parsed
except Exception as err:
print(f"An error ocurred getting user api key: {err}")
pprint(parsed)
self.last_error = parsed

return address_resp

Expand Down Expand Up @@ -184,10 +172,6 @@ async def getUserApiKey(self, accountId: int, privateKey: str) -> ApiKeyResponse
print(f"Error getting user api key: {client_err}")
pprint(parsed)
self.last_error = parsed
except Exception as err:
print(f"An error ocurred getting user api key: {err}")
pprint(parsed)
self.last_error = parsed

return api_key_resp

Expand Down Expand Up @@ -219,12 +203,7 @@ async def getUserNftBalance(self, apiKey: str, accountId: int) -> NftBalance:
nft_balance['data'].extend(nft_balance_limit['data'])
nft_balance['totalNum'] += len(nft_balance_limit['data'])
except aiohttp.ClientError as client_err:
print(f"Error getting user NFT balance: {client_err}")
pprint(parsed)
self.last_error = parsed
break
except Exception as err:
print(f"An error ocurred getting user NFT balance: {err}")
print(f"Error getting user NFT balance: ")
pprint(parsed)
self.last_error = parsed
break
Expand All @@ -249,10 +228,6 @@ async def getNextStorageId(self, apiKey: str, accountId: int, sellTokenId: int)
print(f"Error getting storage id: ")
pprint(parsed)
self.last_error = parsed
except Exception as err:
print(f"An error ocurred getting storage id: {err}")
pprint(parsed)
self.last_error = parsed

return storage_id

Expand All @@ -274,10 +249,6 @@ async def computeTokenAddress(self, apiKey: str, counterFactualNftInfo: CounterF
print(f"Error computing token address: ")
pprint(parsed)
self.last_error = parsed
except Exception as err:
print(f"An error ocurred computing token address: {err}")
pprint(parsed)
self.last_error = parsed

return counterfactual_nft

Expand All @@ -299,10 +270,6 @@ async def getOffChainFee(self, apiKey: str, accountId: int, requestType: int, to
print(f"Error getting off chain fee: ")
pprint(parsed)
self.last_error = parsed
except Exception as err:
print(f"An error ocurred getting off chain fee: {err}")
pprint(parsed)
self.last_error = parsed

return off_chain_fee

Expand All @@ -322,10 +289,6 @@ async def getNftData(self, nftDatas: str) -> 'list[NftData]':
print(f"Error getting nft datas: {client_err}")
pprint(parsed)
self.last_error = parsed
except Exception as err:
print(f"An error ocurred getting nft datas: {err}")
pprint(parsed)
self.last_error = parsed

return nft_data

Expand Down Expand Up @@ -392,11 +355,6 @@ async def mintNft(
print("Error minting nft: ")
pprint(parsed)
self.last_error = parsed
except Exception as err:
print("An error ocurred minting nft: ")
pprint(err)
pprint(parsed)
self.last_error = parsed

return nft_mint_data

Expand Down Expand Up @@ -460,11 +418,6 @@ async def transferNft(
print("Error transferring nft: ")
pprint(parsed)
self.last_error = parsed
except Exception as err:
print("An error ocurred transferring nft: ")
pprint(err)
pprint(parsed)
self.last_error = parsed

return transfer_data

Expand Down
8 changes: 6 additions & 2 deletions python/enc-config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import sys
from glob import glob

from utils import Struct, generate_paths, save_config_json
from utils import generate_paths, save_config_json, print_exception_secret

# Parse CLI arguments
def parse_args():
Expand All @@ -23,7 +23,11 @@ def parse_args():

def main():
# check for command line arguments
args = parse_args()
try:
args = parse_args()
except Exception as err:
print_exception_secret()
sys.exit(f"Unable to parse arguments")

# Generate paths and make directories
paths = generate_paths()
Expand Down
109 changes: 70 additions & 39 deletions python/minter.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import json
import re

from utils import generate_paths, load_config_json, load_traits, set_progress_for_ui, Struct
from utils import generate_paths, load_config_json, load_traits, print_exception_secret, set_progress_for_ui, Struct

from DataClasses import *
from LoopringMintService import LoopringMintService, NFTDataEddsaSignHelper, NFTEddsaSignHelper
Expand Down Expand Up @@ -89,14 +89,18 @@ async def load_config(args, paths: Struct, traits: Struct):
cfg.royaltyAccount, cfg.royaltyAddress = await retry_async(get_account_info, cfg.royalty, retries=3)
assert cfg.royaltyAddress and cfg.royaltyAccount, f"Invalid royalty account: {cfg.royalty} aka {cfg.royaltyAddress} (account ID {cfg.royaltyAddress})"

assert secret.loopringPrivateKey, "Missing private key (LOOPRING_PRIVATE_KEY)"
assert cfg.nftType in [0, 1], f"Invalid NFT type (NFT_TYPE): {cfg.nftType}"
assert cfg.royaltyPercentage in range(0, 11), f"Invalid royalty percentage [0-10] (ROYALTY_PERCENTAGE): {cfg.royaltyPercentage}"
assert cfg.maxFeeTokenId in range(len(token_decimals)), f"Missing or invalid fee token ID (FEE_TOKEN_ID): {cfg.maxFeeTokenId}"
assert secret.loopringPrivateKey, "Missing private key"
assert cfg.nftType in [0, 1], f"Invalid NFT type: {cfg.nftType}"
assert cfg.royaltyPercentage in range(0, 11), f"Invalid royalty percentage [0-10]: {cfg.royaltyPercentage}"
assert cfg.maxFeeTokenId in range(len(token_decimals)), f"Missing or invalid fee token ID: {cfg.maxFeeTokenId}"

if secret.loopringPrivateKey[:2] != "0x":
secret.loopringPrivateKey = "0x{0:0{1}x}".format(int(secret.loopringPrivateKey), 64)
secret.loopringPrivateKey = secret.loopringPrivateKey.lower()
try:
if secret.loopringPrivateKey[:2] != "0x":
secret.loopringPrivateKey = "0x{0:0{1}x}".format(int(secret.loopringPrivateKey), 64)
secret.loopringPrivateKey = secret.loopringPrivateKey.lower()
except Exception as err:
print_exception_secret()
sys.exit(f"Unable to parse L2 private key")

return cfg, secret

Expand All @@ -120,7 +124,11 @@ def parse_args():
batch_group.add_argument("-j", "--json", help="Specify a json file containing a list of CIDv0 hash to batch mint", type=str)
batch_group.add_argument("-s", "--start", help="Specify the the starting ID to batch mint", type=int)
batch_group.add_argument("-e", "--end", help="Specify the last ID to batch mint", type=int)
args = parser.parse_args()
try:
args = parser.parse_args()
except Exception as err:
print_exception_secret()
sys.exit(f"Unable to parse arguments")

# Rebuild command
args.command = "./docker.sh mint " + " ".join(sys.argv[1:])
Expand Down Expand Up @@ -214,7 +222,11 @@ def prompt_yes_no(prompt: str, default: str=None):
async def get_user_api_key(cfg, secret):
async with LoopringMintService() as lms:
# Getting the user api key
api_key_resp = await lms.getUserApiKey(accountId=cfg.minterAccount, privateKey=secret.loopringPrivateKey)
try:
api_key_resp = await lms.getUserApiKey(accountId=cfg.minterAccount, privateKey=secret.loopringPrivateKey)
except Exception as err:
print_exception_secret()
sys.exit(f"Unable to get user api key")
# log(f"User API key: {json.dumps(api_key_resp, indent=2)}") # DO NOT LOG
if api_key_resp is None:
sys.exit("Failed to obtain user api key")
Expand All @@ -225,7 +237,11 @@ async def get_offchain_parameters(cfg, secret):
async with LoopringMintService() as lms:
parameters = {}
# Getting the storage id
storage_id = await lms.getNextStorageId(apiKey=secret.loopringApiKey, accountId=cfg.minterAccount, sellTokenId=cfg.maxFeeTokenId)
try:
storage_id = await lms.getNextStorageId(apiKey=secret.loopringApiKey, accountId=cfg.minterAccount, sellTokenId=cfg.maxFeeTokenId)
except Exception as err:
print_exception_secret()
sys.exit(f"Unable to get storage id")
log(f"Storage id: {json.dumps(storage_id, indent=2)}")
if storage_id is None:
sys.exit("Failed to obtain storage id")
Expand All @@ -234,7 +250,11 @@ async def get_offchain_parameters(cfg, secret):

# Getting the token address
counterfactual_nft_info = CounterFactualNftInfo(nftOwner=cfg.minterAddress, nftFactory=cfg.nftFactory, nftBaseUri="")
counterfactual_nft = await lms.computeTokenAddress(apiKey=secret.loopringApiKey, counterFactualNftInfo=counterfactual_nft_info)
try:
counterfactual_nft = await lms.computeTokenAddress(apiKey=secret.loopringApiKey, counterFactualNftInfo=counterfactual_nft_info)
except Exception as err:
print_exception_secret()
sys.exit(f"Unable to get token address")
log(f"CounterFactualNFT Token Address: {json.dumps(counterfactual_nft, indent=2)}")
if counterfactual_nft is None:
sys.exit("Failed to obtain token address")
Expand All @@ -243,7 +263,11 @@ async def get_offchain_parameters(cfg, secret):
parameters['counterfactual_nft'] = counterfactual_nft

# Getting the offchain fee
off_chain_fee = await lms.getOffChainFee(apiKey=secret.loopringApiKey, accountId=cfg.minterAccount, requestType=9, tokenAddress=counterfactual_nft['tokenAddress'])
try:
off_chain_fee = await lms.getOffChainFee(apiKey=secret.loopringApiKey, accountId=cfg.minterAccount, requestType=9, tokenAddress=counterfactual_nft['tokenAddress'])
except Exception as err:
print_exception_secret()
sys.exit(f"Unable to get offchain fee")
log(f"Offchain fee: {json.dumps(off_chain_fee['fees'][cfg.maxFeeTokenId], indent=2)}")
if off_chain_fee is None:
sys.exit("Failed to obtain offchain fee")
Expand Down Expand Up @@ -290,8 +314,12 @@ async def get_hashes_and_sign(cfg, secret, cid: str, amount: int, offchain_param
cfg.validUntil,
offchain_parameters['storage_id']['offchainId']
]
hasher = NFTEddsaSignHelper(private_key=secret.loopringPrivateKey)
nft_poseidon_hash = hasher.hash(inputs)
try:
hasher = NFTEddsaSignHelper(private_key=secret.loopringPrivateKey)
nft_poseidon_hash = hasher.hash(inputs)
except Exception as err:
print_exception_secret()
sys.exit(f"Unable to generate poseidon hash")
# plog(inputs)
log("Hashed NFT payload: 0x{0:0{1}x}".format(nft_poseidon_hash, 64))
info['nft_poseidon_hash'] = "0x{0:0{1}x}".format(nft_poseidon_hash, 64)
Expand All @@ -317,29 +345,32 @@ async def mint_nft(cfg, secret, nft_data_poseidon_hash: str, nft_id: str, amount
if test_mode:
return MintResult.TESTMODE

nft_mint_response = await lms.mintNft(
apiKey=secret.loopringApiKey,
exchange=cfg.exchange,
minterId=cfg.minterAccount,
minterAddress=cfg.minterAddress,
toAccountId=cfg.minterAccount,
toAddress=cfg.minterAddress,
royaltyAddress=cfg.royaltyAddress,
nftType=cfg.nftType,
tokenAddress=offchain_parameters['counterfactual_nft']['tokenAddress'],
nftId=nft_id,
amount=str(amount),
validUntil=cfg.validUntil,
royaltyPercentage=cfg.royaltyPercentage,
storageId=offchain_parameters['storage_id']['offchainId'],
maxFeeTokenId=cfg.maxFeeTokenId,
maxFeeAmount=int( (1 + cfg.feeSlippage) * int(offchain_parameters['off_chain_fee']['fees'][cfg.maxFeeTokenId]['fee']) ),
forceToMint=False,
counterFactualNftInfo=offchain_parameters['counterfactual_nft_info'],
eddsaSignature=eddsa_signature
)
log(f"Nft Mint reponse: {nft_mint_response}")
info['nft_mint_response'] = nft_mint_response
try:
nft_mint_response = await lms.mintNft(
apiKey=secret.loopringApiKey,
exchange=cfg.exchange,
minterId=cfg.minterAccount,
minterAddress=cfg.minterAddress,
toAccountId=cfg.minterAccount,
toAddress=cfg.minterAddress,
royaltyAddress=cfg.royaltyAddress,
nftType=cfg.nftType,
tokenAddress=offchain_parameters['counterfactual_nft']['tokenAddress'],
nftId=nft_id,
amount=str(amount),
validUntil=cfg.validUntil,
royaltyPercentage=cfg.royaltyPercentage,
storageId=offchain_parameters['storage_id']['offchainId'],
maxFeeTokenId=cfg.maxFeeTokenId,
maxFeeAmount=int( (1 + cfg.feeSlippage) * int(offchain_parameters['off_chain_fee']['fees'][cfg.maxFeeTokenId]['fee']) ),
forceToMint=False,
counterFactualNftInfo=offchain_parameters['counterfactual_nft_info'],
eddsaSignature=eddsa_signature
)
log(f"Nft Mint reponse: {nft_mint_response}")
info['nft_mint_response'] = nft_mint_response
except Exception as err:
print_exception_secret()

if nft_mint_response is None: # Something failed
mint_code = lms.last_error['resultInfo']['code']
Expand Down Expand Up @@ -439,7 +470,7 @@ async def main():
# NFT Mint sequence
for i, cid in enumerate(filtered_cids):
set_progress_for_ui("Minting", i + 1, len(filtered_cids))

id = cid['ID']
cid_hash = cid['CID']

Expand Down
Loading

0 comments on commit 5a86351

Please sign in to comment.