diff --git a/.github/workflows/ci-workflow.yml b/.github/workflows/ci-workflow.yml index f472f0f..43f6b51 100644 --- a/.github/workflows/ci-workflow.yml +++ b/.github/workflows/ci-workflow.yml @@ -23,6 +23,8 @@ jobs: name: "nanosp" - sdk: "$STAX_SDK" name: "stax" + - sdk: "$FLEX_SDK" + name: "flex" runs-on: ubuntu-latest container: @@ -38,27 +40,6 @@ jobs: run: | make BOLOS_SDK=${{ matrix.sdk }} -j - job_scan_build: - name: Clang Static Analyzer - runs-on: ubuntu-latest - container: - image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder-lite:latest - - steps: - - uses: actions/checkout@v3 - with: - submodules: recursive - - - name: Build with Clang Static Analyzer - run: | - scan-build --use-cc=clang -analyze-headers -enable-checker security -enable-checker unix -enable-checker valist -o scan-build --status-bugs make default - - - uses: actions/upload-artifact@v3 - if: failure() - with: - name: scan-build - path: scan-build - job_build_debug_plugin: name: Build debug plugin strategy: @@ -70,6 +51,10 @@ jobs: name: "nanox" - sdk: "$NANOSP_SDK" name: "nanosp" + - sdk: "$STAX_SDK" + name: "stax" + - sdk: "$FLEX_SDK" + name: "flex" runs-on: ubuntu-latest container: @@ -106,6 +91,10 @@ jobs: name: "nanox" - sdk: "$NANOSP_SDK" name: "nanosp" + - sdk: "$STAX_SDK" + name: "stax" + - sdk: "$FLEX_SDK" + name: "flex" runs-on: ubuntu-latest container: @@ -116,8 +105,8 @@ jobs: uses: actions/checkout@v3 with: repository: LedgerHQ/app-ethereum + submodules: recursive ref: ${{ ((github.base_ref || github.ref_name) == 'main' && 'master') || (github.base_ref || github.ref_name) }} - submodules: true - name: Build run: | diff --git a/src/contract.c b/src/contract.c index c031fa3..30b712b 100644 --- a/src/contract.c +++ b/src/contract.c @@ -103,6 +103,7 @@ static const uint8_t STAKEKIT_VIC_VOTE_SELECTOR[SELECTOR_SIZE] = {0x6d, 0xd7, 0x static const uint8_t STAKEKIT_VIC_RESIGN_SELECTOR[SELECTOR_SIZE] = {0xae, 0x6e, 0x43, 0xf5}; static const uint8_t STAKEKIT_VIC_UNVOTE_SELECTOR[SELECTOR_SIZE] = {0x02, 0xaa, 0x9b, 0xe2}; static const uint8_t STAKEKIT_VIC_WITHDRAW_SELECTOR[SELECTOR_SIZE] = {0x44, 0x1a, 0x3e, 0x70}; +static const uint8_t STAKEKIT_CLAIM_SELECTOR[SELECTOR_SIZE] = {0xaa, 0xd3, 0xec, 0x96}; // Array of all the different StakeKit selectors. const uint8_t *const STAKEKIT_SELECTORS[NUM_STAKEKIT_SELECTORS] = { @@ -161,7 +162,7 @@ const uint8_t *const STAKEKIT_SELECTORS[NUM_STAKEKIT_SELECTORS] = { STAKEKIT_VIC_RESIGN_SELECTOR, STAKEKIT_VIC_UNVOTE_SELECTOR, STAKEKIT_VIC_WITHDRAW_SELECTOR, -}; + STAKEKIT_CLAIM_SELECTOR}; // Null address const uint8_t NULL_ETH_ADDRESS[ADDRESS_LENGTH] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/src/handle_finalize.c b/src/handle_finalize.c index 01b53b0..0c0abc6 100644 --- a/src/handle_finalize.c +++ b/src/handle_finalize.c @@ -65,6 +65,7 @@ void handle_finalize(ethPluginFinalize_t *msg) { if (context->valid) { switch (context->selectorIndex) { case COMET_CLAIM: + case CLAIM: msg->numScreens = 2; msg->result = ETH_PLUGIN_RESULT_OK; break; diff --git a/src/handle_init_contract.c b/src/handle_init_contract.c index b2844ad..7a96a29 100644 --- a/src/handle_init_contract.c +++ b/src/handle_init_contract.c @@ -80,6 +80,7 @@ void handle_init_contract(ethPluginInitContract_t *msg) { case VOTE: case REVOKE_ACTIVE: case VIC_UNVOTE: + case CLAIM: context->next_param = RECIPIENT; break; case MORPHO_SUPPLY_1: diff --git a/src/handle_provide_parameter.c b/src/handle_provide_parameter.c index 9e83eed..a19679d 100644 --- a/src/handle_provide_parameter.c +++ b/src/handle_provide_parameter.c @@ -221,6 +221,28 @@ static void handle_comet_claim(ethPluginProvideParameter_t *msg, plugin_paramete } } +// Save 1 amount and 1 recipient in the context. +// The first param is the operator saved in recipient. +// The second param is the request number saved in amount_sent. +static void handle_claim(ethPluginProvideParameter_t *msg, plugin_parameters_t *context) { + switch (context->next_param) { + case RECIPIENT: // Put the operator address in recipient + copy_address(context->recipient, msg->parameter, ADDRESS_LENGTH); + context->next_param = AMOUNT_SENT; + break; + case AMOUNT_SENT: + copy_parameter(context->amount_sent, msg->parameter, INT256_LENGTH); + context->next_param = NONE; + break; + case NONE: + break; + default: + PRINTF("Param not supported\n"); + msg->result = ETH_PLUGIN_RESULT_ERROR; + break; + } +} + // Save 1 amount and 3 recipients in the context. // The first param is the second recipient saved in recipient. // The second param is the amount sent saved in amount_sent. @@ -536,6 +558,9 @@ void handle_provide_parameter(ethPluginProvideParameter_t *msg) { case LIDO_CLAIM_WITHDRAWALS: handle_lido_claim_withdrawal(msg, context); break; + case CLAIM: + handle_claim(msg, context); + break; case VIC_VOTE: case VIC_RESIGN: // Only save the recipient to the context. diff --git a/src/handle_query_contract_id.c b/src/handle_query_contract_id.c index d1c5d34..e7cba3c 100644 --- a/src/handle_query_contract_id.c +++ b/src/handle_query_contract_id.c @@ -81,6 +81,7 @@ void handle_query_contract_id(ethQueryContractID_t *msg) { strlcpy(msg->version, "Leave", msg->versionLength); break; case COMET_CLAIM: + case CLAIM: strlcpy(msg->version, "Claim", msg->versionLength); break; case TRANSFER_OUT: diff --git a/src/handle_query_contract_ui.c b/src/handle_query_contract_ui.c index e1bea23..e6551a9 100644 --- a/src/handle_query_contract_ui.c +++ b/src/handle_query_contract_ui.c @@ -62,6 +62,9 @@ static bool set_send_ui(ethQueryContractUI_t *msg, plugin_parameters_t *context) case VIC_UNVOTE: strlcpy(msg->title, "Cap", msg->titleLength); break; + case CLAIM: + strlcpy(msg->title, "Request Number", msg->titleLength); + break; default: PRINTF("Unhandled selector Index: %d\n", context->selectorIndex); return false; @@ -257,6 +260,9 @@ static bool set_recipient_ui(ethQueryContractUI_t *msg, plugin_parameters_t *con case VIC_UNVOTE: strlcpy(msg->title, "Candidate", msg->titleLength); break; + case CLAIM: + strlcpy(msg->title, "Operator", msg->titleLength); + break; default: PRINTF("Unhandled selector Index: %d\n", context->selectorIndex); return false; @@ -620,6 +626,7 @@ static screens_t get_screen(ethQueryContractUI_t *msg, case YEARN_VAULT_WITHDRAW_3: case LIDO_REQUEST_WITHDRAWALS: case VIC_UNVOTE: + case CLAIM: return get_screen_amount_sent_recipient(msg, context); case MORPHO_SUPPLY_1: case MORPHO_SUPPLY_2: diff --git a/src/stakekit_plugin.h b/src/stakekit_plugin.h index 0d6073f..245d17e 100644 --- a/src/stakekit_plugin.h +++ b/src/stakekit_plugin.h @@ -7,7 +7,7 @@ #define PLUGIN_NAME "StakeKit" -#define NUM_STAKEKIT_SELECTORS 55u +#define NUM_STAKEKIT_SELECTORS 56u #define TICKER_LEN 30u @@ -91,6 +91,7 @@ typedef enum { VIC_RESIGN, VIC_UNVOTE, VIC_WITHDRAW, + CLAIM, } selector_t; extern const uint8_t *const STAKEKIT_SELECTORS[NUM_STAKEKIT_SELECTORS]; diff --git a/tests/networks/bsc/stakekit/abis/0x0000000000000000000000000000000000002002.abi.json b/tests/networks/bsc/stakekit/abis/0x0000000000000000000000000000000000002002.abi.json new file mode 100644 index 0000000..9daf835 --- /dev/null +++ b/tests/networks/bsc/stakekit/abis/0x0000000000000000000000000000000000002002.abi.json @@ -0,0 +1,1812 @@ +[ + { + "inputs": [], + "name": "AlreadyPaused", + "type": "error" + }, + { + "inputs": [], + "name": "AlreadySlashed", + "type": "error" + }, + { + "inputs": [], + "name": "ConsensusAddressExpired", + "type": "error" + }, + { + "inputs": [], + "name": "DelegationAmountTooSmall", + "type": "error" + }, + { + "inputs": [], + "name": "DuplicateConsensusAddress", + "type": "error" + }, + { + "inputs": [], + "name": "DuplicateMoniker", + "type": "error" + }, + { + "inputs": [], + "name": "DuplicateVoteAddress", + "type": "error" + }, + { + "inputs": [], + "name": "InBlackList", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidCommission", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidConsensusAddress", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidMoniker", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidRequest", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidSynPackage", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "key", + "type": "string" + }, + { + "internalType": "bytes", + "name": "value", + "type": "bytes" + } + ], + "name": "InvalidValue", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidVoteAddress", + "type": "error" + }, + { + "inputs": [], + "name": "JailTimeNotExpired", + "type": "error" + }, + { + "inputs": [], + "name": "NoMoreFelonyAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "NotPaused", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyCoinbase", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyProtector", + "type": "error" + }, + { + "inputs": [], + "name": "OnlySelfDelegation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "systemContract", + "type": "address" + } + ], + "name": "OnlySystemContract", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyZeroGasPrice", + "type": "error" + }, + { + "inputs": [], + "name": "SameValidator", + "type": "error" + }, + { + "inputs": [], + "name": "SelfDelegationNotEnough", + "type": "error" + }, + { + "inputs": [], + "name": "TransferFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "key", + "type": "string" + }, + { + "internalType": "bytes", + "name": "value", + "type": "bytes" + } + ], + "name": "UnknownParam", + "type": "error" + }, + { + "inputs": [], + "name": "UpdateTooFrequently", + "type": "error" + }, + { + "inputs": [], + "name": "ValidatorExisted", + "type": "error" + }, + { + "inputs": [], + "name": "ValidatorNotExisted", + "type": "error" + }, + { + "inputs": [], + "name": "ValidatorNotJailed", + "type": "error" + }, + { + "inputs": [], + "name": "VoteAddressExpired", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroShares", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "BlackListed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operatorAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "delegator", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "bnbAmount", + "type": "uint256" + } + ], + "name": "Claimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operatorAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "newCommissionRate", + "type": "uint64" + } + ], + "name": "CommissionRateEdited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operatorAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newConsensusAddress", + "type": "address" + } + ], + "name": "ConsensusAddressEdited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operatorAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "delegator", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "bnbAmount", + "type": "uint256" + } + ], + "name": "Delegated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operatorAddress", + "type": "address" + } + ], + "name": "DescriptionEdited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operatorAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "delegator", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "bnbAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "enum StakeHub.StakeMigrationRespCode", + "name": "respCode", + "type": "uint8" + } + ], + "name": "MigrateFailed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operatorAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "delegator", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "bnbAmount", + "type": "uint256" + } + ], + "name": "MigrateSuccess", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "key", + "type": "string" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "value", + "type": "bytes" + } + ], + "name": "ParamChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldProtector", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newProtector", + "type": "address" + } + ], + "name": "ProtectorChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "srcValidator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "dstValidator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "delegator", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldShares", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newShares", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "bnbAmount", + "type": "uint256" + } + ], + "name": "Redelegated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "Resumed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operatorAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "failReason", + "type": "bytes" + } + ], + "name": "RewardDistributeFailed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operatorAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "RewardDistributed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operatorAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "creditContract", + "type": "address" + } + ], + "name": "StakeCreditInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "UnBlackListed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operatorAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "delegator", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "bnbAmount", + "type": "uint256" + } + ], + "name": "Undelegated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "channelId", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "msgBytes", + "type": "bytes" + } + ], + "name": "UnexpectedPackage", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "consensusAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operatorAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "creditContract", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "voteAddress", + "type": "bytes" + } + ], + "name": "ValidatorCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operatorAddress", + "type": "address" + } + ], + "name": "ValidatorEmptyJailed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operatorAddress", + "type": "address" + } + ], + "name": "ValidatorJailed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operatorAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "jailUntil", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "slashAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "enum StakeHub.SlashType", + "name": "slashType", + "type": "uint8" + } + ], + "name": "ValidatorSlashed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operatorAddress", + "type": "address" + } + ], + "name": "ValidatorUnjailed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operatorAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "newVoteAddress", + "type": "bytes" + } + ], + "name": "VoteAddressEdited", + "type": "event" + }, + { + "inputs": [], + "name": "BC_FUSION_CHANNELID", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "BREATHE_BLOCK_INTERVAL", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEAD_ADDRESS", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LOCK_AMOUNT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REDELEGATE_FEE_RATE_BASE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "STAKING_CHANNELID", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "addToBlackList", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "blackList", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operatorAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "requestNumber", + "type": "uint256" + } + ], + "name": "claim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "operatorAddresses", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "requestNumbers", + "type": "uint256[]" + } + ], + "name": "claimBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "consensusExpiration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "consensusToOperator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "consensusAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "voteAddress", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "blsProof", + "type": "bytes" + }, + { + "components": [ + { + "internalType": "uint64", + "name": "rate", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "maxRate", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "maxChangeRate", + "type": "uint64" + } + ], + "internalType": "struct StakeHub.Commission", + "name": "commission", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "string", + "name": "moniker", + "type": "string" + }, + { + "internalType": "string", + "name": "identity", + "type": "string" + }, + { + "internalType": "string", + "name": "website", + "type": "string" + }, + { + "internalType": "string", + "name": "details", + "type": "string" + } + ], + "internalType": "struct StakeHub.Description", + "name": "description", + "type": "tuple" + } + ], + "name": "createValidator", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operatorAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "delegateVotePower", + "type": "bool" + } + ], + "name": "delegate", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "consensusAddress", + "type": "address" + } + ], + "name": "distributeReward", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "consensusAddress", + "type": "address" + } + ], + "name": "doubleSignSlash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "downtimeJailTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "consensusAddress", + "type": "address" + } + ], + "name": "downtimeSlash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "downtimeSlashAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "commissionRate", + "type": "uint64" + } + ], + "name": "editCommissionRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newConsensusAddress", + "type": "address" + } + ], + "name": "editConsensusAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "string", + "name": "moniker", + "type": "string" + }, + { + "internalType": "string", + "name": "identity", + "type": "string" + }, + { + "internalType": "string", + "name": "website", + "type": "string" + }, + { + "internalType": "string", + "name": "details", + "type": "string" + } + ], + "internalType": "struct StakeHub.Description", + "name": "description", + "type": "tuple" + } + ], + "name": "editDescription", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "newVoteAddress", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "blsProof", + "type": "bytes" + } + ], + "name": "editVoteAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "felonyJailTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "felonySlashAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operatorAddress", + "type": "address" + } + ], + "name": "getValidatorBasicInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "createdTime", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "jailed", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "jailUntil", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operatorAddress", + "type": "address" + } + ], + "name": "getValidatorCommission", + "outputs": [ + { + "components": [ + { + "internalType": "uint64", + "name": "rate", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "maxRate", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "maxChangeRate", + "type": "uint64" + } + ], + "internalType": "struct StakeHub.Commission", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operatorAddress", + "type": "address" + } + ], + "name": "getValidatorConsensusAddress", + "outputs": [ + { + "internalType": "address", + "name": "consensusAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operatorAddress", + "type": "address" + } + ], + "name": "getValidatorCreditContract", + "outputs": [ + { + "internalType": "address", + "name": "creditContract", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operatorAddress", + "type": "address" + } + ], + "name": "getValidatorDescription", + "outputs": [ + { + "components": [ + { + "internalType": "string", + "name": "moniker", + "type": "string" + }, + { + "internalType": "string", + "name": "identity", + "type": "string" + }, + { + "internalType": "string", + "name": "website", + "type": "string" + }, + { + "internalType": "string", + "name": "details", + "type": "string" + } + ], + "internalType": "struct StakeHub.Description", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "offset", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "getValidatorElectionInfo", + "outputs": [ + { + "internalType": "address[]", + "name": "consensusAddrs", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "votingPowers", + "type": "uint256[]" + }, + { + "internalType": "bytes[]", + "name": "voteAddrs", + "type": "bytes[]" + }, + { + "internalType": "uint256", + "name": "totalLength", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operatorAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getValidatorRewardRecord", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operatorAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getValidatorTotalPooledBNBRecord", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operatorAddress", + "type": "address" + } + ], + "name": "getValidatorVoteAddress", + "outputs": [ + { + "internalType": "bytes", + "name": "voteAddress", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "offset", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "getValidators", + "outputs": [ + { + "internalType": "address[]", + "name": "operatorAddrs", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "creditAddrs", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "totalLength", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "channelId", + "type": "uint8" + }, + { + "internalType": "bytes", + "name": "msgBytes", + "type": "bytes" + } + ], + "name": "handleAckPackage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "channelId", + "type": "uint8" + }, + { + "internalType": "bytes", + "name": "msgBytes", + "type": "bytes" + } + ], + "name": "handleFailAckPackage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + }, + { + "internalType": "bytes", + "name": "msgBytes", + "type": "bytes" + } + ], + "name": "handleSynPackage", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "voteAddress", + "type": "bytes" + } + ], + "name": "maliciousVoteSlash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxElectedValidators", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxFelonyBetweenBreatheBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minDelegationBNBChange", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minSelfDelegationBNB", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "numOfJailed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "srcValidator", + "type": "address" + }, + { + "internalType": "address", + "name": "dstValidator", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "delegateVotePower", + "type": "bool" + } + ], + "name": "redelegate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "redelegateFeeRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "removeFromBlackList", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "resume", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "operatorAddresses", + "type": "address[]" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "syncGovToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "transferGasLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unbondPeriod", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operatorAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "undelegate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operatorAddress", + "type": "address" + } + ], + "name": "unjail", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "key", + "type": "string" + }, + { + "internalType": "bytes", + "name": "value", + "type": "bytes" + } + ], + "name": "updateParam", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "voteExpiration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "voteToOperator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] \ No newline at end of file diff --git a/tests/networks/bsc/stakekit/b2c.json b/tests/networks/bsc/stakekit/b2c.json index c9a950e..321b455 100644 --- a/tests/networks/bsc/stakekit/b2c.json +++ b/tests/networks/bsc/stakekit/b2c.json @@ -11,6 +11,32 @@ "plugin": "StakeKit" } } + }, + { + "address": "0x0000000000000000000000000000000000002002", + "contractName": "StakeHub", + "selectors": { + "0xaad3ec96": { + "erc20OfInterest": [], + "method": "claim", + "plugin": "StakeKit" + }, + "0x982ef0a7": { + "erc20OfInterest": [], + "method": "delegate", + "plugin": "StakeKit" + }, + "0x4d99dd16": { + "erc20OfInterest": [], + "method": "undelegate", + "plugin": "StakeKit" + }, + "0x59491871": { + "erc20OfInterest": [], + "method": "redelegate", + "plugin": "StakeKit" + } + } } ], "name": "StakeKit" diff --git a/tests/snapshots/bsc_flex_bsc_claim/00000.png b/tests/snapshots/bsc_flex_bsc_claim/00000.png new file mode 100644 index 0000000..a66657e Binary files /dev/null and b/tests/snapshots/bsc_flex_bsc_claim/00000.png differ diff --git a/tests/snapshots/bsc_flex_bsc_claim/00001.png b/tests/snapshots/bsc_flex_bsc_claim/00001.png new file mode 100644 index 0000000..d7ebfa7 Binary files /dev/null and b/tests/snapshots/bsc_flex_bsc_claim/00001.png differ diff --git a/tests/snapshots/bsc_flex_bsc_claim/00002.png b/tests/snapshots/bsc_flex_bsc_claim/00002.png new file mode 100644 index 0000000..e44a9b7 Binary files /dev/null and b/tests/snapshots/bsc_flex_bsc_claim/00002.png differ diff --git a/tests/snapshots/bsc_flex_bsc_claim/00003.png b/tests/snapshots/bsc_flex_bsc_claim/00003.png new file mode 100644 index 0000000..0d7b10c Binary files /dev/null and b/tests/snapshots/bsc_flex_bsc_claim/00003.png differ diff --git a/tests/snapshots/bsc_flex_bsc_claim/00004.png b/tests/snapshots/bsc_flex_bsc_claim/00004.png new file mode 100644 index 0000000..dabe7af Binary files /dev/null and b/tests/snapshots/bsc_flex_bsc_claim/00004.png differ diff --git a/tests/snapshots/bsc_nanos_bsc_claim/00000.png b/tests/snapshots/bsc_nanos_bsc_claim/00000.png new file mode 100644 index 0000000..8d84cc7 Binary files /dev/null and b/tests/snapshots/bsc_nanos_bsc_claim/00000.png differ diff --git a/tests/snapshots/bsc_nanos_bsc_claim/00001.png b/tests/snapshots/bsc_nanos_bsc_claim/00001.png new file mode 100644 index 0000000..427d8cb Binary files /dev/null and b/tests/snapshots/bsc_nanos_bsc_claim/00001.png differ diff --git a/tests/snapshots/bsc_nanos_bsc_claim/00002.png b/tests/snapshots/bsc_nanos_bsc_claim/00002.png new file mode 100644 index 0000000..e468995 Binary files /dev/null and b/tests/snapshots/bsc_nanos_bsc_claim/00002.png differ diff --git a/tests/snapshots/bsc_nanos_bsc_claim/00003.png b/tests/snapshots/bsc_nanos_bsc_claim/00003.png new file mode 100644 index 0000000..7d3b90f Binary files /dev/null and b/tests/snapshots/bsc_nanos_bsc_claim/00003.png differ diff --git a/tests/snapshots/bsc_nanos_bsc_claim/00004.png b/tests/snapshots/bsc_nanos_bsc_claim/00004.png new file mode 100644 index 0000000..616fd0a Binary files /dev/null and b/tests/snapshots/bsc_nanos_bsc_claim/00004.png differ diff --git a/tests/snapshots/bsc_nanos_bsc_claim/00005.png b/tests/snapshots/bsc_nanos_bsc_claim/00005.png new file mode 100644 index 0000000..a73fcdf Binary files /dev/null and b/tests/snapshots/bsc_nanos_bsc_claim/00005.png differ diff --git a/tests/snapshots/bsc_nanos_bsc_claim/00006.png b/tests/snapshots/bsc_nanos_bsc_claim/00006.png new file mode 100644 index 0000000..371c126 Binary files /dev/null and b/tests/snapshots/bsc_nanos_bsc_claim/00006.png differ diff --git a/tests/snapshots/bsc_nanos_bsc_claim/00007.png b/tests/snapshots/bsc_nanos_bsc_claim/00007.png new file mode 100644 index 0000000..bbe5c0a Binary files /dev/null and b/tests/snapshots/bsc_nanos_bsc_claim/00007.png differ diff --git a/tests/snapshots/bsc_nanos_bsc_claim/00008.png b/tests/snapshots/bsc_nanos_bsc_claim/00008.png new file mode 100644 index 0000000..1c9156c Binary files /dev/null and b/tests/snapshots/bsc_nanos_bsc_claim/00008.png differ diff --git a/tests/snapshots/bsc_nanos_bsc_claim/00009.png b/tests/snapshots/bsc_nanos_bsc_claim/00009.png new file mode 100644 index 0000000..ce795f3 Binary files /dev/null and b/tests/snapshots/bsc_nanos_bsc_claim/00009.png differ diff --git a/tests/snapshots/bsc_nanosp_bsc_claim/00000.png b/tests/snapshots/bsc_nanosp_bsc_claim/00000.png new file mode 100644 index 0000000..487ea10 Binary files /dev/null and b/tests/snapshots/bsc_nanosp_bsc_claim/00000.png differ diff --git a/tests/snapshots/bsc_nanosp_bsc_claim/00001.png b/tests/snapshots/bsc_nanosp_bsc_claim/00001.png new file mode 100644 index 0000000..a68793a Binary files /dev/null and b/tests/snapshots/bsc_nanosp_bsc_claim/00001.png differ diff --git a/tests/snapshots/bsc_nanosp_bsc_claim/00002.png b/tests/snapshots/bsc_nanosp_bsc_claim/00002.png new file mode 100644 index 0000000..7d61511 Binary files /dev/null and b/tests/snapshots/bsc_nanosp_bsc_claim/00002.png differ diff --git a/tests/snapshots/bsc_nanosp_bsc_claim/00003.png b/tests/snapshots/bsc_nanosp_bsc_claim/00003.png new file mode 100644 index 0000000..b482260 Binary files /dev/null and b/tests/snapshots/bsc_nanosp_bsc_claim/00003.png differ diff --git a/tests/snapshots/bsc_nanosp_bsc_claim/00004.png b/tests/snapshots/bsc_nanosp_bsc_claim/00004.png new file mode 100644 index 0000000..0d6794d Binary files /dev/null and b/tests/snapshots/bsc_nanosp_bsc_claim/00004.png differ diff --git a/tests/snapshots/bsc_nanosp_bsc_claim/00005.png b/tests/snapshots/bsc_nanosp_bsc_claim/00005.png new file mode 100644 index 0000000..3af6333 Binary files /dev/null and b/tests/snapshots/bsc_nanosp_bsc_claim/00005.png differ diff --git a/tests/snapshots/bsc_nanosp_bsc_claim/00006.png b/tests/snapshots/bsc_nanosp_bsc_claim/00006.png new file mode 100644 index 0000000..570ce28 Binary files /dev/null and b/tests/snapshots/bsc_nanosp_bsc_claim/00006.png differ diff --git a/tests/snapshots/bsc_nanosp_bsc_claim/00007.png b/tests/snapshots/bsc_nanosp_bsc_claim/00007.png new file mode 100644 index 0000000..a58590b Binary files /dev/null and b/tests/snapshots/bsc_nanosp_bsc_claim/00007.png differ diff --git a/tests/snapshots/bsc_nanox_bsc_claim/00000.png b/tests/snapshots/bsc_nanox_bsc_claim/00000.png new file mode 100644 index 0000000..487ea10 Binary files /dev/null and b/tests/snapshots/bsc_nanox_bsc_claim/00000.png differ diff --git a/tests/snapshots/bsc_nanox_bsc_claim/00001.png b/tests/snapshots/bsc_nanox_bsc_claim/00001.png new file mode 100644 index 0000000..a68793a Binary files /dev/null and b/tests/snapshots/bsc_nanox_bsc_claim/00001.png differ diff --git a/tests/snapshots/bsc_nanox_bsc_claim/00002.png b/tests/snapshots/bsc_nanox_bsc_claim/00002.png new file mode 100644 index 0000000..7d61511 Binary files /dev/null and b/tests/snapshots/bsc_nanox_bsc_claim/00002.png differ diff --git a/tests/snapshots/bsc_nanox_bsc_claim/00003.png b/tests/snapshots/bsc_nanox_bsc_claim/00003.png new file mode 100644 index 0000000..b482260 Binary files /dev/null and b/tests/snapshots/bsc_nanox_bsc_claim/00003.png differ diff --git a/tests/snapshots/bsc_nanox_bsc_claim/00004.png b/tests/snapshots/bsc_nanox_bsc_claim/00004.png new file mode 100644 index 0000000..0d6794d Binary files /dev/null and b/tests/snapshots/bsc_nanox_bsc_claim/00004.png differ diff --git a/tests/snapshots/bsc_nanox_bsc_claim/00005.png b/tests/snapshots/bsc_nanox_bsc_claim/00005.png new file mode 100644 index 0000000..3af6333 Binary files /dev/null and b/tests/snapshots/bsc_nanox_bsc_claim/00005.png differ diff --git a/tests/snapshots/bsc_nanox_bsc_claim/00006.png b/tests/snapshots/bsc_nanox_bsc_claim/00006.png new file mode 100644 index 0000000..570ce28 Binary files /dev/null and b/tests/snapshots/bsc_nanox_bsc_claim/00006.png differ diff --git a/tests/snapshots/bsc_nanox_bsc_claim/00007.png b/tests/snapshots/bsc_nanox_bsc_claim/00007.png new file mode 100644 index 0000000..a58590b Binary files /dev/null and b/tests/snapshots/bsc_nanox_bsc_claim/00007.png differ diff --git a/tests/snapshots/bsc_stax_bsc_claim/00000.png b/tests/snapshots/bsc_stax_bsc_claim/00000.png new file mode 100644 index 0000000..c8b2258 Binary files /dev/null and b/tests/snapshots/bsc_stax_bsc_claim/00000.png differ diff --git a/tests/snapshots/bsc_stax_bsc_claim/00001.png b/tests/snapshots/bsc_stax_bsc_claim/00001.png new file mode 100644 index 0000000..d70cb5c Binary files /dev/null and b/tests/snapshots/bsc_stax_bsc_claim/00001.png differ diff --git a/tests/snapshots/bsc_stax_bsc_claim/00002.png b/tests/snapshots/bsc_stax_bsc_claim/00002.png new file mode 100644 index 0000000..7064657 Binary files /dev/null and b/tests/snapshots/bsc_stax_bsc_claim/00002.png differ diff --git a/tests/snapshots/bsc_stax_bsc_claim/00003.png b/tests/snapshots/bsc_stax_bsc_claim/00003.png new file mode 100644 index 0000000..339db1b Binary files /dev/null and b/tests/snapshots/bsc_stax_bsc_claim/00003.png differ diff --git a/tests/src/bsc/bsc_claim.test.js b/tests/src/bsc/bsc_claim.test.js new file mode 100644 index 0000000..7c0bfe7 --- /dev/null +++ b/tests/src/bsc/bsc_claim.test.js @@ -0,0 +1,47 @@ +import { processTest, populateTransaction } from "../test.fixture"; + +const contractName = "StakeHub"; // <= Name of the smart contract + +const testLabel = "bsc_claim"; // <= Name of the test +const testDirSuffix = "bsc_claim"; // <= directory to compare device snapshots to +const testNetwork = "bsc"; +const signedPlugin = false; + +const contractAddr = "0x0000000000000000000000000000000000002002"; // <= Address of the smart contract +const chainID = 56; + +// From : https://bscscan.com/tx/0x7be3829b21952e8ffd580bda2edb5ad48179e9e568cb71c3da06a52ae4c7f022 +const inputData = "0xaad3ec960000000000000000000000000e3cf208f4141c41da86d52c5f2076b1ab310e8f0000000000000000000000000000000000000000000000000000000000000000"; + +// Create serializedTx and remove the "0x" prefix +const serializedTx = populateTransaction(contractAddr, inputData, chainID); + +const devices = [ + { + name: "nanos", + label: "Nano S", + steps: 8, // <= Define the number of steps for this test case and this device + }, + { + name: "nanox", + label: "Nano X", + steps: 6, // <= Define the number of steps for this test case and this device + }, + { + name: "nanosp", + label: "Nano S+", + steps: 6, // <= Define the number of steps for this test case and this device + }, + { + name: "stax", + label: "Stax", + }, + { + name: "flex", + label: "Flex", + } +]; + +devices.forEach((device) => + processTest(device, contractName, testLabel, testDirSuffix, "", signedPlugin, serializedTx, testNetwork) +); diff --git a/tests/src/test.fixture.js b/tests/src/test.fixture.js index d410b38..54173be 100644 --- a/tests/src/test.fixture.js +++ b/tests/src/test.fixture.js @@ -1,4 +1,4 @@ -import Zemu from '@zondax/zemu'; +import Zemu, { DEFAULT_START_OPTIONS } from '@zondax/zemu'; import Eth from '@ledgerhq/hw-app-eth'; import { generate_plugin_config } from './generate_plugin_config'; import { parseEther, parseUnits, RLP } from 'ethers/lib/utils'; @@ -12,14 +12,12 @@ export async function waitForAppScreen(sim) { await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot(), transactionUploadDelay); } -const simOptions = { +let simOptions = { + ...DEFAULT_START_OPTIONS, logging: true, + X11: false, startDelay: 15000, - startText: "Ready", - approveKeyword: "APPROVE", - rejectKeyword: "REJECT", - custom: "", - caseSensitive: false, + startText: 'is ready' }; const Resolve = require('path').resolve; @@ -27,27 +25,35 @@ const Resolve = require('path').resolve; const APP_PATH_NANOS = Resolve('elfs/ethereum_nanos.elf'); const APP_PATH_NANOX = Resolve('elfs/ethereum_nanox.elf'); const APP_PATH_NANOSP = Resolve('elfs/ethereum_nanosp.elf'); +const APP_PATH_STAX = Resolve('elfs/ethereum_stax.elf'); +const APP_PATH_FLEX = Resolve('elfs/ethereum_flex.elf'); const PLUGIN_LIB_NANOS = { 'StakeKit': Resolve('elfs/plugin_nanos.elf') }; const PLUGIN_LIB_NANOX = { 'StakeKit': Resolve('elfs/plugin_nanox.elf') }; const PLUGIN_LIB_NANOSP = { 'StakeKit': Resolve('elfs/plugin_nanosp.elf') }; +const PLUGIN_LIB_STAX = { 'StakeKit': Resolve('elfs/plugin_stax.elf') }; +const PLUGIN_LIB_FLEX = { 'StakeKit': Resolve('elfs/plugin_flex.elf') }; const RANDOM_ADDRESS = "0xaaaabbbbccccddddeeeeffffgggghhhhiiiijjjj"; -let genericTx = { +const genericTx = { nonce: Number(0), gasLimit: Number(21000), gasPrice: parseUnits("1", "gwei"), value: parseEther("1"), chainId: 1, to: RANDOM_ADDRESS, - data: null, + data: undefined, }; let config; -const TIMEOUT = 2000000; -jest.setTimeout(TIMEOUT); +beforeAll(async () => { + await Zemu.checkAndPullImage(); +}); + +jest.setTimeout(1000 * 60 * 60); + /** * Generates a serializedTransaction from a rawHexTransaction copy pasted from etherscan. * @param {string} rawTx Raw transaction @@ -85,33 +91,40 @@ function txFromEtherscan(rawTx) { * Emulation of the device using zemu * @param {string} device name of the device to emulate (nanos, nanox) * @param {function} func - * @param {boolean} signed the plugin is already signed + * @param {boolean} signed the plugin is already signed * @returns {Promise} */ function zemu(device, func, testNetwork, signed = false) { return async () => { - let eth_path; - let plugin; let sim_options = simOptions; + let current_model; + + const models = [ + { dev: { name: 'nanos', prefix: 'S', path: APP_PATH_NANOS }, plugin: PLUGIN_LIB_NANOS }, + { dev: { name: 'nanox', prefix: 'X', path: APP_PATH_NANOX }, plugin: PLUGIN_LIB_NANOX }, + { dev: { name: 'nanosp', prefix: 'SP', path: APP_PATH_NANOSP }, plugin: PLUGIN_LIB_NANOSP }, + { dev: { name: 'stax', prefix: 'ST', path: APP_PATH_STAX }, plugin: PLUGIN_LIB_STAX }, + { dev: { name: 'flex', prefix: 'FL', path: APP_PATH_FLEX }, plugin: PLUGIN_LIB_FLEX } + ] if (device === "nanos") { - eth_path = APP_PATH_NANOS; - plugin = PLUGIN_LIB_NANOS; - sim_options.model = "nanos"; + current_model = models[0] } else if (device === "nanox") { - eth_path = APP_PATH_NANOX; - plugin = PLUGIN_LIB_NANOX; - sim_options.model = "nanox"; + current_model = models[1] + } else if (device === "nanosp") { + current_model = models[2] + } else if (device === "stax") { + current_model = models[3] + simOptions.startText = "Ethereum" } else { - eth_path = APP_PATH_NANOSP; - plugin = PLUGIN_LIB_NANOSP; - sim_options.model = "nanosp"; + current_model = models[4] + simOptions.startText = "Ethereum" } - const sim = new Zemu(eth_path, plugin); + const sim = new Zemu(current_model.dev.path, current_model.plugin); try { - await sim.start(sim_options); + await sim.start({ ...sim_options, model: current_model.dev.name }); const transport = await sim.getTransport(); const eth = new Eth(transport); @@ -156,7 +169,7 @@ async function processTransaction(eth, sim, steps, label, rawTxHex, srlTx = "") .catch((e) => { console.warn( "an error occurred in resolveTransaction => fallback to blind signing: " + - e.stack + String(e) ); return null; }); @@ -168,7 +181,11 @@ async function processTransaction(eth, sim, steps, label, rawTxHex, srlTx = "") transactionUploadDelay ); - await sim.navigateAndCompareSnapshots(".", label, [steps, 0]); + if (sim.startOptions.model === "stax" || sim.startOptions.model === "flex") { + await sim.compareSnapshotsAndApprove(".", label) + } else { + await sim.navigateAndCompareSnapshots(".", label, [steps, 0]); + } await tx; } @@ -181,7 +198,7 @@ async function processTransaction(eth, sim, steps, label, rawTxHex, srlTx = "") * @param {string} rawTxHex RawTx Hex to test * @param {boolean} signed The plugin is already signed and existing in Ledger database */ -function processTest(device, contractName, testLabel, testDirSuffix, rawTxHex, signed, serializedTx, testNetwork) { +async function processTest(device, contractName, testLabel, testDirSuffix, rawTxHex, signed, serializedTx, testNetwork) { test( "[" + contractName + "] - " + device.label + " - " + testLabel, zemu(device.name, async (sim, eth) => { @@ -213,9 +230,4 @@ function populateTransaction(contractAddr, inputData, chainId, value = "0.0") { return ethers.utils.serializeTransaction(unsignedTx).slice(2); } - -module.exports = { - processTest, - genericTx, - populateTransaction -}; \ No newline at end of file +export { processTest, genericTx, populateTransaction }; \ No newline at end of file