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

merge sprint-41 #1104

Closed
wants to merge 9 commits into from
47 changes: 36 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,17 +131,6 @@ Under the current implementation, all stablecoins may choose to implement a proo

> A proof of reserve is, in very simple terms, an external feed that provides the backing of the tokens in real world. This may be FIAT or other assets.

## Multisignature functionality

The Stablecoin solution enables the management of a stablecoin through a multi-key account, where the admin key is configured as either a key list or a threshold key.

When an operation (cash-in, burn, ...) is carried out using the _multisig_ mode, the corresponding transaction will not be directly submitted to the Hedera DLT, instead, it will be temporarily stored in a backend waiting for the multisig account key owners to sign it. Once it has been signed by all the required keys it will be available for submission.

It's crucial to note that there is a time constraint for multisig transactions: they must be signed and submitted within three minutes of their initiation. If this timeframe is not met, the Hedera DLT will consider these transactions as expired and reject them.

> The functionality has a limitation: Complex keys must have only one level, in other words, key list and threshold keys must contain only ED25519/ECDSA keys, they cannot contain firther key lists and/or threshold keys.


### Setting up a proof of reserve

During setup, it is possible to link an existing data feed by providing the smart contract's address, or create a new one based on our implementation. If a reserve was created during the stablecoin deployment, it will also be possible to edit the amount of the reserve.
Expand All @@ -160,6 +149,42 @@ In any case, the reserve address can be edited after creation. However, changing

