Hi, there!
@joe-p has a TealScript example for auctions here: auction.algo.ts
He defines bid as follows:
bid(payment: PayTxn): void {
/// Ensure auction hasn't ended
assert(globals.latestTimestamp < this.auctionEnd.value);
/// Verify payment transaction
verifyPayTxn(payment, {
sender: this.txn.sender,
amount: { greaterThan: this.previousBid.value },
});
/// Set global state
this.previousBid.value = payment.amount;
this.previousBidder.value = payment.sender;
/// Update claimable amount
this.claimableAmount(this.txn.sender).value = payment.amount;
}
My question is, how to make a Jest test for this bid call?
I tried his method, as follows:
/**
* Buy 1 piece of the asset
* @param payment Payment in /uAlgos
*/
buyAsset(payment: PayTxn): void {
/// Ensure asset selling period hasn't ended yet
assert(globals.latestTimestamp < this.sellPeriodEnd.value);
/// Verify payment transaction
verifyPayTxn(payment, {
sender: this.txn.sender,
receiver: globals.creatorAddress,
amount: { greaterThanEqualTo: this.assetPrice.value, lessThanEqualTo: this.assetPrice.value },
rekeyTo: globals.zeroAddress,
closeRemainderTo: globals.zeroAddress,
});
/// Verify asset amount
assert(this.assetAmount.value > 0);
/// @todo: check asset amount in buyer account
/// Send asset to payer
sendAssetTransfer({
assetReceiver: this.txn.sender,
xferAsset: this.asset.value,
assetAmount: 1,
});
// Decrease asset amount
this.assetAmount.value = this.assetAmount.value - 1;
}
and tried the following for the Jest test (excerpt):
test('buyAsset', async () => {
const { algod, testAccount } = fixture.context;
const params = await algod.getTransactionParams().do();
await appClient.appClient.fundAppAccount(algokit.microAlgos(400_000));
// Opt in to asset
const globalState = await appClient.getGlobalState();
const asset = globalState.asset!.asNumber();
const txn1 = algosdk.makeAssetTransferTxnWithSuggestedParamsFromObject({
from: sender1.addr,
to: sender1.addr,
amount: 0,
assetIndex: asset,
suggestedParams: params,
});
const stxn1 = txn1.signTxn(sender1.sk);
const txn2 = await algod.sendRawTransaction(stxn1).do();
await algosdk.waitForConfirmation(algod, txn2.txId, 4);
// Make a payment tx
const payment = algosdk.makePaymentTxnWithSuggestedParamsFromObject({
from: sender1.addr,
to: testAccount.addr,
amount: 1_000_000,
suggestedParams: params,
});
// const payment = txn3.signTxn(sender1.sk);
// Buy asset
await appClient.buyAsset({ payment });
});
That is obviously WRONG, the payment isn’t signed. But if I sing it, then I can’t put it into buyAsset as a parameter, I get type error.
OK, compiled TEAL code to the rescure. From the compiled TEAL I see that it waits for a txn grup, and checks whether the last txn in the group is a payment txn:
// buyAsset(pay)void
*abi_route_buyAsset:
// payment: pay
txn GroupIndex
int 1
-
dup
gtxns TypeEnum
int pay
==
assert
// execute buyAsset(pay)void
callsub buyAsset
int 1
return
So I see that a transaction group is needed, where the first tx is the app call, the second is the payment txn, but I still don’t know how to make it in Jest.
Please help! I need to make a demo for a simple DAO in the very near future.