There is a helpful blog post at
https://matthewdowney.github.io/create-segwit-address.htmlwhich provides the code to generate the P2SH address from a public key with minimal dependencies.
This is the only thing that needs to be installed:
(base) zenulabidin@artanis:~/Documents$ pip install git+https://github.com/matthewdowney/bip32utils
Collecting git+https://github.com/matthewdowney/bip32utils
Cloning https://github.com/matthewdowney/bip32utils to /tmp/pip-req-build-bqskxgsa
Running command git clone -q https://github.com/matthewdowney/bip32utils /tmp/pip-req-build-bqskxgsa
Requirement already satisfied: ecdsa in /home/zenulabidin/anaconda3/lib/python3.8/site-packages/ecdsa-0.16.1-py3.8.egg (from bip32utils==0.3.post3) (0.16.1)
Requirement already satisfied: six>=1.9.0 in /home/zenulabidin/anaconda3/lib/python3.8/site-packages (from ecdsa->bip32utils==0.3.post3) (1.15.0)
Building wheels for collected packages: bip32utils
Building wheel for bip32utils (setup.py) ... done
Created wheel for bip32utils: filename=bip32utils-0.3.post3-py3-none-any.whl size=10415 sha256=105abc933ae4057dd876b844ec6efc2167c31c9679e6997d187bd8ae186d16a4
Stored in directory: /tmp/pip-ephem-wheel-cache-7_7ylb1d/wheels/04/0c/5b/e5ed2d7087a4d71bcfb1491071e94c657e4b3eeeb09bb362d2
Successfully built bip32utils
Installing collected packages: bip32utils
Successfully installed bip32utils-0.3.post3
Then you can run the code in the link:
import hashlib
def hash160(x): # Both accepts & returns bytes
return hashlib.new('ripemd160', hashlib.sha256(x).digest()).digest()
from bip32utils import Base58
def p2wpkh_in_p2sh_addr(pk, testnet=False):
"""
Compressed public key (hex string) -> p2wpkh nested in p2sh address. 'SegWit address.'
"""
# Script sig is just PUSH(20){hash160(cpk)}
push_20 = bytes.fromhex("0014")
script_sig = push_20 + hash160(bytes.fromhex(pk))
# Address is then prefix + hash160(script_sig)
prefix = b"\xc4" if testnet else b"\x05"
address = Base58.check_encode(prefix + hash160(script_sig))
return address
>>> pub = "03a1af804ac108a8a51782198c2d034b28bf90c8803f5a53f76276fa69a4eae77f"
>>> p2wpkh_in_p2sh_addr(pub)
"36NvZTcMsMowbt78wPzJaHHWaNiyR73Y4g"
>>> p2wpkh_in_p2sh_addr(pub, testnet=True)
"2Mww8dCYPUpKHofjgcXcBCEGmniw9CoaiD2"
I ran the examples above and I was able to reproduce them (there is a small function error in the original post, hash160_bytes should be just hash160).