Connect to 01 Exchange
01 Exchange uses session-based authentication. Your main wallet private key never leaves your machine. You generate a temporary session locally, then paste the session credentials into Sigma Engine.
Not comfortable with terminal commands? Copy this entire page and paste it into ChatGPT — ask it to walk you through each step for your operating system.
Prerequisites
- Python 3.8+
- A Solana wallet with an
id.jsonkey file (or your private key in base58)
Step 1: Install dependencies
Open your terminal and run:
pip install requests cryptography base58
Step 2: Create the setup script
Create a new file called zo_session.py and paste this:
import argparse, binascii, json, os, sys, time, requests
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from base58 import b58decode, b58encode
API_URL = "https://zo-mainnet.n1.xyz"
def _varint_encode(value):
result = bytearray()
while value > 0x7F:
result.append((value & 0x7F) | 0x80)
value >>= 7
result.append(value & 0x7F)
return bytes(result)
def _field(field_number, wire_type, data):
tag = _varint_encode((field_number << 3) | wire_type)
if wire_type == 0:
return tag + _varint_encode(data)
elif wire_type == 2:
return tag + _varint_encode(len(data)) + data
raise ValueError(f"Unsupported wire type: {wire_type}")
def decode_varint(buffer, offset=0):
result, shift = 0, 0
while True:
byte = buffer[offset]
result |= (byte & 0x7F) << shift
offset += 1
if not (byte & 0x80):
break
shift += 7
return result, offset
def decode_session_id(response_bytes):
msg_len, pos = decode_varint(response_bytes, 0)
receipt = response_bytes[pos:pos + msg_len]
offset = 0
while offset < len(receipt):
tag_val, offset = decode_varint(receipt, offset)
field_number, wire_type = tag_val >> 3, tag_val & 0x07
if wire_type == 0:
value, offset = decode_varint(receipt, offset)
elif wire_type == 2:
length, offset = decode_varint(receipt, offset)
data = receipt[offset:offset + length]
offset += length
if field_number == 33:
inner_offset = 0
while inner_offset < len(data):
inner_tag, inner_offset = decode_varint(data, inner_offset)
if (inner_tag & 0x07) == 0:
val, inner_offset = decode_varint(data, inner_offset)
if (inner_tag >> 3) == 1:
return val
elif field_number == 32:
err_val, _ = decode_varint(data, 0) if data else (0, 0)
raise Exception(f"01 engine error code: {err_val}")
else:
raise Exception(f"Unexpected wire type {wire_type}")
raise Exception("Could not find session_id in receipt")
# Load key from base58 or id.json
key_source = os.getenv("ZO_PRIVATE_KEY")
if key_source:
user_key = Ed25519PrivateKey.from_private_bytes(b58decode(key_source)[:32])
elif os.path.exists(os.path.expanduser("~/id.json")):
with open(os.path.expanduser("~/id.json")) as f:
user_key = Ed25519PrivateKey.from_private_bytes(bytes(json.load(f)[:32]))
else:
print("Set ZO_PRIVATE_KEY env var (base58) or place id.json in home directory")
sys.exit(1)
user_pubkey = user_key.public_key().public_bytes_raw()
wallet_b58 = b58encode(user_pubkey).decode()
# Get server time
server_time = int(requests.get(f"{API_URL}/timestamp", timeout=5).json())
# Generate session
session_key = Ed25519PrivateKey.generate()
session_pubkey = session_key.public_key().public_bytes_raw()
expiry_ts = server_time + (30 * 24 * 3600) # 30 days
# Build and sign
create_session = (
_field(1, 2, user_pubkey) +
_field(2, 2, session_pubkey) +
_field(3, 0, expiry_ts)
)
action = _field(1, 0, server_time) + _field(2, 0, 0) + _field(4, 2, create_session)
length_prefix = _varint_encode(len(action))
message = length_prefix + action
signature = user_key.sign(binascii.hexlify(message))
# Submit
resp = requests.post(
f"{API_URL}/action",
data=message + signature,
headers={"Content-Type": "application/octet-stream"},
timeout=10,
)
if resp.status_code != 200:
print(f"ERROR: {resp.status_code} {resp.text[:200]}")
sys.exit(1)
session_id = decode_session_id(resp.content)
session_privkey_hex = session_key.private_bytes_raw().hex()
print()
print("=" * 50)
print("SESSION CREATED")
print("=" * 50)
print(f" Session ID: {session_id}")
print(f" Session Key: {session_privkey_hex}")
print(f" Wallet: {wallet_b58}")
print(f" Expires: {time.strftime('%Y-%m-%d %H:%M UTC', time.gmtime(expiry_ts))}")
print("=" * 50)
print()
print("Paste these 3 values into Sigma Engine > Connections > 01 Exchange")
print("Your main wallet key was NOT shared.")
Step 3: Run it
Option A — With id.json (Solana CLI format):
python3 zo_session.py
It looks for ~/id.json by default.
Option B — With base58 private key:
ZO_PRIVATE_KEY="your_base58_key_here" python3 zo_session.py
Step 4: Paste into Sigma Engine
You'll see output like:
==================================================
SESSION CREATED
==================================================
Session ID: 1234567890
Session Key: a1b2c3d4e5f6...
Wallet: 7xK9...abc
Expires: 2026-05-10 01:30 UTC
==================================================
Go to Sigma Engine > Connections > 01 Exchange and paste:
- Session ID — the number
- Session Key — the hex string
- Wallet — your base58 public key
That's it. Your session lasts 30 days. Run the script again to renew.
Security
- Your main wallet private key never leaves your machine
- The session key can only trade — it cannot withdraw or transfer funds
- Sessions expire automatically after 30 days
- You can revoke a session anytime by creating a new one