Skip to content

Commit

Permalink
Merge pull request #79 from hyperweb-io/inj-config
Browse files Browse the repository at this point in the history
Inj config

e2e tested locally and success
  • Loading branch information
Zetazzz authored Jan 23, 2025
2 parents 352f0c3 + ed7d51b commit b944c9f
Show file tree
Hide file tree
Showing 16 changed files with 139 additions and 326 deletions.
32 changes: 21 additions & 11 deletions networks/cosmos/src/base/base-signer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ import { BaseCosmosTxBuilder } from './tx-builder';
* * @template TArgs The type of the args.
*/
export abstract class CosmosDocSigner<TDoc, TArgs = unknown> extends BaseSigner
implements IDocSigner<TDoc, TArgs, SignDocResponse<TDoc>>
{
implements IDocSigner<TDoc, TArgs, SignDocResponse<TDoc>> {
constructor(auth: Auth, config: SignerConfig) {
super(auth, config);

Expand Down Expand Up @@ -84,8 +83,7 @@ implements IDocSigner<TDoc, TArgs, SignDocResponse<TDoc>>
*/
export abstract class CosmosBaseSigner<SignDoc>
extends CosmosDocSigner<SignDoc>
implements UniCosmosBaseSigner<SignDoc>
{
implements UniCosmosBaseSigner<SignDoc> {
/**
* QueryClient for querying chain data.
*/
Expand Down Expand Up @@ -211,9 +209,21 @@ export abstract class CosmosBaseSigner<SignDoc>
}

/**
* abstract method to get the account of the current signer
* get account by account creator
*/
abstract getAccount(): Promise<IAccount>;
async getAccount() {
const opts = this.config as SignerOptions;

if (opts.createAccount) {
return new opts.createAccount(
await this.getPrefix(),
this.auth,
this.config.publicKey.isCompressed
);
} else {
throw new Error('No account creator is provided, or you can try to override the method `getAccount`');
}
}

/**
* set the endpoint of the queryClient
Expand Down Expand Up @@ -243,10 +253,10 @@ export abstract class CosmosBaseSigner<SignDoc>
: {
type: 'absolute',
value:
timeoutHeight.type === 'absolute'
? timeoutHeight.value
: (await this.queryClient.getLatestBlockHeight()) +
timeoutHeight.value,
timeoutHeight.type === 'absolute'
? timeoutHeight.value
: (await this.queryClient.getLatestBlockHeight()) +
timeoutHeight.value,
};
}

Expand Down Expand Up @@ -317,7 +327,7 @@ export abstract class CosmosBaseSigner<SignDoc>
const { signerInfo } = await this.txBuilder.buildSignerInfo(
this.encodedPublicKey,
options?.sequence ??
(await this.queryClient.getSequence(await this.getAddress())),
(await this.queryClient.getSequence(await this.getAddress())),
options?.signMode ?? SignMode.SIGN_MODE_DIRECT
);

Expand Down
11 changes: 10 additions & 1 deletion networks/cosmos/src/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ import { bytes as assertBytes } from '@noble/hashes/_assert';
import { ripemd160 } from '@noble/hashes/ripemd160';
import { sha256 } from '@noble/hashes/sha256';

import { EncodedMessage, FeeOptions, SignerOptions } from './types';
import { CosmosAccount, EncodedMessage, FeeOptions, SignerOptions } from './types';
import { toDecoder } from './utils';
import { Secp256k1Auth } from '@interchainjs/auth/secp256k1';
import { WalletOptions } from './types/wallet';

export const defaultBroadcastOptions: BroadcastOptions = {
checkTx: true,
Expand Down Expand Up @@ -92,6 +94,13 @@ export const defaultAccountParser = (
export const defaultSignerOptions: Required<SignerOptions> = {
...defaultSignerConfig,
parseAccount: defaultAccountParser,
createAccount: CosmosAccount,
encodePublicKey: defaultPublicKeyEncoder,
prefix: undefined,
};

export const defaultWalletOptions: WalletOptions = {
bip39Password: undefined,
createAuthsFromMnemonic: Secp256k1Auth.fromMnemonic,
signerConfig: defaultSignerOptions,
}
11 changes: 0 additions & 11 deletions networks/cosmos/src/signers/amino.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,17 +109,6 @@ export class AminoSigner
return new AminoTxBuilder(new BaseCosmosTxBuilderContext(this));
}

/**
* get account
*/
async getAccount() {
return new CosmosAccount(
await this.getPrefix(),
this.auth,
this.config.publicKey.isCompressed
);
}

/**
* create AminoSigner from wallet.
* if there're multiple accounts in the wallet, it will return the first one by default.
Expand Down
11 changes: 0 additions & 11 deletions networks/cosmos/src/signers/direct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,6 @@ export class DirectSignerBase extends CosmosBaseSigner<CosmosDirectDoc> {
super(auth, encoders, endpoint, options);
}

/**
* Get account from the signer.
*/
async getAccount() {
return new CosmosAccount(
await this.getPrefix(),
this.auth,
this.config.publicKey.isCompressed
);
}

getTxBuilder(): BaseCosmosTxBuilder<CosmosDirectDoc> {
return new DirectTxBuilder(new BaseCosmosTxBuilderContext(this));
}
Expand Down
18 changes: 7 additions & 11 deletions networks/cosmos/src/signing-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import {
import {
DeliverTxResponse,
EncodeObject,
SignerOptions,
SigningOptions,
} from './types/signing-client';

/**
Expand All @@ -40,7 +40,7 @@ import {
export class SigningClient {
readonly client: QueryClient | null | undefined;
readonly offlineSigner: ICosmosGenericOfflineSigner;
readonly options: SignerOptions;
readonly options: SigningOptions;

readonly signers: Record<string, DirectSigner | AminoSigner> = {};

Expand All @@ -54,7 +54,7 @@ export class SigningClient {
constructor(
client: QueryClient | null | undefined,
offlineSigner: ICosmosGenericOfflineSigner,
options: SignerOptions = {}
options: SigningOptions = {}
) {
this.client = client;

Expand All @@ -75,10 +75,10 @@ export class SigningClient {
static async connectWithSigner(
endpoint: string | HttpEndpoint,
signer: ICosmosGenericOfflineSigner,
options: SignerOptions = {}
options: SigningOptions = {}
): Promise<SigningClient> {
const signingClient = new SigningClient(
new RpcClient(endpoint, options.prefix),
new RpcClient(endpoint, options.signerOptions?.prefix),
signer,
options
);
Expand All @@ -97,9 +97,7 @@ export class SigningClient {
this.offlineSigner as IDirectGenericOfflineSigner,
this.encoders,
this.endpoint,
{
prefix: this.options.prefix,
}
this.options.signerOptions
)
break;

Expand All @@ -109,9 +107,7 @@ export class SigningClient {
this.encoders,
this.converters,
this.endpoint,
{
prefix: this.options.prefix,
}
this.options.signerOptions
);
break;

Expand Down
16 changes: 12 additions & 4 deletions networks/cosmos/src/types/signer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ import {
StdFee,
StdSignDoc,
UniSigner,
IApiClient
IApiClient,
Auth
} from '@interchainjs/types';
import { Event } from '@interchainjs/types';
import { AccountBase } from '@interchainjs/types/account';
Expand All @@ -38,6 +39,13 @@ export interface SignerOptions extends Partial<SignerConfig> {
*/
parseAccount?: (encodedAccount: EncodedMessage) => BaseAccount;

/**
* the constructor for creating account
*/
createAccount?: new (prefix: string,
auth: Auth,
isPublicKeyCompressed: boolean) => IAccount;

/**
* encode public key to encoded message
*/
Expand Down Expand Up @@ -188,7 +196,7 @@ export type TxOptions = {
/**
* Query client ops for cosmos chains
*/
export interface QueryClient extends IApiClient<Uint8Array, BroadcastResponse, BroadcastOptions>{
export interface QueryClient extends IApiClient<Uint8Array, BroadcastResponse, BroadcastOptions> {
readonly endpoint: string | HttpEndpoint;
getChainId: () => Promise<string>;
getAccountNumber: (address: string) => Promise<bigint>;
Expand Down Expand Up @@ -275,7 +283,7 @@ export type Bech32Address = string;
/**
* Base signer for cosmos chains
*/
export interface ICosmosAccount extends IAccount {}
export interface ICosmosAccount extends IAccount { }

/**
* Check if instance is cosmos account
Expand All @@ -289,7 +297,7 @@ export function isICosmosAccount(
/**
* Cosmos account implementation
*/
export class CosmosAccount extends AccountBase {
export class CosmosAccount extends AccountBase {
getAddressByPubKey() {
return Key.from(ripemd160(sha256(this.publicKey.value))).toBech32(
this.prefix
Expand Down
6 changes: 3 additions & 3 deletions networks/cosmos/src/types/signing-client.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AminoConverter, Message } from '../types/signer';
import { AminoConverter, Message, SignerOptions } from '../types/signer';
import { BroadcastOptions, Price } from '@interchainjs/types';
import { Event, TelescopeGeneratedType } from '@interchainjs/types';

Expand All @@ -8,12 +8,12 @@ export type TypeUrl = string;

export type Registry = Array<[TypeUrl, TelescopeGeneratedType<any, any, any>]>;

export interface SignerOptions {
export interface SigningOptions {
registry?: Registry;
aminoConverters?: Record<TypeUrl, AminoConverter>;
gasPrice?: Price | string;
prefix?: string;
broadcast?: BroadcastOptions;
signerOptions?: SignerOptions;
}

export interface SignerData {
Expand Down
7 changes: 6 additions & 1 deletion networks/cosmos/src/types/wallet.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AccountData, IGenericOfflineSignArgs, IGenericOfflineSigner, SIGN_MODE, SignerConfig } from '@interchainjs/types';
import { AccountData, Auth, AuthOptions, IGenericOfflineSignArgs, IGenericOfflineSigner, SIGN_MODE, SignerConfig } from '@interchainjs/types';

import { CosmosAminoDoc, CosmosDirectDoc } from './signer';

Expand All @@ -7,6 +7,11 @@ import { CosmosAminoDoc, CosmosDirectDoc } from './signer';
*/
export interface WalletOptions {
bip39Password?: string;
createAuthsFromMnemonic?: (
mnemonic: string,
hdPaths: string[],
options?: AuthOptions
) => Auth[];
signerConfig: SignerConfig;
}

Expand Down
55 changes: 38 additions & 17 deletions networks/cosmos/src/wallets/secp256k1hd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import { Secp256k1Auth } from '@interchainjs/auth/secp256k1';
import { AddrDerivation, Auth, SignerConfig, SIGN_MODE, IGenericOfflineSignArgs } from '@interchainjs/types';

import { AminoDocSigner } from '../signers/amino';
import { defaultSignerConfig } from '../defaults';
import { defaultSignerConfig, defaultWalletOptions } from '../defaults';
import { DirectDocSigner } from '../signers/direct';
import {
CosmosAccount,
CosmosAminoDoc,
CosmosDirectDoc,
ICosmosAccount,
ICosmosWallet,
SignerOptions,
} from '../types';
import {
AminoSignResponse,
Expand All @@ -21,11 +22,7 @@ import {
} from '../types/wallet';
import { BaseCosmosWallet } from '../base/base-wallet';

/**
* Cosmos HD Wallet for secp256k1
*/
export class Secp256k1HDWallet extends BaseCosmosWallet<DirectDocSigner, AminoDocSigner>
{
export class HDWallet extends BaseCosmosWallet<DirectDocSigner, AminoDocSigner> {
constructor(
accounts: ICosmosAccount[],
options: SignerConfig
Expand All @@ -43,28 +40,52 @@ export class Secp256k1HDWallet extends BaseCosmosWallet<DirectDocSigner, AminoDo
}

/**
* Create a new HD wallet from mnemonic
* @param mnemonic
* @param derivations infos for derivate addresses
* @param options wallet options
* @returns HD wallet
*/
* Create a new HD wallet from mnemonic
* @param mnemonic
* @param derivations infos for derivate addresses
* @param options wallet options
* @returns HD wallet
*/
static fromMnemonic(
mnemonic: string,
derivations: AddrDerivation[],
options?: WalletOptions
) {
const walletOpts = { ...defaultWalletOptions, ...options };

const hdPaths = derivations.map((derivation) => derivation.hdPath);

const auths: Auth[] = Secp256k1Auth.fromMnemonic(mnemonic, hdPaths, {
bip39Password: options?.bip39Password,
});
let auths: Auth[];

if (walletOpts?.createAuthsFromMnemonic) {
auths = walletOpts.createAuthsFromMnemonic(mnemonic, hdPaths, {
bip39Password: walletOpts?.bip39Password,
});
} else {
auths = Secp256k1Auth.fromMnemonic(mnemonic, hdPaths, {
bip39Password: walletOpts?.bip39Password,
});
}

const accounts = auths.map((auth, i) => {
const derivation = derivations[i];
return new CosmosAccount(derivation.prefix, auth);

const opts = walletOpts.signerConfig as SignerOptions;

if (opts?.createAccount) {
return new opts.createAccount(derivation.prefix, auth, opts.publicKey.isCompressed);
} else {
return new CosmosAccount(derivation.prefix, auth);
}
});

return new Secp256k1HDWallet(accounts, options?.signerConfig);
return new HDWallet(accounts, walletOpts?.signerConfig);
}
}

/**
* Cosmos HD Wallet for secp256k1
*/
export class Secp256k1HDWallet extends HDWallet {

}
Loading

0 comments on commit b944c9f

Please sign in to comment.