Skip to content

Commit

Permalink
Merge pull request #69 from multiversx/facades-01
Browse files Browse the repository at this point in the history
Sketch a simple facade: the entrypoint
  • Loading branch information
andreibancioiu authored Jul 25, 2024
2 parents f622c44 + 1def751 commit f4c7c95
Show file tree
Hide file tree
Showing 11 changed files with 478 additions and 1 deletion.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@ The methods are named in correspondence with the use cases they implement, e.g.

Optionally, the implementing library can choose to return an object that isn't a complete representation of the `Transaction`, if desired. In this case, the library must name the incomplete representation `DraftTransaction`, and also must provide a direct conversion facility from `DraftTransaction` to `Transaction` - for example, a named constructor. See [transaction](core/transaction.md).

### Transactions Controllers

The transaction controllers are components built upon the lower-level transaction factories and transaction outcome parsers. They are able to create signed transactions and parse the outcome of these transactions. The controllers are specialized for a "family" of transactions (e.g. transfer transactions, delegation transactions, smart contract transactions), just like the factories and the outcome parsers.

One controller is backed by **one transaction factory and one outcome parser** (paired).

- All functions that create transactions receive as first parameter the `sender: IAccount`. They also receive an optional `guardian: IAccount`.
- All functions that create transactions receive a nonce, which is optional. If not provided, the nonce is fetched from the network.
- All functions that create transactions return already-signed transactions.
- All functions that parse transactions outcomes receive a `TransactionOnNetwork`.
- All functions that parse transactions outcomes are paired with an additional function that awaits the completion of the transaction on the network (before parsing the outcome). For example, `parse_deploy` is paired with `await_completed_deploy`.

## Guidelines

### **`in-ifaces-out-concrete-types`**
Expand Down
8 changes: 8 additions & 0 deletions core/controllers/account_management_controller.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## AccountManagementController

Promotes all the functionality of `AccountManagementTransactionsFactory` and `AccountManagementTransactionsOutcomeParser`.

```
class AccountManagementController:
...
```
28 changes: 28 additions & 0 deletions core/controllers/delegation_controller.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
## DelegationController

Promotes all the functionality of `DelegationTransactionsFactory` and `DelegationTransactionsOutcomeParser`.

```
class DelegationController:
// The constructor is not captured by the specs; it's up to the implementing library to define it.
// Suggestions:
constructor(network_provider: INetworkProvider);
create_transaction_for_new_delegation_contract({
sender: IAccount;
nonce: int;
totalDelegationCap: Amount;
service_fee: number;
amount: Amount;
}): Transaction;
parse_create_new_delegation_contract(transaction_on_network: TransactionOnNetwork): {
contract_address: string;
}[];
await_completed_create_new_delegation_contract(transaction_on_network: TransactionOnNetwork): {
contract_address: string;
}[];
// ...
```
8 changes: 8 additions & 0 deletions core/controllers/relayed_controller.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## RelayedController

Promotes all the functionality of `RelayedTransactionsFactory` and `RelayedTransactionsOutcomeParser`.

```
class RelayedController:
...
```
117 changes: 117 additions & 0 deletions core/controllers/smart_contract_controller.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
## SmartContractController

Promotes all the functionality of `SmartContractTransactionsFactory`, `SmartContractTransactionsOutcomeParser` and `SmartContractQueriesController`.

```
class SmartContractController:
// The constructor is not captured by the specs; it's up to the implementing library to define it.
// Suggestions:
constructor(network_provider: INetworkProvider, abi: Optional[Abi]);
create_transaction_for_deploy({
sender: IAccount;
nonce: Optional[int];
bytecode: bytes OR bytecodePath: Path;
arguments: List[object] = [];
native_transfer_amount: Amount = 0;
is_upgradeable: bool = True;
is_readable: bool = True;
is_payable: bool = False;
is_payable_by_contract: bool = True;
gas_limit: uint32;
}): Transaction;
parse_deploy(transaction_on_network: TransactionOnNetwork): {
return_code: string;
return_message: string;
contracts: List[{
address: string;
ownerAddress: string;
codeHash: bytes;
}];
};
// Does "await_completed_transaction" and "parse_deploy" in one go.
await_completed_deploy(transaction_hash: string): {
return_code: string;
return_message: string;
contracts: List[{
address: string;
ownerAddress: string;
codeHash: bytes;
}];
};
create_transaction_for_upgrade({
sender: IAccount;
nonce: Optional[int];
contract: IAddress;
bytecode: bytes OR bytecodePath: Path;
arguments: List[object] = [];
native_transfer_amount: Amount = 0;
is_upgradeable: bool = True;
is_readable: bool = True;
is_payable: bool = False;
is_payable_by_contract: bool = True;
gas_limit: uint32;
}): Transaction;
// This method is less important (supports an exotic flow).
parse_upgrade(transaction_on_network: TransactionOnNetwork): {
return_code: string;
return_message: string;
contracts: List[{
address: string;
codeHash: bytes;
}];
};
// Specialized function to await and parse a contract upgrade transaction.
// Does "await_completed_transaction" and "parse_upgrade" in one go.
await_completed_upgrade(transaction_hash: string): {
return_code: string;
return_message: string;
contracts: List[{
address: string;
codeHash: bytes;
}];
};
create_transaction_for_execute({
sender: IAccount;
nonce: Optional[int];
contract: IAddress;
// If "function" is a reserved word in the implementing language, it should be replaced with a different name (e.g. "func" or "functionName").
function: string;
arguments: List[object] = [];
native_transfer_amount: Amount = 0;
token_transfers: List[TokenTransfer] = [];
gas_limit: uint32;
}): Transaction;
parse_execute({
transaction_on_network: TransactionOnNetwork,
function?: string
}): {
values: List[any];
return_code: string;
return_message: string;
};
// Does "await_completed_transaction" and "parse_execute" in one go.
await_completed_execute({
transaction_hash: string;
}): {
values: List[any];
return_code: string;
return_message: string;
};
query_contract({
contract: IAddress;
caller?: IAddress;
value?: Amount;
function: string;
arguments: List[object];
}): List[any];
```
8 changes: 8 additions & 0 deletions core/controllers/token_management_controller.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## TokenManagementController

