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

build(connector-stellar): add a run soroban transaction endpoint #3296

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
76 changes: 68 additions & 8 deletions packages/cacti-plugin-ledger-connector-stellar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
This plugin provides `Cacti` a way to interact with Stellar networks. Using this we can perform:

- Deploy Smart-contracts over the network.
- Build and sign transactions. (WIP)
- Invoke smart-contract functions that we have deployed on the network. (WIP)
- Build and sign transactions.
- Invoke smart-contract functions that we have deployed on the network.

## Summary

Expand Down Expand Up @@ -51,11 +51,28 @@ This endpoint is responsible for deploying smart contracts to Soroban (Stellar's
**Core Aspects**:

- **Input**: Accepts either a compiled WASM buffer or a WASM hash.
- **WASM Buffer**: Uploads compiled code to Stellar, generates a on-chain WASM hash, then deploys the contract. Refer to the [Stellar documentation](https://developers.stellar.org/docs/learn/fundamentals/stellar-data-structures/contracts) for further detail on this process.
- **WASM Hash**: Directly deploys the contract using the existing WASM hash.

- `wasmBuffer`: Uploads compiled code to Stellar, generates a on-chain WASM hash, then deploys the contract. Refer to the [Stellar documentation](https://developers.stellar.org/docs/learn/fundamentals/stellar-data-structures/contracts) for further detail on this process.
- `wasmHash`: Directly deploys the contract using the existing WASM hash.
- `transactionInvocation`: An object containing data about how the transaction should be assembled and executed.

- **Output**: An object containing the on-chain WASM hash and a unique contract ID of the newly deployed instance.

- **Transaction Invocation**: Provides data for assembling and executing the transactions.
#### `run-soroban-transaction` endpoint

This endpoint is responsible for invoking smart contracts on Soroban (Stellar's smart contract platform) to either change or read a ledger state.

**Core Aspects**:

- **Input**: Accepts either a compiled WASM buffer or a WASM hash.
- `contractId`: The unique contract id of the contract instance to be invoked.
- `method`: The name of the contract method being invoked.
- `methodArgs`: An object containing the arguments accepted by the method.
- `specXdr`: An array containing the contract specification in XDR format.
- `transactionInvocation`: An object containing data about how the transaction should be assembled and executed.
- `readOnly`: A flag to indicate when the transaction should not alter ledger state. When `true`, the transaction will only be simulated based on the current ledger state and provide an up-to-date output without registering the transaction to the ledger, ensuring no fees are consumed.
- **Output**: An object containing the response of the transaction invocation.
- `result`: The direct output of the invoked contract method.

### Usage

Expand Down Expand Up @@ -111,6 +128,28 @@ const deployOut = await connector.deployContract({
});
```

Call example to invoke a contract and return the output value:

```typescript
const res = await connector.runSorobanTransaction({
contractId,
method: "balance",
methodArgs: {
id: adminAccount.getPublicKey(),
},
specXdr: tokenSpec,
readOnly: true,
transactionInvocation: {
header: {
source: adminAccount.getPublicKey(),
fee: 100,
timeout: 30,
},
signers: [adminAccount.getSecretKey()],
},
});
```

### Building/running the container image locally

In the Cacti project root say:
Expand Down Expand Up @@ -168,9 +207,30 @@ docker run \

#### Testing API calls with the container

Don't have a Stellar network on hand to test with? Test or develop against our Stellar All-In-One container!
Don't have a Stellar network on hand to test with? Test or develop against our Stellar All-In-One container by importing the `StellarTestLedger` from `cacti-test-tooling`. It will deploy and manage a docker image based on [Stellar quickstart](https://github.com/stellar/quickstart).

**Usage Example**(refer to the integration tests for further examples):

```typescript
import { StellarTestLedger } from "@hyperledger/cactus-test-tooling";
import { Network } from "stellar-plus/lib/stellar-plus";

const logLevel: LogLevelDesc = "TRACE";
const stellarTestLedger = new StellarTestLedger({ logLevel });

await stellarTestLedger.start();
const networkConfig = Network.CustomNet(
await stellarTestLedger.getNetworkConfiguration(),
);

// Here use the networkConfig object to connect to
// your test ledger and run your tests.

await stellarTestLedger.stop();
await stellarTestLedger.destroy();
```

TODO (WIP)
In this example, the `StellarTestLedger` is used to pull up a fresh new ledger with no history and all of its required services to interact with the network. In conjunction with the `stellar-plus` library, the method `getNetworkConfiguration` is used to get all services data and instantiate an object that can be used with all tools in Stellar Plus to directly interact with the test ledger.

## Prometheus Exporter

Expand All @@ -184,7 +244,7 @@ You can also initialize the prometheus exporter object seperately and then pass
`getPrometheusMetricsV1` function returns the prometheus exporter metrics, currently displaying the total transaction count, which currently increments everytime a Stellar transaction is executed through the connector internal methods. This includes the methods

- `deployContract`
- `runSorobanTransaction()` (_Soon_)
- `runSorobanTransaction()`

### Prometheus Integration

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,65 @@
}
}
},
"RunSorobanTransactionRequest": {
"type": "object",
"additionalProperties": false,
"required": [
"contractId",
"method",
"specXdr",
"transactionInvocation",
"readOnly"
],
"properties": {
"contractId": {
"type": "string",
"pattern": "^C[a-zA-Z0-9]{55}$",
"nullable": false,
"minLength": 56,
"maxLength": 56,
"description": "The ID of the contract that was deployed."
},
"specXdr": {
"type": "array",
"items": {
"type": "string"
},
"nullable": false,
"description": "Array of strings containing the XDR of the contract specification."
},
"method": {
"type": "string",
"nullable": false,
"description": "The method to be called on the contract."
},
"methodArgs": {
"type": "object",
"nullable": true,
"description": "The arguments to pass to the method."
},
"transactionInvocation": {
"$ref": "#/components/schemas/TransactionInvocation",
"nullable": false,
"description": "The transaction invocation that will be used to run the contract."
},
"readOnly": {
"type": "boolean",
"nullable": false,
"description": "Flag indicating if the transaction should be read-only."
}
}
},
"RunSorobanTransactionResponse": {
"type": "object",
"properties": {
"result": {
"type": "object",
"description": "The result of the invoked contract method."
}
},
"description": "Response object containing the result of a contract invocation or error information if it failed."
},
"DeployContractV1Request": {
"type": "object",
"additionalProperties": false,
Expand Down Expand Up @@ -209,6 +268,40 @@
}
}
},
"/api/v1/plugins/@hyperledger/cacti-plugin-ledger-connector-stellar/run-soroban-transaction": {
"post": {
"x-hyperledger-cacti": {
"http": {
"verbLowerCase": "post",
"path": "/api/v1/plugins/@hyperledger/cacti-plugin-ledger-connector-stellar/run-soroban-transaction"
}
},
"operationId": "runSorobanTransactionV1",
"summary": "Executes a Soroban transaction on a stellar ledger",
"parameters": [],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RunSorobanTransactionRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RunSorobanTransactionResponse"
}
}
}
}
}
}
},
"/api/v1/plugins/@hyperledger/cacti-plugin-ledger-connector-stellar/get-prometheus-exporter-metrics": {
"get": {
"x-hyperledger-cacti": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,68 @@
}
}
},

"RunSorobanTransactionRequest": {
"type": "object",
"additionalProperties": false,
"required": [
"contractId",
"method",
"specXdr",
"transactionInvocation",
"readOnly"
],
"properties": {
"contractId": {
"type": "string",
"pattern": "^C[a-zA-Z0-9]{55}$",
"nullable": false,
"minLength": 56,
"maxLength": 56,
"description": "The ID of the contract that was deployed."
},
"specXdr": {
"type": "array",
"items": {
"type": "string"
},
"nullable": false,
"description": "Array of strings containing the XDR of the contract specification."
},
"method": {
"type": "string",
"nullable": false,
"description": "The method to be called on the contract."
},
"methodArgs": {
"type": "object",
"nullable": true,
"description": "The arguments to pass to the method."
},
"transactionInvocation": {
"$ref": "#/components/schemas/TransactionInvocation",
"nullable": false,
"description": "The transaction invocation that will be used to run the contract."
},
"readOnly": {
"type": "boolean",
"nullable": false,
"description": "Flag indicating if the transaction should be read-only."
}
}
},

"RunSorobanTransactionResponse": {
"type": "object",
"properties": {
"result": {
"type": "object",
"description": "The result of the invoked contract method."
}
},
"description": "Response object containing the result of a contract invocation or error information if it failed."
},

"DeployContractV1Request": {
"type": "object",
"additionalProperties": false,
Expand Down Expand Up @@ -209,6 +271,42 @@
}
}
},

"/api/v1/plugins/@hyperledger/cacti-plugin-ledger-connector-stellar/run-soroban-transaction": {
"post": {
"x-hyperledger-cacti": {
"http": {
"verbLowerCase": "post",
"path": "/api/v1/plugins/@hyperledger/cacti-plugin-ledger-connector-stellar/run-soroban-transaction"
}
},
"operationId": "runSorobanTransactionV1",
"summary": "Executes a Soroban transaction on a stellar ledger",
"parameters": [],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RunSorobanTransactionRequest"
}
}
}
},
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RunSorobanTransactionResponse"
}
}
}
}
}
}
},

"/api/v1/plugins/@hyperledger/cacti-plugin-ledger-connector-stellar/get-prometheus-exporter-metrics": {
"get": {
"x-hyperledger-cacti": {
Expand Down
Loading
Loading