Skip to content

Commit 639aee7

Browse files
committed
wip: evm to wasm relayer connection complete
1 parent abe8fcd commit 639aee7

File tree

2 files changed

+134
-1
lines changed

2 files changed

+134
-1
lines changed

packages/gateway/src/index.ts

+23-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { readFileSync } from 'fs';
44
import { ethers } from 'ethers';
55
import { AzeroId } from './azero-id';
66
import { GasLimit } from './utils';
7+
import { Relayer } from './registration-relayer';
8+
import { Keyring } from '@polkadot/keyring';
79
import supportedTLDs from './supported-tlds.json';
810

911
const program = new Command();
@@ -28,7 +30,7 @@ const signer = new ethers.utils.SigningKey(privateKey);
2830

2931
// TODO: make it configurable
3032
const defaultGasLimit: GasLimit = {
31-
refTime: 10_000_000_000,
33+
refTime: 100_000_000_000,
3234
proofSize: 1_000_000,
3335
};
3436

@@ -43,4 +45,24 @@ AzeroId.init(
4345
const app = makeApp(signer, '/', db);
4446
console.log(`Serving on port ${options.port} with signing address ${address}`);
4547
app.listen(parseInt(options.port));
48+
}).then(async () => {
49+
// TODO: make it configurable
50+
const evmProviderURL = "https://ethereum-sepolia.publicnode.com";
51+
const evmRelayerAddr = "0x2BaD727319377af238a7F6D166494118Ca9D0497";
52+
const wasmRelayerAddr = "5GNDka5xV9y9nsES2gqYQponJ8vJaAmoJjMUvrqGqPF65q7P";;
53+
const wasmProviderURL = options.providerUrl;
54+
const keyring = new Keyring({ type: 'sr25519' });
55+
const seed = "0xd5836897dc77e6c87e5cc268abaaa9c661bcf19aea9f0f50a1e149d21ce31eb7"; // public seed
56+
const wasmSigner = keyring.createFromUri(seed);
57+
58+
const relayer = await Relayer.init(
59+
evmProviderURL,
60+
evmRelayerAddr,
61+
wasmProviderURL,
62+
wasmRelayerAddr,
63+
wasmSigner,
64+
defaultGasLimit
65+
);
66+
67+
relayer.start();
4668
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import { ethers } from 'ethers';
2+
import { ApiPromise, WsProvider } from '@polkadot/api';
3+
import { ContractPromise } from '@polkadot/api-contract';
4+
import { KeyringPair } from '@polkadot/keyring/types';
5+
import type { WeightV2 } from '@polkadot/types/interfaces';
6+
import evmABI from './artefacts/evm.json';
7+
import wasmABI from './artefacts/wasm.json';
8+
import { GasLimit } from './utils';
9+
10+
export class Relayer {
11+
evm: ethers.Contract;
12+
wasm: ContractPromise;
13+
wasmSigner: KeyringPair;
14+
wasmGasLimit: WeightV2;
15+
16+
constructor(
17+
evm: ethers.Contract,
18+
wasm: ContractPromise,
19+
wasmSigner: KeyringPair,
20+
wasmGasLimit: WeightV2
21+
) {
22+
this.evm = evm;
23+
this.wasm = wasm;
24+
this.wasmSigner = wasmSigner;
25+
this.wasmGasLimit = wasmGasLimit
26+
}
27+
28+
static async init(
29+
evmProviderURL: string,
30+
evmAddr: string,
31+
wasmProviderURL: string,
32+
wasmAddr: string,
33+
wasmSigner: KeyringPair,
34+
wasmGasLimit: GasLimit
35+
): Promise<Relayer> {
36+
const evmProvider = ethers.getDefaultProvider(evmProviderURL);
37+
const evm = new ethers.Contract(evmAddr, evmABI, evmProvider);
38+
39+
const wsProvider = new WsProvider(wasmProviderURL);
40+
const api = await ApiPromise.create({ provider: wsProvider });
41+
const wasm = new ContractPromise(api, wasmABI, wasmAddr);
42+
const weightV2 = api.registry.createType('WeightV2', wasmGasLimit) as WeightV2;
43+
44+
return new Relayer(evm, wasm, wasmSigner, weightV2);
45+
}
46+
47+
start() {
48+
this.evm.on("InitiateRequest", (id, name, recipient, yearsToRegister, value, ttl) => {
49+
console.log("New request:", Number(id), name, ttl);
50+
// TODO: Check ttl is valid
51+
this.executeRequest(Number(id), name, recipient, Number(yearsToRegister), value);
52+
})
53+
}
54+
55+
async executeRequest(
56+
id: number,
57+
name: string,
58+
recipient: string,
59+
yearsToRegister: number,
60+
maxFeesInEVM: number
61+
) {
62+
const maxFeesInWASM = this.valueEVM2WASM(maxFeesInEVM);
63+
64+
// TODO: first dry-run to save Tx which would fail
65+
66+
await this.wasm.tx.register(
67+
{
68+
gasLimit: this.wasmGasLimit
69+
},
70+
id,
71+
name,
72+
recipient,
73+
yearsToRegister,
74+
maxFeesInWASM,
75+
)
76+
.signAndSend(this.wasmSigner, ({ events = [], status }) => {
77+
if (status.isFinalized) {
78+
let successEventRecord = events.find((eventRecord) => {
79+
const isContractEvent = this.wasm.api.events.contracts.ContractEmitted.is;
80+
const verifyEventEmitter = (addr: any) => eventRecord.event.data.at(0)?.eq(addr);
81+
82+
const successEventExists = (eventRecord: any, id: number) => {
83+
const decoded = this.wasm.abi.decodeEvent(eventRecord);
84+
const emittedID = Number(decoded.args[0]);
85+
return decoded.event.identifier === "wasm::registration_proxy::Success" &&
86+
emittedID === id;
87+
};
88+
89+
return isContractEvent(eventRecord.event) &&
90+
verifyEventEmitter(this.wasm.address) &&
91+
successEventExists(eventRecord, id);
92+
});
93+
94+
if (successEventRecord === undefined) {
95+
// Failure
96+
console.log("Failed to register")
97+
} else {
98+
// Success
99+
const decoded = this.wasm.abi.decodeEvent(successEventRecord);
100+
const priceInWASM = Number(decoded.args[1]);
101+
console.log("Registered successfully with price:", priceInWASM);
102+
}
103+
}
104+
});
105+
}
106+
107+
private valueEVM2WASM(valueInEVM: number) {
108+
// TODO: set value converter properly
109+
return valueInEVM + 10000000000000;
110+
}
111+
}

0 commit comments

Comments
 (0)