Skip to content

Instantly share code, notes, and snippets.

@DanBurton
Last active January 6, 2023 20:04
Show Gist options
  • Save DanBurton/d11a6c8a99b33f28ea7fc83a82ccaef8 to your computer and use it in GitHub Desktop.
Save DanBurton/d11a6c8a99b33f28ea7fc83a82ccaef8 to your computer and use it in GitHub Desktop.
Discover HumbleSwap v2 pools via Event logs
import algosdk from 'algosdk';
import { sha512_256 } from 'js-sha512';
const indexer = new algosdk.Indexer('', 'https://mainnet-idx.algonode.cloud', '');
// The Reach declaration for this Event type is:
// Register: [ Contract, MToken, Token ]
// Event signature prefix, see ARC 28
// https://github.com/reach-sh/ARCs/blob/arc-0028-events/ARCs/arc-0028.md
const sig = 'Register(uint64,(byte,byte[8]),uint64)';
const prefix_hex = sha512_256(sig).slice(0,8);
// We are ignoring next-token for simplicity in this example
const appid = 771884869;
const logs_nested = await indexer.lookupApplicationLogs(appid).do();
const logs = logs_nested['log-data'].map((x) => x.logs).flat();
// Filter down to only the Register logs by looking for the matching prefix
const register_logs = logs.filter((l) =>
prefix_hex === Buffer.from(l, 'base64').slice(0,4).toString('hex')
);
// interpret the next 8 bytes after the 4-byte prefix as the registered Contract (appid: uint64)
const registered_appids = register_logs.map((l) =>
Number('0x' + Buffer.from(l, 'base64').slice(4,12).toString('hex'))
);
console.log(registered_appids);
@DanBurton
Copy link
Author

sample output:

$ node logparse.mjs
[
  771891102, 773172535, 777623301, 777628254, 777639704,
  777643671, 777657671, 777662431, 777670234, 777673635,
  777736409, 777747637, 777878364, 778031658, 778051470,
  779141178, 779142716, 779144473, 779146836, 779148387,
  779149552, 779634856, 779655316, 779712918, 780019724,
  780417867, 780419039, 780420235, 780434326, 780975511,
  781760847, 783216201, 783345603, 784577700, 785782947,
  786634915, 786647110, 786647448, 786786367, 787300124,
  788058822, 788245364, 789897919, 789917736, 789941730,
  790440838, 791663864, 792015446, 792655439, 794422646,
  796188450, 798217167, 800566087, 800827422, 802880767,
  803352524, 804335626, 805140967, 805202737, 805234207,
  805698042, 805930289, 805959700, 807380472, 808427510,
  808604926, 809514206, 809516228, 810058782, 810072531,
  810991930, 810996104, 811067896, 814401475, 814854166,
  815811487, 816349683, 817376950, 817459914, 818602187,
  819431564, 819867425
]

@algolog
Copy link

algolog commented Jan 6, 2023

Translated to Python

#!/usr/bin/env python

# List Humble.sh DEX pools from on-chain logs.
# Translated to Python from https://gist.github.com/DanBurton/d11a6c8a99b33f28ea7fc83a82ccaef8
# Pool ABI docs: https://reach-sh.github.io/humble-sdk/LP-ABI.html

from itertools import chain
from base64 import b64decode
from algosdk.v2client.indexer import IndexerClient
from algosdk.encoding import checksum

indexer = IndexerClient("", "https://mainnet-idx.algonode.cloud")

# The Reach declaration for pool registration Event type is:
#    Register: [ Contract, MToken, Token ]
# Event signature prefix, see ARC 28
# https://github.com/reach-sh/ARCs/blob/arc-0028-events/ARCs/arc-0028.md
sig = 'Register(uint64,(byte,byte[8]),uint64)'.encode()
prefix_hex = checksum(sig).hex()[0:8]

manager_app_id = 771884869
# We are ignoring next-token for simplicity in this example
logs_nested = indexer.application_logs(manager_app_id)

# make flat list of all logs
logs = list(chain.from_iterable(x['logs'] for x in logs_nested['log-data']))

# Filter down to only the Register logs by looking for the matching prefix
register_logs = [l for l in logs if b64decode(l)[0:4].hex() == prefix_hex]

for l in register_logs:
    data = b64decode(l)
    # interpret the next 8 bytes after the 4-byte prefix as the registered Contract (app_id: uint64)
    pool_app_id = int(data[4:12].hex(), base=16)

    pool_type = int(data[12:13].hex(), base=16)
    assetA = int(data[13:21].hex(), base=16)
    assetB = int(data[21:29].hex(), base=16)
    if pool_type == 0:
        if assetA != 0:
            raise ValueError("Non-zero assetA for ALGO-OTHER pool type.")

    print(f"{pool_app_id:12} {assetA:12} {assetB:12}")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment