Skip to content

Commit a26aa9b

Browse files
authored
Merge pull request #157 from hyperweb-io/major-refactor-unisigner
Major refactor unisigner
2 parents 4743188 + e33ac85 commit a26aa9b

File tree

509 files changed

+31760
-11667
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

509 files changed

+31760
-11667
lines changed

.github/workflows/e2e-tests.yaml

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,34 +10,6 @@ on:
1010
workflow_dispatch:
1111

1212
jobs:
13-
interchainjs:
14-
runs-on: ubuntu-latest
15-
16-
steps:
17-
- name: Checkout Repository 📝
18-
uses: actions/checkout@v4
19-
20-
- name: Setup Node.js
21-
uses: actions/setup-node@v4
22-
with:
23-
node-version: "20.x"
24-
cache: "yarn"
25-
26-
- name: Install Dependencies
27-
run: yarn install --frozen-lockfile
28-
29-
- name: Build Project
30-
run: yarn build
31-
32-
- name: Set Up Starship Infrastructure
33-
id: starship-infra
34-
uses: hyperweb-io/[email protected]
35-
with:
36-
config: libs/interchainjs/starship/configs/config.workflow.yaml
37-
38-
- name: Run E2E Tests
39-
run: cd ./libs/interchainjs && yarn starship:test
40-
4113
networks-cosmos:
4214
runs-on: ubuntu-latest
4315

README.md

Lines changed: 79 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -130,80 +130,77 @@ npm i @interchainjs/cosmos
130130

131131
## Quick Start
132132

133-
Get a signing client to send the trasactions:
133+
### Using Signers Directly
134134

135-
```ts
136-
import { SigningClient as CosmosSigningClient } from "@interchainjs/cosmos";
135+
Create and use signers for transaction signing and broadcasting:
137136

138-
const signingClient = await CosmosSigningClient.connectWithSigner(
139-
await getRpcEndpoint(),
140-
new DirectGenericOfflineSigner(directSigner),
137+
```typescript
138+
import { DirectSigner } from '@interchainjs/cosmos';
139+
import { Secp256k1HDWallet } from '@interchainjs/cosmos';
140+
import { HDPath } from '@interchainjs/types';
141+
142+
// Create wallet from mnemonic
143+
const wallet = await Secp256k1HDWallet.fromMnemonic(
144+
"your twelve word mnemonic phrase here",
141145
{
142-
registry: [
143-
// as many as possible encoders registered here.
144-
MsgDelegate,
145-
MsgSend,
146-
],
147-
broadcast: {
148-
checkTx: true,
149-
},
146+
derivations: [{
147+
prefix: "cosmos",
148+
hdPath: HDPath.cosmos(0, 0, 0).toString(), // m/44'/118'/0'/0/0
149+
}]
150150
}
151151
);
152152

153-
// sign and broadcast
154-
const result = await signingClient.signAndBroadcast(<MESSAGE>[]);
155-
console.log(result.hash); // the hash of TxRaw
153+
// Create signer
154+
const signer = new DirectSigner(wallet, {
155+
chainId: 'cosmoshub-4',
156+
queryClient: queryClient,
157+
addressPrefix: 'cosmos'
158+
});
159+
160+
// Sign and broadcast transaction
161+
const result = await signer.signAndBroadcast({
162+
messages: [{
163+
typeUrl: '/cosmos.bank.v1beta1.MsgSend',
164+
value: {
165+
fromAddress: 'cosmos1...',
166+
toAddress: 'cosmos1...',
167+
amount: [{ denom: 'uatom', amount: '1000000' }]
168+
}
169+
}],
170+
fee: {
171+
amount: [{ denom: 'uatom', amount: '5000' }],
172+
gas: '200000'
173+
},
174+
memo: 'Transfer via InterchainJS'
175+
});
176+
177+
console.log('Transaction hash:', result.transactionHash);
156178
```
157179

158-
Use the tree shakable helper functions provided by interchainjs or generated by telescope for query or send the transctions:
180+
### Using with External Wallets
159181

160-
```ts
161-
import { SigningClient as CosmosSigningClient } from "@interchainjs/cosmos/signing-client";
162-
import { getBalance } from "interchainjs/cosmos/bank/v1beta1/query.rpc.func";
163-
import { submitProposal } from "interchainjs/cosmos/gov/v1beta1/tx.rpc.func";
182+
For integration with browser wallets like Keplr:
164183

