eoslime.js
EOS development and deployment framework based on eosjs.js. The framework's main purpose is to make the process of unit testing, deployment and compilation much simpler and much easier.
You can join us on telegram - https://t.me/eoslime
Installing
npm install eoslime
Simple usage
/* Supported Networks: [ local ] [ jungle ] [ bos ] [ worbli ] [ main ] [kylin] or { url: 'custom url', chainId: 'custom id' }*/const eoslime = ; const TOKEN_WASM_PATH = './contract/eosio.token.wasm';const TOKEN_ABI_PATH = './contract/eosio.token.abi'; // Generate and setup freshly new accounts for usagelet accounts = await eoslimeAccount;let tokensIssuer = accounts0;let tokensHolder = accounts1; // Deploy contract (localhost)let tokenContract = await eoslimeCleanDeployer; // Call contract functions// By default provider's default account(localhost - eosio) executes methods calls on the blockchainawait tokenContract; // Change the execution account await tokenContract;
Simple tests
const assert = ;const eoslime = ; const TOKEN_WASM_PATH = './example/eosio-token/contract/eosio.token.wasm';const TOKEN_ABI_PATH = './example/eosio-token/contract/eosio.token.abi'; ;
Eoslime initialization
Parameters:
- network name - [ local ] [ jungle ] [ bos ] [ worbli ] [ main ] [ kylin ] or { url: 'custom url', chainId: 'custom id' }
Initialization with default parameters:
const eoslime = ;
Defaults:
- network name - local
On local network, eoslime.provider.defaultAccount is set automatically to eosio
const eoslime = ; eoslimeproviderdefaultAccount Account name: 'eosio' executiveAuthority: actor: 'eosio' permission: 'active' publicKey: 'EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV' privateKey: '5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3' provider: network: "name": "local" "url": "http://127.0.0.1:8888" "chainId": "cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f" ...
Important ! Only local network comes with preset provider's default account
. If you connect to another network you should set provider's default account manually
Initialization on supported network
const eoslime = ;
Initialization on unsupported network
const eoslime = ;
Account
Account is a class that provides an easy access to blockchain account endpoint.
1. Instantiate
const eoslime = ; // Load existing network account let account = eoslimeAccount;
Parameters:
- name - account name
- privateKey - private key of the account.
If you provide 'custom' permission, the privateKey should be the relevant for that permission - permission ( Optional ) - the account's permission. Default ->
active
Permission per account. If you want to operate with another account's permission you should load the same account with the second permission.
2. Instantiated account
2.1 Properties
- name
- publicKey
- privateKey
- provider - The network provider that the account is connected to
- executiveAuthority - transactions authority
actor: '' permission: '' }
2.2 Functions
- buyRam (bytes, payer) - buy ram for this account
const eoslime = ; // Existing accounts on local network let payer = eoslimeAccount; let account2 = eoslimeAccount; // Payer will buy ram for account2 await account2;
Defaults:
payer
- current account
const eoslime = ; // Existing account on local network let account = eoslimeAccount; // The account will buy ram by self for 10000 bytes await account;
- buyBandwidth (cpu, net, payer) - buy cpu and network for this account
const eoslime = ; // Existing accounts on local network let payer = eoslimeAccount; let account2 = eoslimeAccount; // Payer will buy cpu and network for account2 for 100 EOS await account2;
Defaults:
payer
- current account
const eoslime = ; // Existing account on local network let account = eoslimeAccount; // The account will buy cpu and net by self for 10 EOS await account;
- send (receiver, amount, symbol) - send EOS tokens to another account
const eoslime = ; // Existing accounts on local network let sender = eoslimeAccount; let receiver = eoslimeAccount; // The sender will send 100 EOS tokens to receiver await sender;
Defaults:
symbol
- EOS
const eoslime = ; // Existing accounts on local network let sender = eoslimeAccount; let receiver = eoslimeAccount; // The sender will send 100 EOS tokens to receiver await sender;
- createAuthority (authorityName) - Creates a new authority. Behind the scene it will generate a new private/public keys pair for the authority
const eoslime = ; // Existing account on local network let activeAccount = eoslimeAccount; // It will create 'contracts' authority. Parent authority will be the 'active' one let contractsAccount = await activeAccount; /* customAccount.executiveAuthority : { actor: 'myAcc1', permission: 'contracts' } contractsAccount.pubKey != activeAccount.pubKey */
- addPermission (permName, actor) - Adds a new permission in the account's authority
const eoslime = ; // Existing accounts on local network let account = eoslimeAccount; let tokenFactoryAccount = eoslimeAccount; /* It will allow a contract account with eosio.code permission to act on behalf when you are authorizing an action with active authority Use case: We have two contracts: TokenFactory and Token TokenFactory.create behind the scene calls Token.issue_tokens. You want issue_tokens action to be called from you, not from the TokenFactory name */ await account;
Defaults:
actor
- current account name
const eoslime = ; // Existing account on local network let account = eoslimeAccount; // It will add eosio.code permission in the active authority await account;
- getBalance (symbol, code) - get the account balance for token with symbol
const eoslime = ; // Existing account on local network let account = eoslimeAccount; // custom.token is a contract account with a token deployed on it await account;
Defaults:
symbol
- EOScode
- eosio.token
const eoslime = ; // Existing account on local network let account = eoslimeAccount; await account;
3. Static account properties
Important! Keep in mind the following points which are applicable for each create-account function:
- It buys ram for 8192 bytes
- It executes blockchain create-account transaction
- It sets the executive authority to
active
-
createFromName (name, accountCreator) - Creates a fresh new account for a given name
Important! Keep in mind that this name may already exists on the network
const eoslime = ;// Existing account on local networklet accountCreator = eoslimeAccount;// accountCreator will create account2 on the network, a.k.a accountCreator.provider.networklet account2 = await eoslimeAccount;Defaults:
accountCreator
- provider's default account
const eoslime = ;// Provider’s default account will create this account on local networklet account = await eoslimeAccount; -
createRandom (accountCreator) - Creates new random account
const eoslime = ;// Existing account on local networklet accountCreator = eoslimeAccount;// accountCreator will create account2 on the network, a.k.a accountCreator.provider.networklet account2 = await eoslimeAccount;Defaults:
accountCreator
- provider's default account
const eoslime = ;// Provider's default account account will create this account on local networklet account = await eoslimeAccount; -
createRandoms (accountsCount, accountCreator) - Creates new random accounts
const eoslime = ;// Existing account on local networklet accountsCreator = eoslimeAccount;// accountsCreator will create random accounts on the network, a.k.a accountsCreator.provider.networkconst accountsCount = 2;let accounts = await eoslimeAccount;Defaults:
accountCreator
- provider's default account
const eoslime = init;// Provider's default account will create this accounts on local networkconst accountsCount = 2;let accounts = await eoslimeAccount; -
createEncrypted (password, accountCreator) - Creates fresh new account and returns the encrypted json format of it
How it works: Creates a fresh new random account. Created account's data is hashed and a cipherText is derived by encrypting privateKey::dataHash// Account data for hashingname: accountnamenetwork: accountprovidernetworkprivateKey: accountprivateKeyconst eoslime = ;// Existing account on local networklet accountCreator = 'myAcc' 'myPrivateKey';// accountCreator will create encrypted JSON account on the network, a.k.a accountCreator.provider.networkconst password = 'secret password';let encryptedJSONAccount = await eoslimeAccount;/*Encrypted JSON account => {"name": "random generated","network": {"name": 'name',"url": 'url',"chainId": 'chainId'},"ciphertext": "encrypted private key + dataHash"}*/Defaults:
accountCreator
- provider's default account
const eoslime = init;// Provider's default account will create this account on local networkconst password = 'secret password';let encryptedJSONAccount = await eoslimeAccount; -
fromEncrypted (encryptedAccount, password) - Decrypt an encrypted account
How it works: Decrypts cipherText and gets it's parts (privateKey and dataHash). The PrivateKey is merged with the other encryptedAccount properties into an object which after the merging is hashed. This hash is validated against the dataHash for correctness.const eoslime = ;// Existing account on local networklet accountCreator = 'myAcc' 'myPrivateKey';// accountCreator will create encrypted JSON account on the network, a.k.a accountCreator.provider.networkconst password = 'secret password';let encryptedJSONAccount = await eoslimeAccount;let decryptedAccount = eoslimeAccount;
4. Default account
Default account or main account is the account which executes blockchain transactions if none is provided. Most of the functions have executor in the form of payer | accountCreator | contractExecutor. For example: When you are on local network eosio account is preset automatically for you as default/main account. You are able to do
await Account
without the need of specifying the accountCreator every time.
If you are on another network, you can set the default/main account as follow:
const eoslime = ; const jungleMainAccount = eoslimeAccount;eoslimeProviderdefaultAccount = jungleMainAccount;
In this way jungleMainAccount will execute every blockchain transaction whenever the execution account is needed but none was provided.
Providers
Providers are the blockchain connectors. A provider is instantiated internally based on the network name provided on initialization: [ local ] [ jungle ] [ bos ] [ worbli ] [ main ] or { url: 'custom url', chainId: 'custom id' }
Depending on what network you want to connect to, the following providers are available: [ LocalProvider ] [ JungleProvider ] [ BosProvider ] [ WorbliProvider ] [ KylinProvider ] [ MainProvider ] [ CustomProvider ] :
const eoslime = -> JungleProvider
1. Properties:
- network
name: ''url: ''chainId: ''
- defaultAccount - The default/main account from which the blockchain transactions are executed
- eos - eosjs instance that serves as a bridge with the blockchain
Deployers
Account Deployer
Account Deployer is used when you already have an account on which you want to deploy a new contract or when you have an account with already deployed contract and you want to upgrade it.
const eoslime = ; const WASM_PATH = './contract/contract.wasm';const ABI_PATH = './contract/contract.abi'; let contractAccount = eoslimeAccount; let contract = await eoslimeAccountDeployer;
- Options:
- inline - If true, contract account's active authority obtains 'eosio.code' permission. In this way the contract has the ability to do inline actions (call another contract)
const eoslime = ; const WASM_PATH = './contract/contract.wasm';const ABI_PATH = './contract/contract.abi'; let contractAccount = eoslimeAccount; // contract account's active authority obtains `eosio.code` permissionlet contract = await eoslimeAccountDeployer;
The deploy
function returns a ready to use instance of the deployed contract.
Clean Deployer
Clean Deployer is used when you don't have a contract account. It creates a new contract account on which the contract is is being deployed. The creator of the new contract account is the provider's default account. The Clean Deployer is always deploying contracts on new accounts.
This is helpful when we want to do the following:
We have two tests and one contract account. The first test writes to the contract storage, but you need this storage to be clear for the second test due to some assertions or something like that depending on the use-case.
// Local network initializationconst eoslime = ; const WASM_PATH = './contract/contract.wasm';const ABI_PATH = './contract/contract.abi'; let contract = await eoslimeCleanDeployer;
- Options:
- inline - If true, contract account's active authority obtains 'eosio.code' permission. In this way the contract has the ability to do inline actions (call another contract)
const eoslime = ; const WASM_PATH = './contract/contract.wasm';const ABI_PATH = './contract/contract.abi'; // contract account's active authority obtains `eosio.code` permissionlet contract = await eoslimeCleanDeployer;
The deploy
function returns a ready to use instance of the deployed contract.
Contract
You can get a contract's instance in two ways
- Each Deployer returns to you a new contract after deployment
- You can instatiate an already existing contract by doing:
// Local network initializationconst eoslime = ; const CONTRACT_NAME = 'mycontract';// Pre-created local network accountconst CONTRACT_EXECUTOR = 'myaccount' 'privateKey';const ABI_PATH = './contract/contract.abi'; let contract = eoslime;
Note! If you don't provide CONTRACT_EXECUTOR
the provider's default account will be applied as executor
Important! eoslime is based on eosjs and when we are calling a contract method, eosjs options { broadcast: true, sign: true }
are always set to true
Properties
- name - For convenience you have accsess to the contract name
- provider - For convenience you have accsess to the network provider
- executor - The account which will execute contract methods (transactions) on the blockchain
Functions
-
##### contract methods Each contract method has the following optionals
from - If you want to call a contract method from another account(executor) you can do
// Local network initializationconst eoslime = ;const CONTRACT_NAME = 'mycontract';const ABI_PATH = './contract/contract.abi';// Pre-created local network accountsconst EXECUTOR_1 = eoslimeAccount;const EXECUTOR_2 = eoslimeAccount;let contract = eoslime;// EXECUTOR_1 will execute `doSmth` transaction on the blockchainawait contract;// EXECUTOR_2 will execute `doSmth` transaction on the blockchainawait contract;// EXECUTOR_1 will execute `doSmth` transaction on the blockchainawait contract;unique - Nonce action support. Solve the
duplicate transaction
error// Local network initializationconst eoslime = ;const CONTRACT_NAME = 'mycontract';const ABI_PATH = './contract/contract.abi';// Pre-created local network accountsconst EXECUTOR_1 = eoslimeAccount;let contract = eoslime;await contract;// Execute `doSmth` one more time with same parametersawait contract; -
##### makeInline() - It adds 'eosio.code' permission to the contracts account's authority. It allows contract to do inline actions/call another contract's methods
let contract = eoslime;// CONTRACT_ACCOUNT will obtains 'eosio.code' permissionawait contract;
Table getters
In order to search in a contract tables in an easier way there are default table getters Each table getter is constructed such as
get + table name but with uppered first letter
Example:
table = admins
default getter = getAdmins
When you are using table getters, you should provide some query parameters Default: { equal: null, lower: null, upper: null, index: 1, index_type: "i64", limit: 100 }
- equal - Search for records which are equal to
- lower/upper - Search for records in range
- index - Search for records by table index
- index_type - Search for records and specify their index data type
- limit - Limit the resulted records. If the limit is set to 1 you will get directly the resulted record instead of an array with one element
const withdrawer = await eoslimeAccount;const faucetAccount = await eoslimeAccount;const faucetContract = eoslime; // faucetAccount is the executorawait faucetContract; // With equal criteriaconst equalResult = await faucetContract; // With range criteriaconst rangeResult = await faucetContract; // With limitconst allWithdrawers = await faucetContract; // With different index (By Quantity)const balanceWithdrawers = await faucetContract;
Utils
Test
- #####
eoslime.utils.test.expectAssert
const eoslime = ; const WASM_PATH = './contract/contract.wasm';const ABI_PATH = './contract/contract.abi';
- #####
eoslime.utils.test.expectMissingAuthority
const eoslime = ; const WASM_PATH = './contract/contract.wasm';const ABI_PATH = './contract/contract.abi';
Example (eosio.token)
You can check eosio.token example to get better idea of how to work with eoslime
.
The example is for testing purposes only.
You must:
- Run nodoes locally
- Start example with:
npm run start
Roadmap
- cli
Donations
This is a free time project. We do it, because we want to help EOS world to reach more developers. If you want to buy us some beers in order to relax, we won't say no :P
Account: gqytgmrtgage