I’ve created an lsig file following the buildweb3 tutorial.
goal clerk compile -a <PUBLIC KEY> -s step5.teal -o step5.lsig
I’ve adapted the step5.py
script so that only the transaction with the lsig file is signed when sending the transactions. I had planned to have the other signed using Algosigner by passing the transaction ID.
However, I’m getting exceptions and am unsure how to solve them.
import json
import base64
from pathlib import Path
from algosdk.v2client import algod
from algosdk import transaction
from algosdk import encoding
from app import const
class AtomicSwap:
def __init__(
self,
seller = const.SELLER_ADDR,
receiver = const.RECEIVER,
asset_id = const.ASSET_ID,
asset_price = const.ASSET_PRICE,
asset_count = 1,
trxn_params=None
):
self.seller = seller
self.receiver = receiver
self.asset_id = asset_id
self.asset_count = asset_count
self.asset_price = asset_price
self.algod_client = connect_to_network()
# utility for waiting on a transaction confirmation
def wait_for_confirmation(self, txid):
while True:
txinfo = self.algod_client.pending_transaction_info(txid)
if txinfo.get('round') and txinfo.get('round') > 0:
print("Transaction {} confirmed in round {}.".format(txid, txinfo.get('round')))
break
else:
print("Waiting for confirmation...")
self.algod_client.status_after_block(algod_client.status().get('lastRound') +1)
def build(self):
# get suggested parameters
params = self.algod_client.suggested_params()
gh = params.gh
first_valid_round = params.first
last_valid_round = params.last
fee = params.min_fee
# create transaction 1 - Payment
txn1 = transaction.PaymentTxn(
self.receiver, fee, first_valid_round, last_valid_round,
gh, self.seller, int(self.asset_count*self.asset_price)
)
# create transaction 2 - Asset transfer
txn2 = transaction.AssetTransferTxn(
self.seller, fee, first_valid_round,
last_valid_round, gh, self.receiver,
self.asset_count, self.asset_id
)
# get group id and assign it to transactions
gid = transaction.calculate_group_id([txn1, txn2])
txn1.group = gid
txn2.group = gid
# sign transaction2
with open(Path(const.smart_contracts_dir) / const.smart_contract_fname, "rb") as f:
lsig = encoding.future_msgpack_decode(base64.b64encode(f.read()))
stxn2 = transaction.LogicSigTransaction(txn2, lsig)
signedGroup = [txn1, stxn2]
# send them over network - FAILS HERE!
txID = self.algod_client.send_transactions(
signedGroup
)
wait_for_confirmation(self.algod_client, txID)
return txnID
def connect_to_network():
""" utility to connect to node """
algod_address = const.algod_address
algod_token = const.algod_token
algod_client = algod.AlgodClient(
const.algod_token,
const.algod_address,
headers=const.purestake_token
)
return algod_client
sc = AtomicSwap()
print(sc.build())
But, when trying to send the transactions, I’m getting the error:
algosdk.error.AlgodHTTPError: {"message":"msgpack decode error [pos 5]: no matching struct field found when decoding stream map with key amt"}
I attempted to solve this by changing the headers passed to the purestake API from purestake_token = {'X-Api-key': algod_token}
to purestake_token = {'X-Api-key': algod_token, 'content-type': 'application/x-binary'}
.
But this fails with algosdk.error.AlgodHTTPError: {"message": "Unsupported Media Type"}
when attempting to get suggested transactions.
How to solve this? And is my logic valid?