Skip to content

Commit

Permalink
Merge pull request #21 from terra-money/feature/mito
Browse files Browse the repository at this point in the history
Feature/mito
  • Loading branch information
simke9445 authored Mar 12, 2024
2 parents a859fff + b26ec08 commit d541782
Show file tree
Hide file tree
Showing 8 changed files with 326 additions and 17 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"bot-injective": "esbuild src/bot.ts --bundle --platform=node --outdir=dist --outbase=src && node ./dist/bot.js ./config.injective.json",
"bot-nibiru": "esbuild src/bot.ts --bundle --platform=node --outdir=dist --outbase=src && node ./dist/bot.js ./config.nibiru.json",
"generate-dts": "dts-bundle-generator -o types.d.ts src/index.ts",
"example-mito": "esbuild src/examples/example_mito.ts --bundle --platform=node --outdir=dist --outbase=src && node ./dist/examples/example_mito.js ./config.injective.json",
"format": "prettier --write \"src/**/*.{js,ts,tsx}\"",
"generate-types": "node --experimental-specifier-resolution=node --loader ts-node/esm ./scripts/generate-types.js warp-protocol",
"postinstall": "husky install",
Expand Down
61 changes: 55 additions & 6 deletions src/condition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export class Condition {
}

if ('ref' in value) {
return this.resolveVariable(this.variable(value.ref, job), (v) => String(v));
return this.resolveVariable(this.variable(value.ref, job), (v) => String(v), job);
}
};

Expand Down Expand Up @@ -145,7 +145,7 @@ export class Condition {
}

if ('ref' in value) {
return this.resolveVariable(this.variable(value.ref, job), (v) => Big(v));
return this.resolveVariable(this.variable(value.ref, job), (v) => Big(v), job);
}

