Skip to content

Commit 670fc23

Browse files
author
Dev Kalra
authored
Osmosis deployment code (#469)
* Osmosis deployment code * extract out pyth sources
1 parent 3d8638a commit 670fc23

File tree

8 files changed

+677
-82
lines changed

8 files changed

+677
-82
lines changed

target-chains/cosmwasm/tools/package-lock.json

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

target-chains/cosmwasm/tools/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,24 @@
1111
"author": "",
1212
"license": "ISC",
1313
"dependencies": {
14+
"@cosmjs/cosmwasm-stargate": "^0.29.5",
1415
"@cosmjs/encoding": "^0.26.2",
1516
"@injectivelabs/networks": "^1.0.55",
1617
"@injectivelabs/sdk-ts": "^1.0.330",
1718
"@injectivelabs/utils": "^1.0.47",
1819
"@terra-money/terra.js": "^3.1.3",
20+
"chain-registry": "^1.6.0",
21+
"cosmjs-utils": "^0.1.0",
1922
"dotenv": "^16.0.0",
2023
"ethers": "^5.4.4",
24+
"osmojs": "^13.0.0-rc.7-i-alpha",
2125
"yargs": "^17.0.1"
2226
},
2327
"devDependencies": {
2428
"@types/yargs": "^17.0.18",
2529
"@typescript-eslint/eslint-plugin": "^5.43.0",
2630
"@typescript-eslint/parser": "^5.43.0",
31+
"cosmjs-types": "^0.6.1",
2732
"eslint": "^8.27.0",
2833
"eslint-config-prettier": "^8.5.0",
2934
"ts-node": "^10.9.1",

target-chains/cosmwasm/tools/src/deployer/config.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ import { Network } from "@injectivelabs/networks";
22
import { TerraHost } from "./terra";
33
import { InjectiveHost } from "./injective";
44
import { NETWORKS } from "../network";
5+
import { OsmosisHost } from "./osmosis";
56

67
export enum CONFIG_TYPE {
78
TERRA = "terra",
89
INJECTIVE = "injective",
10+
OSMOSIS = "osmosis",
911
}
1012

1113
export const CONFIG: Config = {
@@ -31,6 +33,12 @@ export const CONFIG: Config = {
3133
network: Network.Testnet,
3234
},
3335
},
36+
[NETWORKS.OSMOSIS_LOCAL]: {
37+
type: CONFIG_TYPE.OSMOSIS,
38+
host: {
39+
endpoint: "http://localhost:26657",
40+
},
41+
},
3442
};
3543

3644
export type Config = Record<NETWORKS, NetworkConfig>;
@@ -43,4 +51,8 @@ export type NetworkConfig =
4351
| {
4452
type: CONFIG_TYPE.INJECTIVE;
4553
host: InjectiveHost;
54+
}
55+
| {
56+
type: CONFIG_TYPE.OSMOSIS;
57+
host: OsmosisHost;
4658
};

target-chains/cosmwasm/tools/src/deployer/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { CONFIG, CONFIG_TYPE, NetworkConfig } from "./config";
22
import { TerraDeployer } from "./terra";
33
import { InjectiveDeployer } from "./injective";
44
import { NETWORKS } from "../network";
5+
import { OsmosisDeployer } from "./osmosis";
56

67
export interface Deployer {
78
deployArtifact(artifact: string): Promise<number>;
@@ -22,6 +23,9 @@ export class DeployerFactory {
2223
case CONFIG_TYPE.INJECTIVE:
2324
return InjectiveDeployer.fromHostAndMnemonic(config.host, mnemonic);
2425

26+
case CONFIG_TYPE.OSMOSIS:
27+
return OsmosisDeployer.fromHostAndMnemonic(config.host, mnemonic);
28+
2529
default:
2630
throw new Error("Invalid config type");
2731
}
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
import { getSigningOsmosisClient } from "osmojs";
2+
import { getOfflineSignerProto as getOfflineSigner } from "cosmjs-utils";
3+
import { chains } from "chain-registry";
4+
import { Chain } from "@chain-registry/types";
5+
import { readFileSync } from "fs";
6+
import { cosmwasm, estimateOsmoFee } from "osmojs";
7+
import { DeliverTxResponse } from "@cosmjs/stargate";
8+
import { wasmTypes } from "@cosmjs/cosmwasm-stargate/build/modules/wasm/messages";
9+
import assert from "assert";
10+
11+
import { Deployer } from ".";
12+
import { convert_terra_address_to_hex, extractFromRawLog } from "./terra";
13+
import { EncodeObject } from "@cosmjs/proto-signing";
14+
import Long from "long";
15+
16+
export type OsmosisHost = {
17+
endpoint: string;
18+
};
19+
20+
export class OsmosisDeployer implements Deployer {
21+
private chain: Chain;
22+
constructor(private endpoint: string, private mnemonic: string) {
23+
const c = chains.find(({ chain_name }) => chain_name === "osmosis");
24+
if (c === undefined)
25+
throw new Error("Could not find Osmosis in chain registry");
26+
this.chain = c;
27+
}
28+
29+
private async getAccountAddress(): Promise<string> {
30+
const signer = await getOfflineSigner({
31+
mnemonic: this.mnemonic,
32+
chain: this.chain,
33+
});
34+
35+
const accountData = await signer.getAccounts();
36+
return accountData[0].address;
37+
}
38+
39+
private async signAndBroadcast(
40+
msg: EncodeObject
41+
): Promise<DeliverTxResponse> {
42+
const signer = await getOfflineSigner({
43+
mnemonic: this.mnemonic,
44+
chain: this.chain,
45+
});
46+
47+
const client = await getSigningOsmosisClient({
48+
rpcEndpoint: this.endpoint,
49+
signer,
50+
defaultTypes: wasmTypes,
51+
});
52+
53+
const address = await this.getAccountAddress();
54+
const fee = await estimateOsmoFee(client, address, [msg], "estimate fee");
55+
const rs = await client.signAndBroadcast(address, [msg], fee);
56+
57+
if (rs.code !== 0) {
58+
console.error(`Transaction failed: ${rs.rawLog}`);
59+
} else {
60+
console.log(
61+
`Broadcasted transaction hash: ${JSON.stringify(rs.transactionHash)}`
62+
);
63+
}
64+
65+
client.disconnect();
66+
67+
return rs;
68+
}
69+
70+
async deployArtifact(artifact: string): Promise<number> {
71+
const contract_bytes = readFileSync(artifact);
72+
console.log(`Storing WASM: ${artifact} (${contract_bytes.length} bytes)`);
73+
74+
const storeCode = cosmwasm.wasm.v1.MessageComposer.withTypeUrl.storeCode({
75+
sender: await this.getAccountAddress(),
76+
wasmByteCode: contract_bytes,
77+
});
78+
79+
const rs = await this.signAndBroadcast(storeCode);
80+
if (rs.rawLog === undefined)
81+
throw new Error("error parsing raw logs: rawLog undefined");
82+
83+
var codeId: number;
84+
try {
85+
// {"key":"code_id","value":"14"}
86+
const ci = extractFromRawLog(rs.rawLog, "code_id");
87+
codeId = parseInt(ci);
88+
} catch (e) {
89+
console.error(
90+
"Encountered an error in parsing deploy code result. Printing raw log"
91+
);
92+
console.error(rs.rawLog);
93+
throw e;
94+
}
95+
96+
return codeId;
97+
}
98+
99+
async instantiate(
100+
codeId: number,
101+
inst_msg: string | object,
102+
label: string
103+
): Promise<string> {
104+
const accAddress = await this.getAccountAddress();
105+
const instMsg =
106+
cosmwasm.wasm.v1.MessageComposer.withTypeUrl.instantiateContract({
107+
sender: accAddress,
108+
admin: accAddress,
109+
codeId: Long.fromNumber(codeId),
110+
label,
111+
msg: Buffer.from(JSON.stringify(inst_msg)),
112+
funds: [],
113+
});
114+
115+
const rs = await this.signAndBroadcast(instMsg);
116+
if (rs.rawLog === undefined)
117+
throw new Error("error parsing raw logs: rawLog undefined");
118+
119+
var address: string = "";
120+
try {
121+
// {"key":"_contract_address","value":"terra1xxx3ps3gm3wceg4g300hvggdv7ga0hmsk64srccffmfy4wvcrugqnlvt8w"}
122+
address = extractFromRawLog(rs.rawLog, "_contract_address");
123+
} catch (e) {
124+
console.error(
125+
"Encountered an error in parsing instantiation result. Printing raw log"
126+
);
127+
console.error(rs.rawLog);
128+
throw e;
129+
}
130+
131+
console.log(
132+
`Instantiated ${label} at ${address} (${convert_terra_address_to_hex(
133+
address
134+
)})`
135+
);
136+
return address;
137+
}
138+
139+
async migrate(contract: string, codeId: number): Promise<void> {
140+
const migrateMsg =
141+
cosmwasm.wasm.v1.MessageComposer.withTypeUrl.migrateContract({
142+
sender: await this.getAccountAddress(),
143+
contract,
144+
codeId: Long.fromNumber(codeId),
145+
msg: Buffer.from(
146+
JSON.stringify({
147+
action: "",
148+
})
149+
),
150+
});
151+
152+
const rs = await this.signAndBroadcast(migrateMsg);
153+
if (rs.rawLog === undefined)
154+
throw new Error("error parsing raw logs: rawLog undefined");
155+
156+
try {
157+
// {"key":"code_id","value":"13"}
158+
let resultCodeId = parseInt(extractFromRawLog(rs.rawLog, "code_id"));
159+
assert.strictEqual(codeId, resultCodeId);
160+
} catch (e) {
161+
console.error(
162+
"Encountered an error in parsing migration result. Printing raw log"
163+
);
164+
console.error(rs.rawLog);
165+
throw e;
166+
}
167+
}
168+
169+
static fromHostAndMnemonic(host: OsmosisHost, mnemonic: string) {
170+
return new OsmosisDeployer(host.endpoint, mnemonic);
171+
}
172+
}

target-chains/cosmwasm/tools/src/deployer/terra.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,12 @@ export class TerraDeployer implements Deployer {
149149

150150
// Terra addresses are "human-readable", but for cross-chain registrations, we
151151
// want the "canonical" version
152-
function convert_terra_address_to_hex(human_addr: string) {
152+
export function convert_terra_address_to_hex(human_addr: string) {
153153
return "0x" + toHex(zeroPad(Bech32.decode(human_addr).data, 32));
154154
}
155155

156156
// enter key of what to extract
157-
function extractFromRawLog(rawLog: string, key: string): string {
157+
export function extractFromRawLog(rawLog: string, key: string): string {
158158
const rx = new RegExp(`"${key}","value":"([^"]+)`, "gm");
159159
return rx.exec(rawLog)![1];
160160
}

target-chains/cosmwasm/tools/src/network.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@ export enum NETWORKS {
22
TERRA_MAINNET = "terra_mainnet",
33
TERRA_TESTNET = "terra_testnet",
44
INJECTIVE_TESTNET = "injective_testnet",
5+
OSMOSIS_LOCAL = "osmosis_local",
56
}
67

7-
export const NETWORKS_OPTIONS = [
8-
NETWORKS.TERRA_MAINNET,
9-
NETWORKS.TERRA_TESTNET,
10-
NETWORKS.INJECTIVE_TESTNET,
11-
];
8+
export const NETWORKS_OPTIONS = Object.values(NETWORKS);

0 commit comments

Comments
 (0)