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
= "https://rpc1.piccadilly.autonity.org" RPC_ENDPOINT
Account constants
= "<YOUR-ACCOUNT-ADDRESS>"
ACCOUNT assert Web3.is_checksum_address(ACCOUNT)
= "<YOUR-LOCAL-KEYFILE-ADDRESS>"
KEYFILE = "<YOUR-ACCOUNT-PASSPHRASE>" PASSPHRASE
Generate private key
with open(KEYFILE) as keyfile:
= keyfile.read()
keyfile_contents = eth_keys.keys.PrivateKey(
PRIVATE_KEY
account.Account.decrypt(keyfile_contents, PASSPHRASE) )
Create Web3
= Web3(provider=Web3.HTTPProvider(RPC_ENDPOINT))
w3
w3.middleware_onion.add(
construct_sign_and_send_raw_middleware(Account.from_key(PRIVATE_KEY)) )
Create contract
= w3.eth.contract(
NTN_CONTRACT =AUTONITY_CONTRACT_ADDRESS,
address=ABIManager.load_abi("IERC20"),
abi
)
= w3.eth.contract(
USDC_CONTRACT ="0x3a60C03a86eEAe30501ce1af04a6C04Cf0188700",
address=ABIManager.load_abi("IERC20"),
abi )
Generate API key
For CAX account and url, please visit: https://game.autonity.org/getting-started/exchange-cax.html
= "<CAX-ACCOUNT-ADDRESS>"
CAX_ACCOUNT assert Web3.is_checksum_address(CAX_ACCOUNT)
= "https://cax.piccadilly.autonity.org/api" CAX_URL
= w3.to_wei(1.0, "ether")
DEPOSIT_ATN_VALUE = w3.to_wei(1.0, "ether")
DEPOSIT_NTN_VALUE = 1 * 1000000
DEPOSIT_USDC_VALUE = "1.0" WITHDRAW_ATN_VALUE
Deposit ATN to CAX
# Prepare transaction.
= {
transaction "from": ACCOUNT,
"to": CAX_ACCOUNT,
"value": DEPOSIT_ATN_VALUE,
}
# Sent transaction.
= w3.eth.send_transaction(transaction)
tx_hash
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.
= NTN_CONTRACT.functions.transfer(
function =CAX_ACCOUNT, amount=DEPOSIT_NTN_VALUE
recipient
)= function.build_transaction({"from": ACCOUNT})
function_transaction
# Sent transaction.
= w3.eth.send_transaction(function_transaction)
tx_hash
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.
= USDC_CONTRACT.functions.transfer(
function =CAX_ACCOUNT, amount=DEPOSIT_USDC_VALUE
recipient
)= function.build_transaction({"from": ACCOUNT})
function_transaction
# Sent transaction.
= w3.eth.send_transaction(function_transaction)
tx_hash
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.from_key(PRIVATE_KEY)
account = str(time.time_ns())
nonce = '{"nonce":"' + nonce + '"}'
msgstr = msgstr.encode("utf-8")
msgbytes
# Generate signature.
= account.sign_message(encode_defunct(msgbytes)).signature.hex()
sigstr
# Post request.
= requests.post(
response + "/apikeys",
CAX_URL ={"API-Sig": sigstr},
headers=msgbytes,
data
)
= response.json()
response_json
if "apikey" in response_json:
= response.json()["apikey"]
API print("API key generated")
else:
print("Account not registered on CAX")
API key generated
Interact with CAX (API key not required)
Get orderbooks
= requests.get(
response + "/orderbooks"
CAX_URL
)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
= requests.get(
response + "/orderbooks/ATN-USDC/quote"
CAX_URL
)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
= requests.get(
response + "/orderbooks/ATN-USDC/depth"
CAX_URL
)= response.json()
pair_depth 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
= [float(bid["price"]) for bid in pair_depth["bids"]]
bid_prices = [float(ask["price"]) for ask in pair_depth["asks"]]
ask_prices = (min(ask_prices) + max(bid_prices)) / 2
mid_price print(mid_price)
1.0350000000000001
Get trades
= requests.get(
response + f"/orderbooks/ATN-USDC/trades"
CAX_URL
)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
= requests.get(
response + "/balances",
CAX_URL ={"API-Key": API},
headers
)print(response.status_code)
200
Submit an order
= requests.post(
response + "/orders",
CAX_URL ={"API-Key": API},
headers={
json"pair": "ATN-USDC",
"side": "bid",
"price": "0.9",
"amount": "100.0",
},
)print(response.status_code, response.json())
# Record order_id.
= response.json()["order_id"] 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
= requests.get(
response + f"/orders/{order_id}", headers={"API-Key": API}
CAX_URL
)print(response.status_code, response.json()["status"])
200 open
Cancel an order
= response = requests.delete(
response + f"/orders/{order_id}", headers={"API-Key": API}
CAX_URL
)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
= requests.get(
response + f"/orders/{order_id}", headers={"API-Key": API}
CAX_URL
)print(response.status_code, response.json()["status"])
200 cancelled
Make a withdraw
= requests.post(
response + "/withdraws",
CAX_URL ={"API-Key": API},
headers={
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}