165-
// query to get balance
166-
const { balance } = await getBalance(await getRpcEndpoint(), {
167-
address: directAddress,
168-
denom,
169-
});
184+
```typescript
185+
import { DirectSigner } from '@interchainjs/cosmos';
170186

171-
const signingClient = await CosmosSigningClient.connectWithSigner(
172-
await getRpcEndpoint(),
173-
new DirectGenericOfflineSigner(directSigner),
174-
{
175-
// no registry needed here anymore
176-
// registry: [
177-
// ],
178-
broadcast: {
179-
checkTx: true,
180-
},
181-
}
182-
);
187+
// Get offline signer from Keplr
188+
await window.keplr.enable(chainId);
189+
const offlineSigner = window.keplr.getOfflineSigner(chainId);
183190

184-
// Necessary typeurl and codecs will be registered automatically in the helper functions. Meaning users don't have to register them all at once.
185-
const result = await submitProposal(
186-
signingClient,
187-
directAddress,
188-
{
189-
proposer: directAddress,
190-
initialDeposit: [
191-
{
192-
amount: "1000000",
193-
denom: denom,
194-
},
195-
],
196-
content: {
197-
typeUrl: "/cosmos.gov.v1beta1.TextProposal",
198-
value: TextProposal.encode(contentMsg).finish(),
199-
},
200-
},
201-
fee,
202-
"submit proposal"
203-
);
204-
console.log(result.hash); // the hash of TxRaw
205-
```
191+
// Create signer with offline signer
192+
const signer = new DirectSigner(offlineSigner, {
193+
chainId: 'cosmoshub-4',
194+
queryClient: queryClient,
195+
addressPrefix: 'cosmos'
196+
});
206197