For more information about the SDK and the methods to perform these operations, visit to the [docs](https://github.com/hashgraph/stablecoin-studio/tree/main/sdk#reserve-data-feed).

## Multisignature functionality

Hedera allows for the creation of accounts with complex key structures (__multi-key accounts__), enabling configurations that require multiple signatures from different ED25519 or ECDSA keys to authorize transactions.

These accounts can use simple multi-signature setups or more sophisticated threshold key arrangements, where a specific number of approvals from a designated group of key holders is necessary to execute transactions. This functionality is ideal for enhancing security and governance in applications requiring collective decision-making.

For more information about this type of account please check the official Hedera documentation about [key structures](https://docs.hedera.com/hedera/core-concepts/keys-and-signatures#key-structures).

> If you need to deploy a brand new multikey account you can use our [script](https://github.com/hashgraph/stablecoin-studio/tree/main/sdk/scripts/CreateMultisigAccount.ts). Follow the instructions in the script itself (comment section at the begining)

The Stablecoin solution enables the management of a stablecoin through multi-key accounts.

When an operation (cash-in, burn, ...) is carried out using the _multisig_ mode, the corresponding transaction will not be directly submitted to the Hedera DLT, instead, it will be temporarily stored in a backend waiting for the multisig account key owners to sign it. Once it has been signed by all the required keys it will be available for submission.

It's crucial to note that there is a time constraint for multisig transactions: they must be signed and submitted within three minutes of their initiation. If this timeframe is not met, the Hedera DLT will consider these transactions as expired and reject them.

> The functionality has a limitation: Complex keys must have only one level, in other words, key list and threshold keys must contain only ED25519/ECDSA keys, they cannot contain further key lists and/or threshold keys.

### Steps to deploy a multisig-managed stablecoin

If you wish to deploy a stablecoin and fully manage it with a multisig account the steps to follow are:
- Using a single key account, deploy a stablecoin assigning all roles and the proxy admin ownership to the multisig account
- Once the stablecoin is deployed, assign the "admin" role to the multisig account.
> The admin role is the only one that cannot be assigned automatically during the initial deployment
- Remove the admin role from the single key account used to deploy the stablecoin
> The admin role is automatically assigned to the deploying account
- Connect to the stablecoin platform using the multisig account and manually import the deployed stablecoin
> Since the deployment was carried out by another account, the multisig account was not associated to the token, that is the reason why you need to import it manually. It you associate your multisig account to the stablecoin's hedera token, you will not need to import it anymore.

### Importing a multisig account key into a Wallet

In order to manage a stablecoin using a multisig account we will need to, **for every single key _K_** in the multisig account's key list / threshold key, do as follows:
- Create a single key account _A_ and set _K_ as its admin key
- Import _A_ into Hashpack/Blade/Metamask/... depending on whether _K_ is an ED25519 or ECDSA key
- Whenever we want to sign a multisig transaction using _K_, we will log into the wallet we used to import _A_ and carry out the signature.

# Architecture

The project is divided in 5 node modules:
Expand Down
4 changes: 2 additions & 2 deletions backend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion backend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@hashgraph/stablecoin-npm-backend",
"version": "1.18.0",
"version": "1.19.0",
"description": "",
"author": "",
"license": "Apache-2.0",
Expand Down
6 changes: 3 additions & 3 deletions cli/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@hashgraph/stablecoin-npm-cli",
"version": "1.18.0",
"version": "1.19.0",
"description": "CLI for Hedera Stablecoin",
"main": "./build/src/index.js",
"bin": {
Expand Down
4 changes: 2 additions & 2 deletions contracts/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion contracts/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@hashgraph/stablecoin-npm-contracts",
"version": "1.18.0",
"version": "1.19.0",
"description": "",
"main": "./build/typechain-types/index.js",
"module": "./build/typechain-types/index.js",
Expand Down
2 changes: 1 addition & 1 deletion defenders/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "accelerator-service",
"version": "1.18.0",
"version": "1.19.0",
"description": "Accelerator integration with OZ Defenders",
"license": "Apache-2.0",
"devDependencies": {
Expand Down
4 changes: 2 additions & 2 deletions hashconnect/lib/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion hashconnect/lib/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@hashgraph/hashconnect",
"version": "1.18.0",
"version": "1.19.0",
"description": "hashconnect interoperability library",
"author": "Tyler Coté <[email protected]>, Nick Hanna <[email protected]>",
"license": "Apache-2.0",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hedera-stable-coin",
"version": "1.18.0",
"version": "1.19.0",
"description": "stablecoin studio",
"scripts": {
"install": "node install.js && npm run build:cli:full && npm run prepare",
Expand Down
8 changes: 4 additions & 4 deletions sdk/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@hashgraph/stablecoin-npm-sdk",
"version": "1.18.0",
"version": "1.19.0",
"description": "stablecoin studio SDK",
"main": "./build/cjs/src/index.js",
"module": "./build/esm/src/index.js",
Expand Down Expand Up @@ -45,6 +45,7 @@
"typescript": "^4.9.4"
},
"scripts": {
"execute:createMultisig": "node build/cjs/scripts/CreateMultisigAccount.js",
"start": "node build/src/index.js",
"clean": "rimraf coverage build",
"prebuild": "npm run lint",
Expand Down
97 changes: 97 additions & 0 deletions sdk/scripts/CreateMultisigAccount.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
*
* Hedera Stablecoin SDK
*
* Copyright (C) 2023 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

/**
* DESCRIPTION
* This script will deploy a multi-key account with a key list made of 2 keys:
* - one ED25519 key
* - one EDCSA key
*
* HOW TO RUN IT
* 1- Fill in the following constants : Multisig_ED25519_privateKey, Multisig_ECDSA_privateKey, deployingAccount
* 2- Compile the script : npm run build (this command will actually build all the typescript files in the module)
* 3- Run the compiled script : npm run execute:createMultisig
* 4- the multisig account id will be displayed in the console.
*/

import {
AccountCreateTransaction,
KeyList,
Client,
PrivateKey,
AccountId,
} from '@hashgraph/sdk';

// Hex encoded private key of the ED25519 key that will be added to the multisig account's key
const Multisig_ED25519_privateKey = '';

// Hex encoded private key of the ECDSA key that will be added to the multisig account's key
const Multisig_ECDSA_privateKey = '';

// Account Id and Hex encoded ECDSA private key of the single key account that will be used to deploy the multisig account.
// MAKE SURE this account has funds as it will pay for the account creation fees !!!!!!!!!!!
const deployingAccount = {
id: '',
ECDSA_privateKey: '',
};

const delay = async (seconds = 5): Promise<void> => {
seconds = seconds * 1000;
await new Promise((r) => setTimeout(r, seconds));
};

async function createMultisigAccount(): Promise<string> {
const signerKeys = [
PrivateKey.fromStringED25519(Multisig_ED25519_privateKey),
PrivateKey.fromStringECDSA(Multisig_ECDSA_privateKey),
];

const keyList = KeyList.of(
signerKeys[0].publicKey,
signerKeys[1].publicKey,
);

const newAccountTx = new AccountCreateTransaction().setKey(keyList);

const client = Client.forTestnet().setOperator(
AccountId.fromString(deployingAccount.id),
PrivateKey.fromStringECDSA(deployingAccount.ECDSA_privateKey),
);

const newAccountResponse = await newAccountTx.execute(client);

await delay();

const newAccountReceipt = await newAccountResponse.getReceipt(client);
const newAccountId = newAccountReceipt.accountId;

const multisigAccountId = newAccountId!.toString();

Check warning on line 85 in sdk/scripts/CreateMultisigAccount.ts

View workflow job for this annotation

GitHub Actions / testing

Forbidden non-null assertion

return multisigAccountId;
}

// Main
createMultisigAccount()
.then((events) => {
console.log(events);
})
.catch((error) => {
console.error(error);
});
2 changes: 1 addition & 1 deletion sdk/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@
"resolveJsonModule": true
},
"exclude": ["build/**/*", "node_modules", "example/**/*"],
"include": ["src/**/*", "__tests__/**/*"]
"include": ["src/**/*", "__tests__/**/*", "scripts/**/*"]
}
3 changes: 2 additions & 1 deletion web/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ The ENV file contains the following parameters:
- **REACT_APP_FACTORIES**: This var is only required if you want to create a new stablecoin. The var must be a JSON array with a factory proxy id in Hedera format `0.0.XXXXX` per environment. Regarding this, your can find the factories proxy's contract ids depending on the Stablecoin Studio versión [here](./../FACTORY_VERSION.md).
- **REACT_APP_MIRROR_NODE**: This var is required if you want to create a new stablecoin. The var must be a unique mirror node service for each Hedera network, and this is the service which would be used when the UI starts. The service is configured by the environment and the base url properties, and, optionally, can also have an api key and a http header through which the api key is provided.
- **REACT_APP_RPC_NODE**: This var is required if you want to create a new stablecoin. The var must be a unique rpc node service for Hedera network, and this is the service which would be used when the UI starts. The service is configured using the same properties than the mirror node. You can check the available JSON-RPC relays [here](https://github.com/hashgraph/stablecoin-studio/blob/main/README.md#JSON-RPC-Relays).
- **REACT_APP_BACKEND_URL**: This var is only required if you want to enable multisignature functionality. It is the backend rest api endpoint.
- **REACT_APP_BACKEND_URL**: This variable is only required if you want to enable multisignature functionality. It corresponds to the backend REST API endpoint.
> **Important:** If **REACT_APP_BACKEND_URL** is not set, the multisignature option will not be activated and therefore will not be displayed on the web interface.
- **REACT_APP_CONSENSUS_NODES**: This var is only required if you want to enable multisignature functionality. It is a list of consensus nodes per environment. When generating a multisignature transaction the first consensus node of the environment will be added to the transaction.

```bash
Expand Down
10 changes: 5 additions & 5 deletions web/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading