Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: support latest soroban-examples #97

Merged
merged 1 commit into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions features/dapp_develop/dapp_develop.feature
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Scenario Outline: DApp developer compiles, installs, deploys and invokes a contr

Examples:
| Tool | ContractExampleSubPath | ContractName | ContractCompiledFileName | FunctionName | FunctionParams | Result |
| NODEJS | hello_world | soroban-hello-world-contract | soroban_hello_world_contract.wasm | hello | Aloha | ["Hello","Aloha"] |
| NODEJS | hello_world | soroban-hello-world-contract | soroban_hello_world_contract.wasm | hello | to:'Aloha' | ["Hello","Aloha"] |
| CLI | hello_world | soroban-hello-world-contract | soroban_hello_world_contract.wasm | hello | --to=Aloha | ["Hello","Aloha"] |
| NODEJS | increment | soroban-increment-contract | soroban_increment_contract.wasm | increment | | 1 |
| CLI | increment | soroban-increment-contract | soroban_increment_contract.wasm | increment | | 1 |
Expand All @@ -30,7 +30,7 @@ Scenario Outline: DApp developer compiles, deploys and invokes a contract

Examples:
| Tool | ContractExampleSubPath | ContractName | ContractCompiledFileName | FunctionName | FunctionParams | Result | EventCount | DiagEventCount |
| NODEJS | hello_world | soroban-hello-world-contract | soroban_hello_world_contract.wasm | hello | Aloha | ["Hello","Aloha"] | 0 | 1 |
| NODEJS | hello_world | soroban-hello-world-contract | soroban_hello_world_contract.wasm | hello | to:'Aloha' | ["Hello","Aloha"] | 0 | 1 |
| CLI | hello_world | soroban-hello-world-contract | soroban_hello_world_contract.wasm | hello | --to=Aloha | ["Hello","Aloha"] | 0 | 1 |
| NODEJS | increment | soroban-increment-contract | soroban_increment_contract.wasm | increment | | 1 | 0 | 1 |
| CLI | increment | soroban-increment-contract | soroban_increment_contract.wasm | increment | | 1 | 0 | 1 |
Expand Down
107 changes: 65 additions & 42 deletions invoke.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
#!/usr/bin/env ts-node-script

import { ArgumentParser } from 'argparse';

import {
Contract,
Keypair,
TransactionBuilder,
SorobanRpc,
scValToNative,
xdr
xdr,
} from '@stellar/stellar-sdk';

const { Server } = SorobanRpc;
Expand All @@ -33,53 +34,75 @@ async function main() {
functionName,
} = parser.parse_args() as Record<string, string>;

const contract = new Contract(contractId);
const server = new Server(rpcUrl, { allowHttp: true });
const secretKey = Keypair.fromSecret(source);
const account = secretKey.publicKey();
const sourceAccount = await server.getAccount(account);

// Some hacky param-parsing as csv. Generated Typescript bindings would be better.
const params: xdr.ScVal[] = functionParams
? functionParams.split(",").map((p) => xdr.ScVal.scvSymbol(p)) : [];
const keypair = Keypair.fromSecret(source);
const account = keypair.publicKey();

const originalTxn = new TransactionBuilder(sourceAccount, {
fee: "100",
// @ts-ignore contract client only available in stellar-sdk ≥12
const { contract } = await import('@stellar/stellar-sdk');
if (contract) {
const client = await contract.Client.from({
allowHttp: true,
rpcUrl,
networkPassphrase,
})
.addOperation(contract.call(functionName, ...params))
.setTimeout(30)
.build();
contractId,
publicKey: account,
...contract.basicNodeSigner(keypair, networkPassphrase),
});
const args: Record<string, any> = {};
functionParams.split(",").forEach((p) => {
const [name, value] = p.split(":");
args[name] = value;
});
// @ts-ignore client[functionName] is defined dynamically
const { result } = await client[functionName](args);
console.log(JSON.stringify(result));
return;
} else {
const server = new Server(rpcUrl, { allowHttp: true });
const sourceAccount = await server.getAccount(account);
const contract = new Contract(contractId);
// Some hacky param-parsing as csv. Generated Typescript bindings would be better.
const params: xdr.ScVal[] = functionParams
? functionParams.split(",").map((p) => xdr.ScVal.scvSymbol(p.split(':')[1])) : [];

const txn = await server.prepareTransaction(originalTxn);
txn.sign(secretKey);
const send = await server.sendTransaction(txn);
if (send.errorResult) {
throw new Error(`Transaction failed: ${JSON.stringify(send)}`);
}
let response = await server.getTransaction(send.hash);
for (let i = 0; i < 50; i++) {
switch (response.status) {
case "NOT_FOUND": {
// retry
await new Promise(resolve => setTimeout(resolve, 100));
response = await server.getTransaction(send.hash);
break;
const originalTxn = new TransactionBuilder(sourceAccount, {
fee: "100",
networkPassphrase,
})
.addOperation(contract.call(functionName, ...params))
.setTimeout(30)
.build();

const txn = await server.prepareTransaction(originalTxn);
txn.sign(keypair);
const send = await server.sendTransaction(txn);
if (send.errorResult) {
throw new Error(`Transaction failed: ${JSON.stringify(send)}`);
}
case "SUCCESS": {
if (!response.returnValue) {
throw new Error(`No invoke host fn return value provided: ${JSON.stringify(response)}`);
let response = await server.getTransaction(send.hash);
for (let i = 0; i < 50; i++) {
switch (response.status) {
case "NOT_FOUND": {
// retry
await new Promise(resolve => setTimeout(resolve, 100));
response = await server.getTransaction(send.hash);
break;
}
case "SUCCESS": {
if (!response.returnValue) {
throw new Error(`No invoke host fn return value provided: ${JSON.stringify(response)}`);
}

const parsed = scValToNative(response.returnValue);
console.log(JSON.stringify(parsed));
return;
}
case "FAILED": {
throw new Error(`Transaction failed: ${JSON.stringify(response)}`);
}
default:
throw new Error(`Unknown transaction status: ${response.status}`);
const parsed = scValToNative(response.returnValue);
console.log(JSON.stringify(parsed));
return;
}
case "FAILED": {
throw new Error(`Transaction failed: ${JSON.stringify(response)}`);
}
default:
throw new Error(`Unknown transaction status: ${response.status}`);
}
}
}
throw new Error("Transaction timed out");
Expand Down
Loading