Skip to main content

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.json key 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:

  1. Session ID — the number
  2. Session Key — the hex string
  3. 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