Skip to content

Commit eeaf01b

Browse files
authored
Merge pull request #73 from terra-money/feat/simulate
feat: simulate transaction return all data to the frontend
2 parents a03e575 + f9cd6a8 commit eeaf01b

File tree

4 files changed

+108
-4
lines changed

4 files changed

+108
-4
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@terra-money/feather.js",
3-
"version": "2.0.1",
3+
"version": "2.0.2",
44
"description": "The JavaScript SDK for Terra and Feather chains",
55
"license": "MIT",
66
"author": "Terraform Labs, PTE.",

src/client/lcd/api/TxAPI.spec.ts

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
import { LCDClient } from '../LCDClient';
22
import { APIRequester } from '../APIRequester';
3-
import { MsgSend } from '../../../core';
3+
import {
4+
AuthInfo,
5+
Coin,
6+
Fee,
7+
MsgSend,
8+
MsgUndelegate,
9+
Tx,
10+
TxBody,
11+
} from '../../../core';
412
import { TxAPI } from './TxAPI';
513
import { MnemonicKey } from '../../../key';
614
import { isTxError } from './TxAPI';
@@ -148,3 +156,64 @@ describe('TxAPI', () => {
148156
});
149157
});
150158
});
159+
160+
describe('simulateTx', () => {
161+
it('should simulate a transaction', async () => {
162+
// Given the transaction that needs to be simulated
163+
const mockTx = new Tx(
164+
new TxBody([
165+
new MsgUndelegate(
166+
'mockDelegatorAddress',
167+
'mockValidatorAddress',
168+
new Coin('uluna', '1000000')
169+
),
170+
]),
171+
new AuthInfo([], new Fee(50000000, [new Coin('uluna', '1000000')])),
172+
['']
173+
);
174+
// We mock the data that will be returned from the blockchain API and set it up as a function that returns a promise
175+
const mockResponseData = {
176+
gas_info: {
177+
gas_wanted: '2000',
178+
gas_used: '1000',
179+
},
180+
result: {
181+
data: 'data_mocked',
182+
log: '[{"type":"message","attributes":[{"key":"action","value":"undelegate"}]}]',
183+
events: [
184+
{
185+
type: 'message',
186+
attributes: [{ key: 'action', value: 'undelegate' }],
187+
},
188+
],
189+
},
190+
};
191+
lcd.apiRequesters['pisco-1'].post = jest.fn(
192+
async () => Promise.resolve(mockResponseData) as any
193+
);
194+
195+
// When simulating the transaction
196+
const res = await lcd.tx.simulateTx(mockTx, 'pisco-1');
197+
198+
// Expect that the simulate endpoint have been executed,
199+
// and assert the responses from the API.
200+
expect(lcd.apiRequesters['pisco-1'].post).toHaveBeenCalledWith(
201+
`/cosmos/tx/v1beta1/simulate`,
202+
expect.any(Object)
203+
);
204+
expect(res.gas_info).toEqual({
205+
gas_wanted: 2000,
206+
gas_used: 1750,
207+
});
208+
expect(res.result).toEqual({
209+
data: 'data_mocked',
210+
log: '[{"type":"message","attributes":[{"key":"action","value":"undelegate"}]}]',
211+
events: [
212+
{
213+
type: 'message',
214+
attributes: [{ key: 'action', value: 'undelegate' }],
215+
},
216+
],
217+
});
218+
});
219+
});

src/client/lcd/api/TxAPI.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,41 @@ export class TxAPI extends BaseAPI {
374374
return new Dec(gasAdjustment).mul(simulateRes.gas_info.gas_used).toNumber();
375375
}
376376

377+
public async simulateTx(
378+
tx: Tx,
379+
chainID: string,
380+
options?: {
381+
gasAdjustment?: Numeric.Input;
382+
signers?: SignerData[];
383+
}
384+
): Promise<SimulateResponse> {
385+
const gasAdjustment =
386+
options?.gasAdjustment || this.lcd.config[chainID].gasAdjustment;
387+
388+
// append empty signatures if there's no signatures in tx
389+
let simTx: Tx = tx;
390+
if (tx.signatures.length <= 0) {
391+
if (!(options && options.signers && options.signers.length > 0)) {
392+
throw Error('cannot append signature');
393+
}
394+
const authInfo = new AuthInfo([], new Fee(0, new Coins()));
395+
simTx = new Tx(tx.body, authInfo, []);
396+
simTx.appendEmptySignatures(options.signers);
397+
}
398+
399+
const simulateRes = await this.getReqFromChainID(chainID)
400+
.post<SimulateResponse.Data>(`/cosmos/tx/v1beta1/simulate`, {
401+
tx_bytes: this.encode(simTx, this.lcd.config[chainID].isClassic),
402+
})
403+
.then(d => SimulateResponse.fromData(d));
404+
405+
simulateRes.gas_info.gas_used = new Dec(gasAdjustment)
406+
.mul(simulateRes.gas_info.gas_used)
407+
.toNumber();
408+
409+
return simulateRes;
410+
}
411+
377412
public async computeTax(): Promise<Coins> {
378413
throw new Error('Tax was removed from network');
379414
}

0 commit comments

Comments
 (0)