Skip to content

Commit b52bf40

Browse files
committed
Implement submitDatagram
1 parent fb2c4f8 commit b52bf40

File tree

5 files changed

+138
-4
lines changed

5 files changed

+138
-4
lines changed

ibc.ts/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
"typescript": "^3.8.2"
1818
},
1919
"dependencies": {
20+
"codechain-primitives": "^1.0.4",
21+
"codechain-sdk": "^2.0.1",
2022
"debug": "^4.1.1",
2123
"rlp": "^2.0.0"
2224
}

ibc.ts/src/common/chain.ts

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,60 @@
11
import { Datagram } from "./datagram/index";
2+
import { SDK } from "codechain-sdk";
3+
import { H256, PlatformAddress } from "codechain-primitives";
4+
import { IBC } from "./foundry/transaction";
5+
import { delay } from "./util";
6+
import Debug from "debug";
7+
8+
const debug = Debug("common:tx");
9+
10+
export interface ChainConfig {
11+
/**
12+
* Example: "http://localhost:8080"
13+
*/
14+
server: string;
15+
networkId: string;
16+
faucetAddress: PlatformAddress;
17+
}
218

319
export class Chain {
4-
public async submitDatagram(datagram: Datagram): Promise<any> {
5-
return null;
20+
private readonly sdk: SDK;
21+
private readonly faucetAddress: PlatformAddress;
22+
23+
public constructor(config: ChainConfig) {
24+
this.sdk = new SDK({
25+
server: config.server,
26+
networkId: config.networkId
27+
});
28+
this.faucetAddress = config.faucetAddress;
29+
}
30+
31+
public async submitDatagram(datagram: Datagram): Promise<void> {
32+
const ibcAction = new IBC(this.sdk.networkId, datagram.rlpBytes());
33+
34+
const seq = await this.sdk.rpc.chain.getSeq(this.faucetAddress);
35+
const signedTx = await this.sdk.key.signTransaction(ibcAction, {
36+
account: this.faucetAddress,
37+
fee: 100,
38+
seq
39+
});
40+
41+
const txHash = await this.sdk.rpc.chain.sendSignedTransaction(signedTx);
42+
waitForTx(this.sdk, txHash);
643
}
744
}
45+
46+
async function waitForTx(sdk: SDK, txHash: H256) {
47+
const timeout = delay(10 * 1000).then(() => {
48+
throw new Error("Timeout");
49+
});
50+
const wait = (async () => {
51+
while (true) {
52+
debug(`wait tx: ${txHash.toString()}`);
53+
if (sdk.rpc.chain.containsTransaction(txHash)) {
54+
return;
55+
}
56+
await delay(500);
57+
}
58+
})();
59+
return Promise.race([timeout, wait]);
60+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { Transaction } from "codechain-sdk/lib/core/classes";
2+
import { NetworkId } from "codechain-sdk/lib/core/types";
3+
4+
export interface IBCActionJSON {
5+
bytes: Buffer;
6+
}
7+
8+
export class IBC extends Transaction {
9+
private readonly bytes: Buffer;
10+
11+
public constructor(networkId: NetworkId, bytes: Buffer) {
12+
super(networkId);
13+
this.bytes = bytes;
14+
}
15+
16+
public type(): string {
17+
return "ibc";
18+
}
19+
20+
protected actionToEncodeObject(): any[] {
21+
return [0x20, this.bytes];
22+
}
23+
24+
// Since the result type is hard-coded in the SDK, we should use any type here.
25+
protected actionToJSON(): any {
26+
return {
27+
bytes: this.bytes
28+
};
29+
}
30+
}

ibc.ts/src/relayer/config.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
export interface Config {
2+
chainA: FoundryChainConfig;
3+
chainB: FoundryChainConfig;
4+
}
5+
6+
interface FoundryChainConfig {
7+
/**
8+
* Foundry RPC URL
9+
* ex) http://localhost:8080
10+
*/
11+
rpcURL: string;
12+
networkId: string;
13+
faucetAddress: string;
14+
}
15+
16+
export function getConfig(): Config {
17+
return {
18+
chainA: {
19+
rpcURL: getEnv("CHAIN_A_RPC_URL"),
20+
networkId: getEnv("CHAIN_A_NETWORK_ID"),
21+
faucetAddress: getEnv("CHAIN_A_FAUCET_ADDRESS")
22+
},
23+
chainB: {
24+
rpcURL: getEnv("CHAIN_B_RPC_URL"),
25+
networkId: getEnv("CHAIN_B_NETWORK_ID"),
26+
faucetAddress: getEnv("CHAIN_B_FAUCET_ADDRESS")
27+
}
28+
};
29+
}
30+
31+
function getEnv(key: string): string {
32+
const result = process.env[key];
33+
if (result) {
34+
return result;
35+
} else {
36+
throw new Error(`Environment variable ${key} is not set`);
37+
}
38+
}

ibc.ts/src/relayer/index.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,23 @@ import Debug from "debug";
22
import { Chain } from "../common/chain";
33
import { Datagram } from "../common/datagram/index";
44
import { delay } from "../common/util";
5+
import { getConfig } from "./config";
6+
import { PlatformAddress } from "codechain-primitives/lib";
57

68
const debug = Debug("relayer:main");
79

810
async function main() {
9-
const chainA = new Chain();
10-
const chainB = new Chain();
11+
const config = getConfig();
12+
const chainA = new Chain({
13+
server: config.chainA.rpcURL,
14+
networkId: config.chainA.networkId,
15+
faucetAddress: PlatformAddress.fromString(config.chainA.faucetAddress)
16+
});
17+
const chainB = new Chain({
18+
server: config.chainB.rpcURL,
19+
networkId: config.chainB.networkId,
20+
faucetAddress: PlatformAddress.fromString(config.chainB.faucetAddress)
21+
});
1122

1223
while (true) {
1324
debug("Run relay");

0 commit comments

Comments
 (0)