Promotes all the functionality of `TokenManagementTransactionsFactory` and `TokenManagementTransactionsOutcomeParser`.

```
class TokenManagementController:
...
```
10 changes: 10 additions & 0 deletions core/controllers/transfers_controller.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
## TransfersController

Promotes all the functionality of `TransferTransactionsFactory` and `TransferTransactionsOutcomeParser`.

```
class TransfersController:
// The constructor is not captured by the specs; it's up to the implementing library to define it.
// Suggestions:
constructor(network_provider: INetworkProvider);
```
4 changes: 3 additions & 1 deletion core/transactions-factories/relayed_transactions_factory.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## RelayedTransactionsFactory

```
class RelayedTransactionsFactory:
// The constructor is not captured by the specs; it's up to the implementing library to define it.
// Generally speaking, the constructor should be parametrized with a configuration object which defines entries such as:
Expand All @@ -26,5 +27,6 @@ class RelayedTransactionsFactory:
// does not set gasLimit
create_relayed_v3_transaction({
relayer_addresss: IAddress;
innerTransactions: List[ITransaction];
inner_transactions: List[ITransaction];
}): Transaction;
```
9 changes: 9 additions & 0 deletions core/transactions-factories/transfer_transactions_factory.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ class TransferTransactionsFactory:
// Generally speaking, the constructor should be parametrized with a configuration object which defines entries such as:
// "minGasLimit", "gasLimitPerByte", "issueCost", gas limit for specific operations etc. (e.g. "gasLimitForESDTTransfer").
// If multiple transfers are specified, or if a native amount and a token transfer are specified, then a multi-ESDT transfer transaction should be created.
create_transaction_for_transfer({
sender: IAddress;
receiver: IAddress;
native_amount: Optional[Amount];
data: Optional[bytes];
token_transfers: TokenTransfer[];
}): Transaction;
create_transaction_for_native_token_transfer({
sender: IAddress;
receiver: IAddress;
Expand Down
36 changes: 36 additions & 0 deletions facades/account.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
## Account

```
class Account:
// The constructor is not captured by the specs; it's up to the implementing library to define it.
// Suggestions:
constructor(secret_key: bytes, hrp: Optional[str]);
constructor(user_signer: IUserSigner, hrp: Optional[str]);
address: IAddress;
// Local copy of the account nonce.
// Must be explicitly managed by client code.
nonce: uint64;
sign(data: bytes): bytes;
// Gets the nonce (the one from the object's state) and increments it.
get_nonce_then_increment(): uint64;
// Named constructor
// Loads a secret key from a PEM file. PEM files may contain multiple accounts - thus, an (optional) "index" is used to select the desired secret key.
// Returns an Account object, initialized with the secret key.
static new_from_pem(path: Path, index: Optional[int], hrp: Optional[str]): Account;
// Named constructor
// Loads a secret key from an encrypted keystore file. Handles both keystores that hold a mnemonic and ones that hold a secret key (legacy).
// For keystores that hold an encrypted mnemonic, the optional "address_index" parameter is used to derive the desired secret key.
// Returns an Account object, initialized with the secret key.
static new_from_keystore(path: Path, password: str, address_index: Optional[int], hrp: Optional[str]): Account;
// Named constructor
// Loads (derives) a secret key from a mnemonic. The optional "address_index" parameter is used to guide the derivation.
// Returns an Account object, initialized with the secret key.
static new_from_mnemonic(mnemonic: str, address_index: Optional[int], hrp: Optional[str]): Account;
```
Loading

0 comments on commit f4c7c95

Please sign in to comment.