Skip to content

Commit

Permalink
feat: Add static print functionality to Soroban contracts
Browse files Browse the repository at this point in the history
Signed-off-by: salaheldinsoliman <[email protected]>
  • Loading branch information
salaheldinsoliman committed Aug 11, 2024
1 parent 06798cd commit 38dde1c
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 43 deletions.
2 changes: 2 additions & 0 deletions integration/soroban/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@
!package.json
node_modules
package-lock.json
*.txt
*.toml
9 changes: 9 additions & 0 deletions integration/soroban/runtime_error.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
contract Error {
uint64 count = 1;

/// @notice Calling this function twice will cause an overflow
function decrement() public returns (uint64){
count -= 1;
return count;
}
}
97 changes: 54 additions & 43 deletions integration/soroban/test_helpers.js
Original file line number Diff line number Diff line change
@@ -1,53 +1,64 @@
import * as StellarSdk from '@stellar/stellar-sdk';



export async function call_contract_function(method, server, keypair, contract) {
let res = null;

let res;
let builtTransaction = new StellarSdk.TransactionBuilder(await server.getAccount(keypair.publicKey()), {
fee: StellarSdk.BASE_FEE,
networkPassphrase: StellarSdk.Networks.TESTNET,
}).addOperation(contract.call(method)).setTimeout(30).build();

let preparedTransaction = await server.prepareTransaction(builtTransaction);

// Sign the transaction with the source account's keypair.
preparedTransaction.sign(keypair);

try {
let sendResponse = await server.sendTransaction(preparedTransaction);
if (sendResponse.status === "PENDING") {
let getResponse = await server.getTransaction(sendResponse.hash);
// Poll `getTransaction` until the status is not "NOT_FOUND"
while (getResponse.status === "NOT_FOUND") {
console.log("Waiting for transaction confirmation...");
// See if the transaction is complete
getResponse = await server.getTransaction(sendResponse.hash);
// Wait one second
await new Promise((resolve) => setTimeout(resolve, 1000));
}

if (getResponse.status === "SUCCESS") {
// Make sure the transaction's resultMetaXDR is not empty
if (!getResponse.resultMetaXdr) {
throw "Empty resultMetaXDR in getTransaction response";
}
// Find the return value from the contract and return it
let transactionMeta = getResponse.resultMetaXdr;
let returnValue = transactionMeta.v3().sorobanMeta().returnValue();
console.log(`Transaction result: ${returnValue.value()}`);
res = returnValue.value();
let builtTransaction = new StellarSdk.TransactionBuilder(await server.getAccount(keypair.publicKey()), {
fee: StellarSdk.BASE_FEE,
networkPassphrase: StellarSdk.Networks.TESTNET,
}).addOperation(contract.call(method)).setTimeout(30).build();

let preparedTransaction = await server.prepareTransaction(builtTransaction);

// Sign the transaction with the source account's keypair.
preparedTransaction.sign(keypair);

let sendResponse = await server.sendTransaction(preparedTransaction);

if (sendResponse.status === "PENDING") {
let getResponse = await server.getTransaction(sendResponse.hash);
// Poll `getTransaction` until the status is not "NOT_FOUND"
while (getResponse.status === "NOT_FOUND") {
console.log("Waiting for transaction confirmation...");
// Wait one second
await new Promise((resolve) => setTimeout(resolve, 1000));
// See if the transaction is complete
getResponse = await server.getTransaction(sendResponse.hash);
}

if (getResponse.status === "SUCCESS") {
// Ensure the transaction's resultMetaXDR is not empty
if (!getResponse.resultMetaXdr) {
throw "Empty resultMetaXDR in getTransaction response";
}
// Extract and return the return value from the contract
let transactionMeta = getResponse.resultMetaXdr;
let returnValue = transactionMeta.v3().sorobanMeta().returnValue();
console.log(`Transaction result: ${returnValue.value()}`);
res = returnValue.value();
} else {
throw `Transaction failed: ${getResponse.resultXdr}`;
}
} else if (sendResponse.status === "FAILED") {
// Handle expected failure and return the error message
if (sendResponse.errorResultXdr) {
const errorXdr = StellarSdk.xdr.TransactionResult.fromXDR(sendResponse.errorResultXdr, 'base64');
const errorRes = errorXdr.result().results()[0].tr().invokeHostFunctionResult().code().value;
console.log(`Transaction error: ${errorRes}`);
res = errorRes;
} else {
throw "Transaction failed but no errorResultXdr found";
}
} else {
throw `Transaction failed: ${getResponse.resultXdr}`;
throw sendResponse.errorResultXdr;
}
} else {
throw sendResponse.errorResultXdr;
}
} catch (err) {
// Catch and report any errors we've thrown
console.log("Sending transaction failed");
console.log(err);
// Return the error as a string instead of failing the test
console.log("Transaction processing failed");
console.log(err);
res = err.toString();
}

return res;
}
}

0 comments on commit 38dde1c

Please sign in to comment.