if ('env' in value) {
Expand Down Expand Up @@ -221,15 +221,15 @@ export class Condition {
public resolveExprBool(ref: string, job: Job): Promise<boolean> {
const v = this.variable(ref, job);

return this.resolveVariable(v, (val) => (val === 'true' ? true : false));
return this.resolveVariable(v, (val) => (val === 'true' ? true : false), job);
}

public async resolveVariable<T>(variable: warp_resolver.Variable, cast: (val: string) => T): Promise<T> {
public async resolveVariable<T>(variable: warp_resolver.Variable, cast: (val: string) => T, job: Job): Promise<T> {
let resp: T;
let encode: boolean = false;

if ('static' in variable) {
resp = cast(variable.static.value);
resp = cast(await this.resolveStaticVariable(variable.static, job));
encode = variable.static.encode;
}

Expand All @@ -251,16 +251,65 @@ export class Condition {
}

public async resolveQueryVariable(query: warp_resolver.QueryVariable): Promise<string> {
if (!query.reinitialize && Boolean(query.value)) {
return query.value;
}

const resp = await contractQuery<
Extract<warp_resolver.QueryMsg, { simulate_query: {} }>,
warp_resolver.SimulateResponse
>(this.wallet.lcd, this.contracts.resolver, { simulate_query: { query: query.init_fn.query } });

const extracted = JSONPath({ path: query.init_fn.selector, json: JSON.parse(resp.response) });

if (extracted[0] === null) {
return null;
} else {
return String(extracted[0]);
return JSON.stringify(extracted[0]);
}
}

public async resolveStaticVariable(variable: warp_resolver.StaticVariable, job: Job): Promise<string> {
if (!variable.reinitialize && Boolean(variable.value)) {
return variable.value;
}

const fnValue = variable.init_fn;

if ('string' in fnValue) {
return this.resolveStringValue(fnValue.string, job);
}

let numResult: Big = null;

if ('uint' in fnValue) {
numResult = await this.resolveNumValue(fnValue.uint, job);
}

if ('int' in fnValue) {
numResult = await this.resolveNumValue(fnValue.int, job);
}

if ('decimal' in fnValue) {
numResult = await this.resolveNumValue(fnValue.decimal, job);
}

if ('block_height' in fnValue) {
numResult = await this.resolveNumValue(fnValue.block_height, job);
}

if ('timestamp' in fnValue) {
numResult = await this.resolveNumValue(fnValue.timestamp, job);
}

if (numResult !== null) {
return numResult.toString();
}

if ('bool' in fnValue) {
const boolResult = this.resolveExprBool(fnValue.bool, job);

return JSON.stringify(boolResult);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/examples/example_eris.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const condition = cond.uint(uint.env('time'), 'gt', uint.ref(nextExecution));
const executions = [
{
condition,
msgs: [msg.execute('terra10788fkzah89xrdm27zkj5yvhj9x3494lxawzm5qq3vvxcqz2yzaqyd3enk', { harvest: {} })],
msgs: [msg.execute('terra1kye343r8hl7wm6f3uzynyyzl2zmcm2sqmvvzwzj7et2j5jj7rjkqa2ue88', { harvest: {} })],
},
];

Expand Down
163 changes: 163 additions & 0 deletions src/examples/example_mito.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import { MnemonicKey, Wallet } from '@terra-money/feather.js';
import { WarpSdk } from '../sdk';
import { uint, cond, fn, msg, variable, job, ts, query, string } from '../composers';
import { ChainName, NetworkName } from 'modules';
import dotenv from 'dotenv';
import fs from 'fs';

dotenv.config();

const configPath = process.argv[2];
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));

const lcd = WarpSdk.lcdClient({ networks: [config.NETWORK as NetworkName], chains: [config.CHAIN as ChainName] });
const lcdClientConfig = Object.values(lcd.config)[0];
const wallet = new Wallet(lcd, new MnemonicKey({ mnemonic: config.MNEMONIC_KEY, coinType: Number(config.COIN_TYPE) }));
const sdk = new WarpSdk(wallet, lcdClientConfig);
const sender = wallet.key.accAddress(lcdClientConfig.prefix);

const vault_contract_addr = 'inj1xvlnfmq5672rmvn6576rvj389ezu9nxc9dpk8l';
const vault_strategy_denom = 'inj';

const subaccount_id = variable
.query()
.kind('string')
.name('subaccount_id')
.onInit({
query: query.smart(vault_contract_addr, { base: { config: {} } }),
selector: '$.config.base.subaccount_id',
})
.reinitialize(true)
.compose();

const next_subaccount_available_balance = variable
.query()
.kind('uint')
.value('0')
.name('next_subaccount_available_balance')
.onInit({
query: {
custom: {
subaccount_deposit: {
subaccount_id: variable.ref(subaccount_id),
denom: vault_strategy_denom,
},
},
} as any,
selector: '$.deposits.available_balance',
})
.reinitialize(true)
.compose();

const prev_subaccount_available_balance = variable
.static()
.kind('uint')
.name('prev_subaccount_available_balance')
.reinitialize(false)
.onInit({
uint: {
simple: '0',
},
})
.onSuccess({
uint: {
ref: variable.ref(next_subaccount_available_balance),
},
})
.compose();

const next_config = variable
.query()
.kind('string')
.name('next_config')
.onInit({
query: query.smart(vault_contract_addr, { base: { config: {} } }),
selector: '$.config',
})
.reinitialize(true)
.compose();

const prev_config = variable
.static()
.kind('string')
.onInit({
string: {
simple: '',
},
})
.name('prev_config')
.reinitialize(false)
.onSuccess({
string: {
ref: variable.ref(next_config),
},
})
.compose();

const condition = cond.or(
cond.uint(uint.ref(prev_subaccount_available_balance), 'lt', uint.ref(next_subaccount_available_balance)),
cond.string(string.ref(prev_config), 'neq', string.ref(next_config))
);

const executions = [
{
condition,
msgs: [
msg.execute(vault_contract_addr, {
market_make: {},
}),
],
},
];

const recurring = true;
const durationDays = '7';
// ordered in reference order (left to right, dfs)
const vars = [
subaccount_id,
next_subaccount_available_balance,
prev_subaccount_available_balance,
next_config,
prev_config,
];

const estimateJobRewardMsg = job
.estimate()
.recurring(recurring)
.durationDays(durationDays)
.vars(vars)
.executions(executions)
.compose();

const main = async () => {
try {
const reward = await sdk.estimateJobReward(sender, estimateJobRewardMsg);

const operationalAmount = await sdk.estimateJobFee(sender, estimateJobRewardMsg, reward.amount.toString());

const createJobMsg = job
.create()
.name('mito-market-make')
.description('Triggers market making on mito vaults.')
.labels([])
.recurring(recurring)
.reward(reward.amount.toString())
.operationalAmount(operationalAmount.amount.toString())
.vars(vars)
.durationDays(durationDays)
.executions(executions)
.compose();

const tx = await sdk.tx.createJob(sender, createJobMsg, [operationalAmount]);

console.log(JSON.stringify(tx.msgs, null, 2));

// sdk.createJob(sender, createJobMsg, [operationalAmount]).then((response) => {
// console.log(response);
// });
} catch (err) {
console.log(err);
}
};

main();
92 changes: 92 additions & 0 deletions src/examples/example_simulate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { LCDClient, LCDClientConfig, MnemonicKey, Wallet } from '@terra-money/feather.js';
import { WarpSdk } from '../sdk';
import { uint, cond, fn, msg, variable, job, ts } from '../composers';

const piscoLcdClientConfig: LCDClientConfig = {
lcd: 'https://pisco-lcd.terra.dev',
chainID: 'pisco-1',
gasAdjustment: 1.75,
gasPrices: { uluna: 0.015 },
prefix: 'terra',
};

const lcd = new LCDClient({
'pisco-1': piscoLcdClientConfig,
});

const wallet = new Wallet(lcd, new MnemonicKey({ mnemonic: '...' }));

const sdk = new WarpSdk(wallet, piscoLcdClientConfig);
const sender = wallet.key.accAddress(piscoLcdClientConfig.prefix);

const nextExecution = variable
.static()
.kind('uint')
.name('next_execution')
.onInit({
uint: {
simple: ts.date(new Date('2023-04-10T12:30:00.000Z')),
},
})
.onSuccess(fn.uint(uint.expr(uint.simple(ts.days(1)), 'add', uint.env('time'))))
.onError(fn.uint(uint.expr(uint.simple(ts.hours(1)), 'add', uint.env('time'))))
.compose();

const condition = cond.uint(uint.env('time'), 'gt', uint.ref(nextExecution));

const executions = [
{
condition,
msgs: [
msg.execute('terra1kjv3e7v7m03kk8lrjqr2j604vusxrpxadg6xjz89jucladh5m5gqqag8q7', {
execute_simulate_query: {
query: {
wasm: {
contract_info: { contract_addr: 'terra1mmsl3mxq9n8a6dgye05pn0qlup7r24e2vyjkqgpe32pv3ehjgnes0jz5nc' },
},
},
},
}),
],
},
];

const recurring = true;
const durationDays = '30';
const vars = [nextExecution];

const estimateJobRewardMsg = job
.estimate()
.recurring(recurring)
.durationDays(durationDays)
.vars(vars)
.executions(executions)
.compose();

const main = async () => {
try {
const reward = await sdk.estimateJobReward(sender, estimateJobRewardMsg);

const operationalAmount = await sdk.estimateJobFee(sender, estimateJobRewardMsg, reward.amount.toString());

const createJobMsg = job
.create()
.name('warp-simulate')
.description('This job executes a query simulation for testing purposes.')
.labels([])
.recurring(recurring)
.reward(reward.amount.toString())
.operationalAmount(operationalAmount.amount.toString())
.vars(vars)
.durationDays(durationDays)
.executions(executions)
.compose();

console.log(JSON.stringify(createJobMsg, null, 2));
} catch (err) {
console.log(err);
throw err;
}
};

main();
4 changes: 2 additions & 2 deletions src/modules/chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const mainnetConfig: Record<string, LCDClientConfig> = {
},
'injective-1': {
chainID: 'injective-1',
lcd: 'https://lcd.injective.network',
lcd: 'https://sentry.lcd.injective.network',
gasAdjustment: 1.75,
gasPrices: {
inj: 1500000000,
Expand Down Expand Up @@ -89,7 +89,7 @@ const testnetConfig: Record<string, LCDClientConfig> = {
},
'injective-888': {
chainID: 'injective-888',
lcd: 'https://k8s.testnet.lcd.injective.network',
lcd: 'https://testnet.sentry.lcd.injective.network:443',
gasAdjustment: 1.75,
gasPrices: {
inj: 1500000000,
Expand Down
Loading

0 comments on commit d541782

Please sign in to comment.