Skip to content

Commit

Permalink
feat: add tx signing support for dymension
Browse files Browse the repository at this point in the history
  • Loading branch information
AaronCQL committed Feb 8, 2024
1 parent 1aeabd2 commit 79e3f27
Show file tree
Hide file tree
Showing 13 changed files with 63 additions and 17 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## `v0.0.55`

### Features

- Added tx signing support for Dymension chain

## `v0.0.54`

### Fixes
Expand Down
9 changes: 8 additions & 1 deletion examples/solid-vite/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import {
KeplrController,
LeapController,
MetamaskInjectiveController,
StationController,
NinjiController,
StationController,
UnsignedTx,
WalletController,
WalletName,
Expand All @@ -32,6 +32,7 @@ const CHAINS: Record<string, string> = {
"migaloo-1": "Migaloo",
"injective-1": "Injective",
"pacific-1": "Sei",
"dymension_1100-1": "Dymension",
};
const WALLETS: Record<WalletName, string> = {
[WalletName.KEPLR]: "Keplr",
Expand Down Expand Up @@ -76,6 +77,8 @@ function getRpc(chain: string): string {
return "https://injective-rpc.polkachu.com";
case "pacific-1":
return "https://rpc-sei-ia.cosmosia.notional.ventures";
case "dymension_1100-1":
return "https://rpc.dymension.nodestake.org";
default:
throw new Error("Unknown chain");
}
Expand All @@ -101,6 +104,8 @@ function getGasPrice(chain: string): { amount: string; denom: string } {
return { amount: "500000000", denom: getDenom(chain) };
case "pacific-1":
return { amount: "0.1", denom: getDenom(chain) };
case "dymension_1100-1":
return { amount: "20000000000", denom: getDenom(chain) };
default:
throw new Error("Unknown chain");
}
Expand All @@ -125,6 +130,8 @@ function getDenom(chain: string): string {
return "inj";
case "pacific-1":
return "usei";
case "dymension_1100-1":
return "adym";
default:
throw new Error("Unknown chain");
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cosmes",
"version": "0.0.54",
"version": "0.0.55",
"private": false,
"packageManager": "[email protected]",
"sideEffects": false,
Expand Down
16 changes: 13 additions & 3 deletions src/client/models/Secp256k1PubKey.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,38 @@
import { PlainMessage } from "@bufbuild/protobuf";
import { base64 } from "cosmes/codec";
import {
EthermintCryptoV1Ethsecp256k1PubKey as ProtoEthermintSecp256k1PubKey,
InjectiveCryptoV1beta1Ethsecp256k1PubKey as ProtoInjectiveSecp256k1PubKey,
CosmosCryptoSecp256k1PubKey as ProtoSecp256k1PubKey,
} from "cosmes/protobufs";

import { DeepPrettify } from "../../typeutils/prettify";
import { Adapter } from "./Adapter";

type Data = DeepPrettify<PlainMessage<ProtoSecp256k1PubKey>>;
type Data = DeepPrettify<
{
chainId?: string | undefined;
} & PlainMessage<ProtoSecp256k1PubKey>
>;

export class Secp256k1PubKey implements Adapter {
private readonly data: Data;
private readonly type: string;

constructor(data: Data) {
this.data = data;
this.type = data.chainId?.split(/[-_]/, 2).at(0) ?? "";
}

public toProto(isInjective = false) {
return isInjective
public toProto() {
return this.type === "injective"
? new ProtoInjectiveSecp256k1PubKey(this.data)
: this.type === "dymension" || this.type === "evmos"
? new ProtoEthermintSecp256k1PubKey(this.data)
: new ProtoSecp256k1PubKey(this.data);
}

// TODO: needs to be updated to include injective/dymension support
public toAmino() {
return {
type: "tendermint/PubKeySecp256k1",
Expand Down
5 changes: 1 addition & 4 deletions src/client/models/Tx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,7 @@ export class Tx {
mode: ProtoSignMode
): PlainMessage<ProtoSignerInfo> {
return {
publicKey: toAny(
// TODO: Injective's chain ID might change in the future
this.data.pubKey.toProto(this.data.chainId.startsWith("injective-"))
),
publicKey: toAny(this.data.pubKey.toProto()),
sequence: sequence,
modeInfo: {
sum: {
Expand Down
1 change: 1 addition & 0 deletions src/wallet/wallets/compass/CompassController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export class CompassController extends WalletController {
for (const { chainId, rpc, gasPrice } of Object.values(chains)) {
const { bech32Address, pubKey, isNanoLedger } = await ext.getKey(chainId);
const key = new Secp256k1PubKey({
chainId,
key: pubKey,
});
wallets.set(
Expand Down
2 changes: 2 additions & 0 deletions src/wallet/wallets/cosmostation/CosmostationController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export class CosmostationController extends WalletController {
const { chainId, rpc, gasPrice } = chains[i];
const { pubkey, address } = await this.wc.getAccount(chainId);
const key = new Secp256k1PubKey({
chainId,
key: base64.decode(pubkey),
});
wallets.set(
Expand Down Expand Up @@ -67,6 +68,7 @@ export class CosmostationController extends WalletController {
for (const { chainId, rpc, gasPrice } of Object.values(chains)) {
const { bech32Address, pubKey, isNanoLedger } = await ext.getKey(chainId);
const key = new Secp256k1PubKey({
chainId,
key: pubKey,
});
wallets.set(
Expand Down
2 changes: 2 additions & 0 deletions src/wallet/wallets/keplr/KeplrController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export class KeplrController extends WalletController {
const { pubkey, address } = await this.wc.getAccount(chainId);
const key = new Secp256k1PubKey({
key: base64.decode(pubkey),
chainId,
});
wallets.set(
chainId,
Expand Down Expand Up @@ -68,6 +69,7 @@ export class KeplrController extends WalletController {
const { bech32Address, pubKey, isNanoLedger } = await ext.getKey(chainId);
const key = new Secp256k1PubKey({
key: pubKey,
chainId,
});
wallets.set(
chainId,
Expand Down
2 changes: 2 additions & 0 deletions src/wallet/wallets/leap/LeapController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export class LeapController extends WalletController {
const { chainId, rpc, gasPrice } = chains[i];
const { pubkey, address } = await this.wc.getAccount(chainId);
const key = new Secp256k1PubKey({
chainId,
key: base64.decode(pubkey),
});
wallets.set(
Expand Down Expand Up @@ -66,6 +67,7 @@ export class LeapController extends WalletController {
for (const { chainId, rpc, gasPrice } of Object.values(chains)) {
const { bech32Address, pubKey, isNanoLedger } = await ext.getKey(chainId);
const key = new Secp256k1PubKey({
chainId,
key: pubKey,
});
wallets.set(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,13 @@ export class MetamaskInjectiveController extends WalletController {
const injAddress = translateEthToBech32Address(ethAddress, "inj");

const [chain] = chains;
const pubKey = await this.getPubKey(ext, chain.rpc, ethAddress, injAddress);
const pubKey = await this.getPubKey(
ext,
chain.chainId,
chain.rpc,
ethAddress,
injAddress
);
const wallets = new Map<T, ConnectedWallet>();
wallets.set(
chain.chainId,
Expand Down Expand Up @@ -86,6 +92,7 @@ export class MetamaskInjectiveController extends WalletController {

private async getPubKey(
ext: Ethereum,
chainId: string,
rpc: string,
ethAddress: string,
injAddress: string
Expand All @@ -98,6 +105,7 @@ export class MetamaskInjectiveController extends WalletController {
const { pubKey } = toBaseAccount(account);
if (pubKey) {
return new Secp256k1PubKey({
chainId,
key: CosmosCryptoSecp256k1PubKey.fromBinary(pubKey.value).key,
});
}
Expand All @@ -116,6 +124,7 @@ export class MetamaskInjectiveController extends WalletController {
throw new Error("Failed to retrieve pubic key");
}
return new Secp256k1PubKey({
chainId,
key: recoverPubKeyFromEthSignature(message, ethhex.decode(signature)),
});
}
Expand Down
12 changes: 8 additions & 4 deletions src/wallet/wallets/mnemonic/MnemonicWallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,10 @@ export class MnemonicWallet extends ConnectedWallet {
coinType,
index,
});
const keyType = chainId.startsWith("injective-")
? "ethsecp256k1"
: "secp256k1";
const keyType =
chainId.startsWith("injective") || chainId.startsWith("dymension")
? "ethsecp256k1"
: "secp256k1";
const address = resolveBech32Address(publicKey, bech32Prefix, keyType);
super(
// We typecast here instead of adding "mnemonic" to `WalletName` and
Expand All @@ -103,7 +104,10 @@ export class MnemonicWallet extends ConnectedWallet {
"mnemonic" as WalletName,
"mnemonic" as WalletType,
chainId,
new Secp256k1PubKey({ key: publicKey }),
new Secp256k1PubKey({
chainId,
key: publicKey,
}),
address,
rpc,
gasPrice
Expand Down
1 change: 1 addition & 0 deletions src/wallet/wallets/ninji/NinjiController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export class NinjiController extends WalletController {
for (const { chainId, rpc, gasPrice } of Object.values(chains)) {
const { bech32Address, pubKey, isNanoLedger } = await ext.getKey(chainId);
const key = new Secp256k1PubKey({
chainId,
key: pubKey,
});
wallets.set(
Expand Down
11 changes: 8 additions & 3 deletions src/wallet/wallets/station/StationController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export class StationController extends WalletController {
const address = wc.accounts[i];
// Since Station's WalletConnect doesn't support getting pub keys,
// we need to query the account to get it.
const key = await this.getPubKey(rpc, address);
const key = await this.getPubKey(chainId, rpc, address);
wallets.set(
chainId,
new StationWalletConnectV1(wc, chainId, key, address, rpc, gasPrice)
Expand Down Expand Up @@ -86,9 +86,12 @@ export class StationController extends WalletController {
}
const coinType = TERRA_CHAINS.includes(chainId) ? "330" : "118";
const key = pubkey
? new Secp256k1PubKey({ key: base64.decode(pubkey[coinType]) })
? new Secp256k1PubKey({
chainId,
key: base64.decode(pubkey[coinType]),
})
: // Legacy support for older versions of Station that don't return pubkey
await this.getPubKey(rpc, address);
await this.getPubKey(chainId, rpc, address);
wallets.set(
chainId,
new StationExtension(ext, chainId, key, address, rpc, gasPrice)
Expand All @@ -105,6 +108,7 @@ export class StationController extends WalletController {
}

private async getPubKey(
chainId: string,
rpc: string,
address: string
): Promise<Secp256k1PubKey> {
Expand All @@ -115,6 +119,7 @@ export class StationController extends WalletController {
}
// TODO: handle other key types (?)
return new Secp256k1PubKey({
chainId,
key: CosmosCryptoSecp256k1PubKey.fromBinary(pubKey.value).key,
});
}
Expand Down

0 comments on commit 79e3f27

Please sign in to comment.