Skip to content

Commit 38dde1c

Browse files
feat: Add static print functionality to Soroban contracts
Signed-off-by: salaheldinsoliman <[email protected]>
1 parent 06798cd commit 38dde1c

File tree

3 files changed

+65
-43
lines changed

3 files changed

+65
-43
lines changed

integration/soroban/.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@
66
!package.json
77
node_modules
88
package-lock.json
9+
*.txt
10+
*.toml

integration/soroban/runtime_error.sol

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
contract Error {
2+
uint64 count = 1;
3+
4+
/// @notice Calling this function twice will cause an overflow
5+
function decrement() public returns (uint64){
6+
count -= 1;
7+
return count;
8+
}
9+
}

integration/soroban/test_helpers.js

+54-43
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,64 @@
11
import * as StellarSdk from '@stellar/stellar-sdk';
22

3-
4-
53
export async function call_contract_function(method, server, keypair, contract) {
4+
let res = null;
65

7-
let res;
8-
let builtTransaction = new StellarSdk.TransactionBuilder(await server.getAccount(keypair.publicKey()), {
9-
fee: StellarSdk.BASE_FEE,
10-
networkPassphrase: StellarSdk.Networks.TESTNET,
11-
}).addOperation(contract.call(method)).setTimeout(30).build();
12-
13-
let preparedTransaction = await server.prepareTransaction(builtTransaction);
14-
15-
// Sign the transaction with the source account's keypair.
16-
preparedTransaction.sign(keypair);
17-
186
try {
19-
let sendResponse = await server.sendTransaction(preparedTransaction);
20-
if (sendResponse.status === "PENDING") {
21-
let getResponse = await server.getTransaction(sendResponse.hash);
22-
// Poll `getTransaction` until the status is not "NOT_FOUND"
23-
while (getResponse.status === "NOT_FOUND") {
24-
console.log("Waiting for transaction confirmation...");
25-
// See if the transaction is complete
26-
getResponse = await server.getTransaction(sendResponse.hash);
27-
// Wait one second
28-
await new Promise((resolve) => setTimeout(resolve, 1000));
29-
}
30-
31-
if (getResponse.status === "SUCCESS") {
32-
// Make sure the transaction's resultMetaXDR is not empty
33-
if (!getResponse.resultMetaXdr) {
34-
throw "Empty resultMetaXDR in getTransaction response";
35-
}
36-
// Find the return value from the contract and return it
37-
let transactionMeta = getResponse.resultMetaXdr;
38-
let returnValue = transactionMeta.v3().sorobanMeta().returnValue();
39-
console.log(`Transaction result: ${returnValue.value()}`);
40-
res = returnValue.value();
7+
let builtTransaction = new StellarSdk.TransactionBuilder(await server.getAccount(keypair.publicKey()), {
8+
fee: StellarSdk.BASE_FEE,
9+
networkPassphrase: StellarSdk.Networks.TESTNET,
10+
}).addOperation(contract.call(method)).setTimeout(30).build();
11+
12+
let preparedTransaction = await server.prepareTransaction(builtTransaction);
13+
14+
// Sign the transaction with the source account's keypair.
15+
preparedTransaction.sign(keypair);
16+
17+
let sendResponse = await server.sendTransaction(preparedTransaction);
18+
19+
if (sendResponse.status === "PENDING") {
20+
let getResponse = await server.getTransaction(sendResponse.hash);
21+
// Poll `getTransaction` until the status is not "NOT_FOUND"
22+
while (getResponse.status === "NOT_FOUND") {
23+
console.log("Waiting for transaction confirmation...");
24+
// Wait one second
25+
await new Promise((resolve) => setTimeout(resolve, 1000));
26+
// See if the transaction is complete
27+
getResponse = await server.getTransaction(sendResponse.hash);
28+
}
29+
30+
if (getResponse.status === "SUCCESS") {
31+
// Ensure the transaction's resultMetaXDR is not empty
32+
if (!getResponse.resultMetaXdr) {
33+
throw "Empty resultMetaXDR in getTransaction response";
34+
}
35+
// Extract and return the return value from the contract
36+
let transactionMeta = getResponse.resultMetaXdr;
37+
let returnValue = transactionMeta.v3().sorobanMeta().returnValue();
38+
console.log(`Transaction result: ${returnValue.value()}`);
39+
res = returnValue.value();
40+
} else {
41+
throw `Transaction failed: ${getResponse.resultXdr}`;
42+
}
43+
} else if (sendResponse.status === "FAILED") {
44+
// Handle expected failure and return the error message
45+
if (sendResponse.errorResultXdr) {
46+
const errorXdr = StellarSdk.xdr.TransactionResult.fromXDR(sendResponse.errorResultXdr, 'base64');
47+
const errorRes = errorXdr.result().results()[0].tr().invokeHostFunctionResult().code().value;
48+
console.log(`Transaction error: ${errorRes}`);
49+
res = errorRes;
50+
} else {
51+
throw "Transaction failed but no errorResultXdr found";
52+
}
4153
} else {
42-
throw `Transaction failed: ${getResponse.resultXdr}`;
54+
throw sendResponse.errorResultXdr;
4355
}
44-
} else {
45-
throw sendResponse.errorResultXdr;
46-
}
4756
} catch (err) {
48-
// Catch and report any errors we've thrown
49-
console.log("Sending transaction failed");
50-
console.log(err);
57+
// Return the error as a string instead of failing the test
58+
console.log("Transaction processing failed");
59+
console.log(err);
60+
res = err.toString();
5161
}
62+
5263
return res;
53-
}
64+
}

0 commit comments

Comments
 (0)