⚠️ (Work In Progress)
Report Bug |
Request Feature
Echpochmak, is a framework based on TONOS Client Library for TON DApp development
It provides some high-level interfaces to interact with your TON smart-contracts, allowing you to write integration and e2e tests.
Echpochmak
npm install -g echpochmak
You can see examples of tests here
To run all tests:
echpochmak-cli test -p ./path/to/tests/folder
Synopsis
test [options]
Options
Option | Description | Default |
---|---|---|
-p, --path | Path to test folder | |
-b, --bail | Enable bail | false |
-v, --verbose | Wite debug info | false |
-t, --timeout | Timeout time for test | 0 |
--version (boolean) | Show version | |
--help (boolean) | Show help information |
If you need help, use
echpochmak-cli --help
beforeEach(async () => {
await restart(); //Recreate and start containers
});
restart command does not set a port for the container, but only uses it for long polling
beforeEach(async () => {
await restart(8080); //Default 80
});
const manager = new Manager();
beforeEach(async () => {
manager = new Manager();
default
['net.ton.dev']
Signature
async createClient(servers: string[] = ['net.ton.dev'])
await manager.createClient(['http://localhost:8080/graphql']);
let keys = await manager.createKeysAndReturn();
Signature
public async loadContract( contractPath: string, abiPath: string, options: loadOptions )
await manager.loadContract(
'./tests/contract/15_MessageReceiver.tvc', // tvc
'./tests/contract/15_MessageReceiver.abi.json' // abi
);
await manager.loadContract(
'./tests/contract/15_MessageReceiver.tvc', // tvc
'./tests/contract/15_MessageReceiver.abi.json' // abi
);
// Custom name
await manager.loadContract(
'./tests/contract/15_MessageSender.tvc',
'./tests/contract/15_MessageSender.abi.json',
{ contractName: 'sender ' } // Name
);
// Custom keys
await manager.loadContract(
'./tests/contract/15_MessageSender.tvc',
'./tests/contract/15_MessageSender.abi.json',
{ keys: anyKeys } // keys
);
Get future/current address
let address = manager.contracts['15_MessageReceiver'].address;
loadOption signature
export interface loadOptions {
keys?: any;
contractName?: string;
}
manager.contracts['Contract_name']; // Taken from the name of the tvc file without extension
Signature
async deployContract(constructorParams = {}, giveGram = true, keys?)
await manager.contracts['15_MessageReceiver'].deployContract();
await manager.contracts['15_MessageSender'].deployContract();
await manager.contracts['9_PiggyBank'].deployContract({
own: manager.contracts['9_PiggyBank_Owner'].address,
lim: 1000000,
});
This method allows you to provide: constructor parameters, constructor headers and init parameters of your deployable smart contract
await manager.contracts['someName'].complicatedDeploy(
constructorParams,
constructorHeader,
initParams,
)
await manager.contracts['9_PiggyBank'].complicatedDeploy(
{
own: manager.contracts['9_PiggyBank_Owner'].address,
lim: 1000000,
},
{
pubkey: keypair.public,
expire: new Date()
},
{
randomNonce: '0x' + crypto.createHash('sha256').update(crypto.randomBytes(32)).digest('hex')
}
);
### Or use custom keys
```js
await manager.contracts['9_PiggyBank'].deployContract({}, keys);
Signature
async addContractFromAddress( address: string, abiPath: string, contractName: string, keyPair? )
await manager.addContractFromAddress(
'address',
'abiPath',
'contractName',
keyPair // HERE, the keys are indicated, if nothing is specified, those inside the contract object are used
);
Signature
async runContract(functionName, input, keyPair?)
await manager.contracts['15_MessageSender'].runContract('sendMessage', {
anotherContract: manager.contracts['15_MessageReceiver'].address,
});
await manager.contracts['15_MessageSender'].runContract(
'sendMessage',
{
anotherContract: manager.contracts['15_MessageReceiver'].address,
},
null // HERE, the keys are indicated, if nothing is specified, those inside the contract object are used (see below);
);
Signature
async runLocal(functionName, input, keyPair?)
await manager.contracts['15_MessageSender'].runLocal('getData', {});
Signature
public async runWithMessage(functionName, input, keyPair?)
const msg = await manager.contracts['15_MessageSender'].runWithMessage(
'sendMessage',
{
anotherContract: manager.contracts['15_MessageReceiver'].address,
}
);
console.log(`Tokens were sent. Transaction id is ${msg.transaction.id}`);
console.log(`Run fees are ${JSON.stringify(msg.fees, null, 2)}`);
Signature
async giveToAddress(address, amount?: number)
manager.giveToAddress(manager.contracts['15_MessageReceiver'].address); // give 1000000000000000 gram
manager.contracts['15_MessageSender'].address; // Contract address
manager.contracts['15_MessageSender'].contractPath; // Contract path
manager.contracts['15_MessageSender'].isDeployed; // boolean
manager.contracts['15_MessageSender'].contractPackage; //{ abi,imageBase64 }
helpers
from Manager objectmanager.helpers.<helper>;
Signature
public static async deployCheck(address, client)
await manager.helpers.deployCheck(contractAddress, manager.client);
Signature
public static async getAccountBalance(address, client)
await manager.helpers.getAccountBalance(contractAddress, manager.client);
Signature
public static async hasOnBounced(address, timestamp: number, client)
timestamp
- The time when the transaction preceding OnBounced was made, guarantees the assistant will wait for the last message OnBounced
await manager.helpers.hasOnBounced(contractAddress, manager.client);
Signature
public static async lastMessage( address, client, fields = 'src, dst, bounce, bounced, value' )
let tx = await manager.helpers.lastTransaction(contractAddress, manager.client);
Signature
public static async lastMessage( address, client, fields = 'src, dst, bounce, bounced, value' )
let msg = await manager.helpers.lastMessage(contractAddress, manager.client);
Signature
public static async balanceHasChanged( address, client, oldValue, type: hasChangedValue )
await manager.helpers.balanceHasChanged(
contractAddress,
manager.client,
100000,
hasChangedValue.big
);
hasChangedValue enum
export enum hasChangedValue {
big,
small,
}
Signature
static async getRunFees( contract: Contract, functionName, input, client, keyPair )
const fees = await manager.helpers.getRunFees(
manager.contracts['15_MessageSender'],
'send',
manager.client,
keys
);
Signature
static async getDeployFees( contract: Contract, constructorParams, newAccount: boolean, client, keyPair )
const fees = await manager.helpers.getDeployFees(
manager.contracts['15_MessageSender'],
{},
true,
manager.client,
keys
);
Signature
assertError = async (asyncFn: any, code: number, message?)
Example
await assertError(
async () => {
await manager.contracts['9_PiggyBank'].runContract('getData', {});
},
3025,
'getData'
);
A simple wallet contract, you may find it useful when testing fallback functions
Signature
async createWallet(keys?)
let wallet = await manager.createWallet();
let wallet = await manager.createWallet(keys);
await wallet.deploy();
Signature
async sendTransaction(dest: string, value: number, bounce: boolean)
await wallet.sendTransaction(
(dest: string),
(value: number),
(bounce: boolean)
);
wallet.address; // wallet address
wallet.contractPath; // wallet path
wallet.isDeployed; // boolean
wallet.contractPackage; //{ abi,imageBase64 }
CustomObject.example.js
const BaseContract = require('echpochmak').BaseContract; // Import BaseContract class
class BankContract extends BaseContract {
async getData() {
// new
return await this.runLocal('getData', {}); // Using 'contract' object fields
}
}
module.exports = BankContract;
Import contract object
const BankContract = require('./CustomObject.example');
Create object (Constructor used from BaseContract class)
const customBankObject = await new BankContract(
'./tests/contract/9_PiggyBank.tvc',
'./tests/contract/9_PiggyBank.abi.json',
manager.client,
await manager.createKeysAndReturn()
);
Add object in manager
manager.addCustomContract(customBankObject, 'customBank');
Use custom fields
const res = await manager.contracts['customBank'].getData();
Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are greatly appreciated.
git checkout -b feature/AmazingFeature
)git commit -m 'Add some AmazingFeature'
)git push origin feature/AmazingFeature
)Distributed under the Apache 2.0 License. See LICENSE
for more information.