198+
// Use the same signing interface
199+
const result = await signer.signAndBroadcast({
200+
messages: [/* your messages */],
201+
fee: { amount: [{ denom: 'uatom', amount: '5000' }], gas: '200000' }
202+
});
203+
```
207204

208205
### Quick Setup with create-interchain-app
209206

@@ -247,6 +244,27 @@ Then an authz example website will be created and users can take a look how sign
247244

248245
---
249246

247+
## Developer Documentation
248+
249+
### For Contributors and Network Implementers
250+
251+
- **[Network Implementation Guide](./docs/advanced/network-implementation-guide.md)** - Comprehensive guide for implementing new blockchain network support
252+
- **[Workflow Builder and Plugins Guide](./docs/advanced/workflow-builder-and-plugins.md)** - Plugin-based transaction workflow architecture
253+
- **[Auth vs. Wallet vs. Signer](./docs/advanced/auth-wallet-signer.md)** - Understanding the three-layer architecture
254+
- **[Tutorial](./docs/advanced/tutorial.md)** - Using and extending signers in the InterchainJS ecosystem
255+
256+
### Architecture and Design
257+
258+
InterchainJS follows a modular, three-layer architecture that separates concerns and enables flexible blockchain integration:
259+
260+
1. **Auth Layer**: Cryptographic operations and key management
261+
2. **Wallet Layer**: Account management and address derivation
262+
3. **Signer Layer**: Transaction building, signing, and broadcasting
263+
264+
This separation allows for maximum flexibility while maintaining type safety and consistent interfaces across different blockchain networks.
265+
266+
---
267+
250268
## Interchain JavaScript Stack ⚛️
251269

252270
A unified toolkit for building applications and smart contracts in the Interchain ecosystem
Lines changed: 72 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,99 @@
11
# Auth vs. Wallet vs. Signer: A Comparison
22

3-
This document aims to provide an overview and comparison of `Auth`, `Wallet`, and `Signer`, three types commonly used for encryption and signing purposes in different networks. Each type serves a specific purpose and has its own characteristics and functionalities.
3+
This document provides an overview and comparison of `Auth`, `Wallet`, and `Signer`, three core abstractions used for cryptographic operations and transaction signing in the InterchainJS ecosystem. Each serves a specific purpose in the signing workflow and has distinct characteristics and functionalities.
44

55
```mermaid
66
graph LR
7-
subgraph AuthType[Auth]
8-
ByteAuth --> |privateKey| PrivateKey
9-
PrivateKey --> |sign| SignedTx
10-
OfflineSigner[Hide PrivateKey] --> DocAuth
11-
DocAuth --> |signDoc| SignedTx
7+
subgraph AuthLayer[Auth Layer]
8+
IWallet --> |getAccounts| IAccount[Account]
9+
IWallet --> |signByIndex| Signature
10+
OfflineSigner --> |signDirect/signAmino| SignedDoc
1211
end
1312
14-
Wallet --> |accounts| IAccount[Account]
15-
Wallet --> |toOfflineSigner| OfflineSigner
16-
17-
Signer --> |prefix| Prefix
18-
Signer --> |account| Account
19-
Signer --> |encoders| Encoder
20-
Signer --> |signAndBroadCast| SignAndBroadCast
13+
subgraph SignerLayer[Signer Layer]
14+
IUniSigner --> |getAccounts| AccountData
15+
IUniSigner --> |sign| ISigned
16+
IUniSigner --> |signAndBroadcast| BroadcastResponse
17+
IUniSigner --> |signArbitrary| ICryptoBytes
18+
end
2119
22-
Account --> |auth| Auth
20+
AuthLayer --> SignerLayer
21+
IAccount --> |address/publicKey| SignerLayer
2322
2423
```
2524

26-
## 1. Auth
25+
## 1. Auth Layer
26+
27+
The Auth layer provides the foundational cryptographic capabilities for account management and signing operations. It consists of two main abstractions:
28+
29+
### IWallet Interface
30+
31+
`IWallet` is the primary interface for managing cryptographic accounts and performing low-level signing operations:
32+
33+
- **Account Management**: Provides access to multiple accounts through `getAccounts()` and `getAccountByIndex()`
34+
- **Direct Signing**: Offers `signByIndex()` method to sign arbitrary binary data using a specific account
35+
- **Network Agnostic**: Designed to work across different blockchain networks with configurable address derivation strategies
36+
37+
### OfflineSigner Interface
38+
39+
`OfflineSigner` provides a secure way to sign transactions without exposing private keys:
40+
41+
- **External Wallet Integration**: Designed for integration with external wallets like Keplr, Leap, or hardware wallets
42+
- **Document Signing**: Supports both Direct (protobuf) and Amino (JSON) signing modes through `OfflineDirectSigner` and `OfflineAminoSigner`
43+
- **Privacy Preservation**: Keeps private keys secure within the external wallet while providing signing capabilities
44+
45+
## 2. Wallet Implementations
46+
47+
Wallet implementations provide concrete realizations of the `IWallet` interface, offering HD (Hierarchical Deterministic) key derivation and network-specific address generation:
48+
49+
### Secp256k1HDWallet
50+
51+
The primary wallet implementation for secp256k1 cryptography:
52+
53+
- **HD Key Derivation**: Supports BIP-32/BIP-44 hierarchical deterministic key derivation from mnemonic phrases
54+
- **Multi-Account Support**: Can manage multiple accounts with different derivation paths
55+
- **Network Compatibility**: Works across Cosmos, Ethereum, and Injective networks with appropriate address strategies
56+
- **Offline Signer Conversion**: Can be converted to `OfflineDirectSigner` or `OfflineAminoSigner` for external wallet compatibility
2757

28-
`Auth` is a common implementation of an encryption algorithm that can be utilized across different networks. It provides a signing method to sign binary data. The primary features and characteristics of `Auth` are as follows:
58+
### Network-Specific Variants
2959

30-
- **Encryption Algorithm**: `Auth` implements an encryption algorithm that is compatible and usable across various networks.
60+
- **Cosmos**: `Secp256k1HDWallet` with bech32 address encoding
61+
- **Ethereum**: `Secp256k1HDWallet` with keccak256 hashing and hex address format
62+
- **Injective**: `EthSecp256k1HDWallet` with Ethereum-style addresses but Cosmos transaction format
3163

32-
- **Signing Binary Data**: `Auth` offers a method to sign binary data, which can be used for verifying the integrity and authenticity of the data.
64+
## 3. Signer Layer
3365

34-
- **Network Agnostic**: Auth is designed to work with different networks, making it a versatile solution for encryption and signing needs.
66+
The Signer layer provides the highest-level abstraction for transaction signing and broadcasting, implementing the `IUniSigner` interface. Signers can be constructed from either `IWallet` implementations or `OfflineSigner` interfaces.
3567

36-
## 2. Wallet
68+
### IUniSigner Interface
3769

38-
`Wallet` is a wrapper built upon `Auth`, providing additional functionalities and convenience, particularly for Web3 usage. `Wallet` extends the capabilities of `Auth` and introduces the following aspects:
70+
The universal signer interface provides a consistent API across all blockchain networks:
3971

40-
- **Signing Network and Document**: In addition to signing binary data, `Wallet` provides a signing method specifically designed for signing network-related information and sign mode specified documents.
72+
- **Account Management**: `getAccounts()` returns account information including addresses and public keys
73+
- **Transaction Workflow**: `sign()` creates signed transactions, `broadcast()` submits them to the network, and `signAndBroadcast()` combines both operations
74+
- **Arbitrary Signing**: `signArbitrary()` signs raw binary data for authentication purposes
75+
- **Network Abstraction**: Generic type parameters allow network-specific customization while maintaining a unified interface
4176

42-
- **Web3 Integration**: `Wallet` is tailored for Web3 usage, making it compatible with blockchain and decentralized applications.
77+
### Network-Specific Implementations
4378

44-
- **Enhanced Functionality**: `Wallet` encompasses the features of `Auth` while incorporating additional functionalities to facilitate secure interactions with Web3 wallets.
79+
- **Cosmos Signers**: `DirectSigner` and `AminoSigner` for protobuf and JSON signing modes
80+
- **Ethereum Signers**: `LegacySigner` and `Eip1559Signer` for different transaction types
81+
- **Injective Signers**: Cosmos-compatible signers with Ethereum-style address derivation
4582

46-
## 3. Signer
83+
### Construction Patterns
4784

48-
`Signer` is a class that can be constructed from `Auth` or `Wallet`. It focuses on providing a signing method specifically for directly signing human-readable messages. Key aspects of `Signer` include:
85+
Signers can be constructed in multiple ways:
4986

50-
- **Signing Human-Readable Messages**: `Signer` offers a dedicated signing method for signing messages that are in a human-readable format, such as plain text or structured data.
87+
1. **From IWallet**: Direct construction with full private key access
88+
2. **From OfflineSigner**: Construction for external wallet integration
89+
3. **Configuration-based**: Using network-specific configuration objects
5190

52-
- **Flexible Construction**: `Signer` can be constructed using either `Auth` or `Wallet`, allowing users to choose their preferred underlying implementation based on their specific requirements.
91+
## Summary
5392

54-
- **Message-Level Security**: `Signer` emphasizes the signing of human-readable messages, making it suitable for use cases where secure communication and message integrity are essential.
93+
The three-layer architecture provides clear separation of concerns:
5594

56-
In summary, `Auth` serves as a fundamental implementation of an encryption algorithm, providing a signing method for binary data. `Wallet`, built upon `Auth`, extends its capabilities by introducing network and document-specific signing methods, tailored for Web3 usage. `Signer`, the top-level layer, contains the code for structured data signing and focuses on dedicated methods for directly signing human-readable messages, which offers flexibility and message-level security.
95+
- **Auth Layer**: Foundational cryptographic operations and account management
96+
- **Wallet Layer**: HD key derivation and network-specific address generation
97+
- **Signer Layer**: High-level transaction signing and broadcasting with network abstraction
5798

58-
The hierarchical relationship between `Auth`, `Wallet`, and `Signer` positions Auth as the foundation, Wallet as the middle layer, and Signer as the top layer with the highest-level functionality for structured data signing. However, the specific choice among `Auth`, `Wallet`, or `Signer` depends on specific requirements and use cases, ensuring the appropriate level of encryption, signing, and security for various network-related operations.
99+
This design allows developers to choose the appropriate abstraction level based on their security requirements, from low-level cryptographic control to high-level transaction management, while maintaining compatibility across different blockchain networks.

0 commit comments

Comments
 (0)