Skip to content

Commit

Permalink
fix(contract)!: allow to static calls without wallet
Browse files Browse the repository at this point in the history
BREAKING CHANGE: `contract call` accepts `wallet_path` as the last argument
For example, replace
```
$ aecli contract call ./myWalletFile --password testpass foo '[1, 2]'
```
with
```
$ aecli contract call --password testpass foo '[1, 2] ./myWalletFile'
```
  • Loading branch information
davidyuk committed Aug 29, 2022
1 parent 42ab90f commit 7bf7bb6
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 9 deletions.
6 changes: 5 additions & 1 deletion src/actions/contract.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import path from 'path';
import { encode } from '@aeternity/aepp-sdk';
import { initSdk, initSdkByWalletFile } from '../utils/cli';
import { print, printTransaction, printUnderscored } from '../utils/print';
import CliError from '../utils/CliError';

const resolve = (filename) => path.resolve(process.cwd(), filename);

Expand Down Expand Up @@ -105,10 +106,13 @@ export async function deploy(walletPath, args, options) {
}

// ## Function which `call` contract
export async function call(walletPath, fn, args, options) {
export async function call(fn, args, walletPath, options) {
const {
callStatic, json, top, ttl, gas, nonce,
} = options;
if (callStatic !== true && walletPath == null) {
throw new CliError('wallet_path is required for on-chain calls');
}
const sdk = await initSdkByWalletFile(walletPath, options);
const contract = await sdk.getContractInstance(await getContractParams(options));
const callResult = await contract.call(fn, args, {
Expand Down
4 changes: 3 additions & 1 deletion src/commands/contract.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,10 @@ program
// You can preset gas, nonce and ttl for that call. If not set use default.
// Example: `aecli contract call ./myWalletFile --password testpass sumFunc '[1, 2]' --descrPath ./contractDescriptorFile.json --gas 2222222 --nonce 4 --ttl 1243`
program
.command('call <wallet_path> <fn>')
.command('call')
.argument('<fn>', 'Name of contract entrypoint to call')
.addArgument(callArgs)
.argument('[wallet_path]', 'Path to secret storage file')
.addOption(descriptorPathOption)
.option('--contractAddress [contractAddress]', 'Contract address to call')
.addOption(contractSourceFilenameOption)
Expand Down
6 changes: 4 additions & 2 deletions src/utils/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ export async function getAccountByWalletFile(walletPath, options) {
//
// We use `getWalletByPathAndDecrypt` from `utils/account` to get `keypair` from file
export async function initSdkByWalletFile(walletPath, options) {
const { account } = await getAccountByWalletFile(walletPath, options);
return initSdk({ ...options, accounts: [account] });
return initSdk({
...options,
accounts: walletPath ? [(await getAccountByWalletFile(walletPath, options)).account] : [],
});
}
32 changes: 27 additions & 5 deletions test/contract.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,10 @@ describe('Contract Module', function contractTests() {
it('calls contract', async () => {
const callResponse = await executeContract([
'call',
WALLET_NAME, '--password', 'test',
'--json',
'--descrPath', deployDescriptorFile,
'test', '[1, 2]',
WALLET_NAME, '--password', 'test',
]);
callResponse.result.returnValue.should.contain('cb_');
callResponse.decodedResult.should.be.equal('6');
Expand All @@ -141,57 +141,79 @@ describe('Contract Module', function contractTests() {
it('overrides descriptor\'s address using --contractAddress', async () => {
await expect(executeContract([
'call',
WALLET_NAME, '--password', 'test',
'--json',
'--contractAddress', 'ct_test',
'--descrPath', deployDescriptorFile,
'test', '[1, 2]',
WALLET_NAME, '--password', 'test',
])).to.be.rejectedWith('Invalid name or address: ct_test');
});

it('throws error if descriptor file not exists', async () => {
await expect(executeContract([
'call',
WALLET_NAME, '--password', 'test',
'--json',
'--descrPath', `${deployDescriptorFile}test`,
'test', '[1, 2]',
WALLET_NAME, '--password', 'test',
])).to.be.rejectedWith('ENOENT: no such file or directory, open');
});

it('throws error when calls contract without wallet', async () => {
await expect(executeContract([
'call',
'--json',
'--descrPath', deployDescriptorFile,
'test', '[1, 2]',
])).to.be.rejectedWith(CliError, 'wallet_path is required for on-chain calls');
});

it('calls contract static', async () => {
const callResponse = await executeContract([
'call',
'--json',
'--descrPath', deployDescriptorFile,
'test', '[1, 2]',
'--callStatic',
WALLET_NAME, '--password', 'test',
]);
callResponse.result.returnValue.should.contain('cb_');
callResponse.decodedResult.should.equal('6');
});

it('calls contract static with dry run account', async () => {
const callResponse = await executeContract([
'call',
'--json',
'--descrPath', deployDescriptorFile,
'test', '[1, 2]',
'--callStatic',
]);
callResponse.result.returnValue.should.contain('cb_');
expect(callResponse.result.callerId).to.equal('ak_11111111111111111111111111111111273Yts');
callResponse.decodedResult.should.equal('6');
});

it('calls contract by contract source and address', async () => {
const callResponse = await executeContract([
'call',
WALLET_NAME, '--password', 'test',
'--json',
'--contractAddress', contractAddress,
'--contractSource', contractSourceFile,
'test', '[1, 2]',
WALLET_NAME, '--password', 'test',
]);
callResponse.decodedResult.should.equal('6');
});

it('calls contract by contract ACI and address', async () => {
const callResponse = await executeContract([
'call',
WALLET_NAME, '--password', 'test',
'--json',
'--contractAddress', contractAddress,
'--contractAci', contractAciFile,
'test', '[1, 2]',
WALLET_NAME, '--password', 'test',
]);
callResponse.decodedResult.should.equal('6');
});
Expand Down

0 comments on commit 7bf7bb6

Please sign in to comment.