import time
import requests
import eth_keys
from eth_account import account, Account
from eth_account.messages import encode_defunct
from web3 import Web3
from web3.middleware import construct_sign_and_send_raw_middleware
from autonity.abi_manager import ABIManager
from autonity import AUTONITY_CONTRACT_ADDRESS
The Piccadilly Circus Games have now finished.
You are viewing an archive of the Piccadilly Circus Games Competition. Join our Discord for the latest information.
CAX Recipes
Preliminary
Network constants
RPC_ENDPOINT = "https://rpc1.piccadilly.autonity.org"Account constants
ACCOUNT = "<YOUR-ACCOUNT-ADDRESS>"
assert Web3.is_checksum_address(ACCOUNT)
KEYFILE = "<YOUR-LOCAL-KEYFILE-ADDRESS>"
PASSPHRASE = "<YOUR-ACCOUNT-PASSPHRASE>"Generate private key
with open(KEYFILE) as keyfile:
keyfile_contents = keyfile.read()
PRIVATE_KEY = eth_keys.keys.PrivateKey(
account.Account.decrypt(keyfile_contents, PASSPHRASE)
)Create Web3
w3 = Web3(provider=Web3.HTTPProvider(RPC_ENDPOINT))
w3.middleware_onion.add(
construct_sign_and_send_raw_middleware(Account.from_key(PRIVATE_KEY))
)Create contract
NTN_CONTRACT = w3.eth.contract(
address=AUTONITY_CONTRACT_ADDRESS,
abi=ABIManager.load_abi("IERC20"),
)
USDC_CONTRACT = w3.eth.contract(
address="0x3a60C03a86eEAe30501ce1af04a6C04Cf0188700",
abi=ABIManager.load_abi("IERC20"),
)Generate API key
For CAX account and url, please visit: https://game.autonity.org/getting-started/exchange-cax.html
CAX_ACCOUNT = "<CAX-ACCOUNT-ADDRESS>"
assert Web3.is_checksum_address(CAX_ACCOUNT)
CAX_URL = "https://cax.piccadilly.autonity.org/api"DEPOSIT_ATN_VALUE = w3.to_wei(1.0, "ether")
DEPOSIT_NTN_VALUE = w3.to_wei(1.0, "ether")
DEPOSIT_USDC_VALUE = 1 * 1000000
WITHDRAW_ATN_VALUE = "1.0"Deposit ATN to CAX
# Prepare transaction.
transaction = {
"from": ACCOUNT,
"to": CAX_ACCOUNT,
"value": DEPOSIT_ATN_VALUE,
}
# Sent transaction.
tx_hash = w3.eth.send_transaction(transaction)
print(w3.eth.get_transaction(tx_hash))AttributeDict({'blockHash': None, 'blockNumber': None, 'from': '0x8EaFBab4A209aF9E587B22A4cc43319c20B2e4D3', 'gas': 21000, 'gasPrice': 2500000000, 'maxFeePerGas': 2500000000, 'maxPriorityFeePerGas': 1500000000, 'hash': HexBytes('0x0dd8b6c83919444108f3885dcb667a1b56b17845d15572f21eb83a0d2a9cffc6'), 'input': HexBytes('0x'), 'nonce': 27, 'to': '0x11F62c273dD23dbe4D1713C5629fc35713Aa5a94', 'transactionIndex': None, 'value': 1000000000000000000, 'type': 2, 'accessList': [], 'chainId': 65100003, 'v': 0, 'r': HexBytes('0xdd7e966261fffc9fc81b167d5d0cfddb5f66bb14d0660de2c1d20dda98147ade'), 's': HexBytes('0x5d3d59d7eab17a76084e24e49ba970305fb9103569e744ea21fa2f84b8dd6d28')})
Deposit NTN to CAX
# Prepare function transaction.
function = NTN_CONTRACT.functions.transfer(
recipient=CAX_ACCOUNT, amount=DEPOSIT_NTN_VALUE
)
function_transaction = function.build_transaction({"from": ACCOUNT})
# Sent transaction.
tx_hash = w3.eth.send_transaction(function_transaction)
print(w3.eth.get_transaction(tx_hash))AttributeDict({'blockHash': None, 'blockNumber': None, 'from': '0x8EaFBab4A209aF9E587B22A4cc43319c20B2e4D3', 'gas': 34603, 'gasPrice': 2500000000, 'maxFeePerGas': 2500000000, 'maxPriorityFeePerGas': 1500000000, 'hash': HexBytes('0x35bd2d001a2b7a002788805905ee469632c05f7fb994690fc5ee5be951fa60e0'), 'input': HexBytes('0xa9059cbb00000000000000000000000011f62c273dd23dbe4d1713c5629fc35713aa5a940000000000000000000000000000000000000000000000000de0b6b3a7640000'), 'nonce': 28, 'to': '0xBd770416a3345F91E4B34576cb804a576fa48EB1', 'transactionIndex': None, 'value': 0, 'type': 2, 'accessList': [], 'chainId': 65100003, 'v': 1, 'r': HexBytes('0x65e3e57cf298f8a0183790abbeffdcf871303aac85e22efcac18de31a6f4a1cd'), 's': HexBytes('0x1eef0b80c32dedfaff07a547d6eba863243760aa355ccc2cc306ddd4d91355ba')})
Deposit USDC to CAX
# Prepare function transaction.
function = USDC_CONTRACT.functions.transfer(
recipient=CAX_ACCOUNT, amount=DEPOSIT_USDC_VALUE
)
function_transaction = function.build_transaction({"from": ACCOUNT})
# Sent transaction.
tx_hash = w3.eth.send_transaction(function_transaction)
print(w3.eth.get_transaction(tx_hash))AttributeDict({'blockHash': None, 'blockNumber': None, 'from': '0x8EaFBab4A209aF9E587B22A4cc43319c20B2e4D3', 'gas': 45276, 'gasPrice': 2500000000, 'maxFeePerGas': 2500000000, 'maxPriorityFeePerGas': 1500000000, 'hash': HexBytes('0x3363f993cbaa15c0c604dea3c050fc256c442acfd52c15adc70eb340fbe89852'), 'input': HexBytes('0xa9059cbb00000000000000000000000011f62c273dd23dbe4d1713c5629fc35713aa5a9400000000000000000000000000000000000000000000000000000000000f4240'), 'nonce': 29, 'to': '0x3a60C03a86eEAe30501ce1af04a6C04Cf0188700', 'transactionIndex': None, 'value': 0, 'type': 2, 'accessList': [], 'chainId': 65100003, 'v': 1, 'r': HexBytes('0xcbb8106cb3af9e2f0653962c68dc3610a235754ace2c5c9eff73167f7cfd0545'), 's': HexBytes('0x57ba017f5b57fdd74de96bf5ec10e22eec736e6ec32f99a43512e9ed68953469')})
Generate API key
# Generate msgbytes.
account = Account.from_key(PRIVATE_KEY)
nonce = str(time.time_ns())
msgstr = '{"nonce":"' + nonce + '"}'
msgbytes = msgstr.encode("utf-8")
# Generate signature.
sigstr = account.sign_message(encode_defunct(msgbytes)).signature.hex()
# Post request.
response = requests.post(
CAX_URL + "/apikeys",
headers={"API-Sig": sigstr},
data=msgbytes,
)
response_json = response.json()
if "apikey" in response_json:
API = response.json()["apikey"]
print("API key generated")
else:
print("Account not registered on CAX")API key generated
Interact with CAX (API key not required)
Get orderbooks
response = requests.get(
CAX_URL + "/orderbooks"
)
print(response.status_code, response.json())200 [{'pair': 'ATN-USDC', 'base': 'ATN', 'quote': 'USDC', 'min_amount': '0.01', 'tick_size': '0.01'}, {'pair': 'NTN-USDC', 'base': 'NTN', 'quote': 'USDC', 'min_amount': '0.01', 'tick_size': '0.01'}]
Get pair quote
response = requests.get(
CAX_URL + "/orderbooks/ATN-USDC/quote"
)
print(response.status_code, response.json())200 {'timestamp': '2024-07-15T08:59:42.454242+00:00', 'bid_price': '1.03', 'bid_amount': '20000.00', 'ask_price': '1.04', 'ask_amount': '26666.67'}
Get pair depth
response = requests.get(
CAX_URL + "/orderbooks/ATN-USDC/depth"
)
pair_depth = response.json()
print(response.status_code, pair_depth)200 {'timestamp': '2024-07-15T08:59:42.771494+00:00', 'bids': [{'price': '1.03', 'amount': '20000.00'}, {'price': '1.02', 'amount': '60000.00'}, {'price': '1.01', 'amount': '60000.00'}, {'price': '0.99', 'amount': '6666.67'}, {'price': '0.98', 'amount': '23333.33'}, {'price': '0.97', 'amount': '20000.00'}, {'price': '0.96', 'amount': '26666.67'}, {'price': '0.95', 'amount': '33333.33'}, {'price': '0.75', 'amount': '4.70'}], 'asks': [{'price': '1.04', 'amount': '26666.67'}, {'price': '1.05', 'amount': '33333.33'}, {'price': '1.06', 'amount': '36666.67'}, {'price': '1.07', 'amount': '13333.33'}, {'price': '1.08', 'amount': '20000.00'}, {'price': '1.10', 'amount': '3.00'}, {'price': '1.20', 'amount': '1.00'}, {'price': '1.25', 'amount': '8.70'}, {'price': '1.30', 'amount': '1.00'}, {'price': '1.50', 'amount': '1.00'}]}
Calculate mid price
bid_prices = [float(bid["price"]) for bid in pair_depth["bids"]]
ask_prices = [float(ask["price"]) for ask in pair_depth["asks"]]
mid_price = (min(ask_prices) + max(bid_prices)) / 2
print(mid_price)1.0350000000000001
Get trades
response = requests.get(
CAX_URL + f"/orderbooks/ATN-USDC/trades"
)
print(response.status_code, response.json()[:10])200 [{'timestamp': '2024-07-14T20:00:11.686288', 'price': '0.99', 'amount': '3334.33'}, {'timestamp': '2024-07-14T20:01:02.885963', 'price': '1.01', 'amount': '6665.67'}, {'timestamp': '2024-07-14T20:01:02.885963', 'price': '1.02', 'amount': '13333.33'}, {'timestamp': '2024-07-14T20:01:02.885963', 'price': '1.03', 'amount': '10001.00'}, {'timestamp': '2024-07-15T04:56:53.642616', 'price': '1.01', 'amount': '6666.67'}, {'timestamp': '2024-07-15T04:59:37.569318', 'price': '1.02', 'amount': '13333.33'}, {'timestamp': '2024-07-15T05:00:14.146210', 'price': '1.03', 'amount': '9999.00'}]
Interact with CAX (API key required)
Please make sure Account is registered on CAX and a valid API key is generated. API key is hidden in this example.
Check balances
response = requests.get(
CAX_URL + "/balances",
headers={"API-Key": API},
)
print(response.status_code)200
Submit an order
response = requests.post(
CAX_URL + "/orders",
headers={"API-Key": API},
json={
"pair": "ATN-USDC",
"side": "bid",
"price": "0.9",
"amount": "100.0",
},
)
print(response.status_code, response.json())
# Record order_id.
order_id = response.json()["order_id"]201 {'order_id': 340759, 'timestamp': '2024-07-15T08:59:44.151290+00:00', 'status': 'pending', 'pair': 'ATN-USDC', 'type': 'limit', 'side': 'bid', 'price': '0.90', 'amount': '100.00', 'remain': '100.00'}
Check order status
response = requests.get(
CAX_URL + f"/orders/{order_id}", headers={"API-Key": API}
)
print(response.status_code, response.json()["status"])200 open
Cancel an order
response = response = requests.delete(
CAX_URL + f"/orders/{order_id}", headers={"API-Key": API}
)
print(response.status_code, response.json())202 {'order_id': 340759, 'timestamp': '2024-07-15T08:59:44.151290', 'status': 'open', 'pair': 'ATN-USDC', 'type': 'limit', 'side': 'bid', 'price': '0.90', 'amount': '100.00', 'remain': '100.00'}
Re-check order status
response = requests.get(
CAX_URL + f"/orders/{order_id}", headers={"API-Key": API}
)
print(response.status_code, response.json()["status"])200 cancelled
Make a withdraw
response = requests.post(
CAX_URL + "/withdraws",
headers={"API-Key": API},
json={
"symbol": "ATN",
"amount": WITHDRAW_ATN_VALUE,
},
)
print(response.status_code, response.json())202 {'txid': 683, 'timestamp': '2024-07-15T08:59:48.042482+00:00', 'status': 'accepted', 'symbol': 'ATN', 'account': '0x8EaFBab4A209aF9E587B22A4cc43319c20B2e4D3', 'amount': '1.000000000000000000', 'txhash': None}