Skip to content

Commit cbb3c4a

Browse files
temp commit
1 parent 8ef2167 commit cbb3c4a

File tree

11 files changed

+296
-150
lines changed

11 files changed

+296
-150
lines changed

packages/core/src/types/cosmos.ts

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { AminoSignResponse, CosmosSignerConfig, DirectSignResponse } from "@interchainjs/cosmos";
2-
import { StdSignDoc } from "@interchainjs/types";
3-
import { WalletAccount, DirectSignDoc } from "./wallet";
1+
import { AminoSignResponse, CosmosSignerConfig, DirectSignResponse } from '@interchainjs/cosmos';
2+
3+
import { DirectSignDoc, WalletAccount } from './wallet';
44

55
export interface OfflineAminoSigner {
66
getAccounts: () => Promise<readonly WalletAccount[]>;
@@ -14,4 +14,71 @@ export interface OfflineDirectSigner {
1414

1515
export interface CosmosSigningOptions {
1616
cosmosSignerConfig: CosmosSignerConfig
17+
}
18+
19+
export interface Pubkey {
20+
type: string;
21+
value: string;
22+
}
23+
24+
export interface StdSignature {
25+
pub_key: Pubkey;
26+
signature: string;
27+
}
28+
29+
export interface TxRaw {
30+
bodyBytes: Uint8Array;
31+
authInfoBytes: Uint8Array;
32+
signatures: Uint8Array[];
33+
}
34+
export interface SignDoc {
35+
bodyBytes: Uint8Array;
36+
authInfoBytes: Uint8Array;
37+
chainId: string;
38+
accountNumber: bigint;
39+
}
40+
export interface Coin {
41+
denom: string;
42+
amount: string;
43+
}
44+
export interface StdFee {
45+
amount: Coin[];
46+
gas: string;
47+
granter?: string;
48+
payer?: string;
49+
}
50+
export interface AminoMessage {
51+
type: string;
52+
value: any;
53+
}
54+
export interface StdSignDoc {
55+
chain_id: string;
56+
account_number: string;
57+
sequence: string;
58+
fee: StdFee;
59+
msgs: AminoMessage[];
60+
memo: string;
61+
}
62+
export type TypeName = string;
63+
64+
export interface DirectSignResponse {
65+
/**
66+
* The sign doc that was signed.
67+
* This may be different from the input signDoc when the signer modifies it as part of the signing process.
68+
*/
69+
signed: SignDoc;
70+
/** Signature object with public key and signature */
71+
signature: StdSignature;
72+
}
73+
/**
74+
* Response from amino signing
75+
*/
76+
export interface AminoSignResponse {
77+
/**
78+
* The sign doc that was signed.
79+
* This may be different from the input signDoc when the signer modifies it as part of the signing process.
80+
*/
81+
signed: StdSignDoc;
82+
/** Signature object with public key and signature */
83+
signature: StdSignature;
1784
}

packages/core/src/wallets/solana-wallet.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import { Chain } from '@chain-registry/types';
2+
import { Transaction, TransactionSignature, VersionedTransaction } from '@solana/web3.js';
23

34
import { ISolanaWallet, SignType, Wallet, WalletAccount } from '../types';
4-
import { getClientFromExtension } from '../utils';
5-
import { BaseWallet } from './base-wallet';
6-
75
import { OfflineAminoSigner, OfflineDirectSigner } from '../types/cosmos';
8-
import { Transaction, TransactionSignature, VersionedTransaction } from '@solana/web3.js';
96
import { SolanaSignInData } from '../types/solana';
7+
import { getClientFromExtension } from '../utils';
8+
import { BaseWallet } from './base-wallet';
109

1110
function publicKeyToUint8Array(publicKey: any): Uint8Array {
1211
if (publicKey?.toBytes) return publicKey.toBytes();
@@ -26,13 +25,14 @@ export class SolanaWallet extends BaseWallet implements ISolanaWallet {
2625
super(info);
2726
}
2827
bindingEvent() {
29-
window.addEventListener(this.info.keystoreChange, () => {
28+
this.solana.on(this.info.keystoreChange, () => {
3029
this.events.emit('accountChanged', () => { });
3130
});
3231
}
3332
async init(): Promise<void> {
34-
this.bindingEvent();
33+
3534
this.solana = await getClientFromExtension(this.info.solanaKey);
35+
this.bindingEvent();
3636
}
3737

3838

packages/core/src/wallets/wc-wallets/wc-solana-wallet.ts

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import { WalletAccount } from "../../types";
2-
import { WalletConnectIcon } from "../../constant";
3-
import { ISolanaWallet } from "../../types/wallet-types";
4-
import { IWCCommon } from "./wc-common";
5-
import { Chain } from "@chain-registry/types";
6-
import UniversalProvider from "@walletconnect/universal-provider";
7-
import { BaseWallet } from "../base-wallet";
8-
import { WCWallet } from "./wc-wallet";
9-
import { SolanaWallet } from "../solana-wallet";
1+
import { Chain } from '@chain-registry/types';
2+
import { PublicKey } from '@solana/web3.js';
3+
import UniversalProvider from '@walletconnect/universal-provider';
4+
5+
import { WalletConnectIcon } from '../../constant';
6+
import { WalletAccount } from '../../types';
7+
import { SolanaWallet } from '../solana-wallet';
8+
import { IWCCommon } from './wc-common';
9+
import { WCWallet } from './wc-wallet';
1010

1111
export class WCSolanaWallet extends SolanaWallet implements IWCCommon {
1212
provider: UniversalProvider;
@@ -47,45 +47,47 @@ export class WCSolanaWallet extends SolanaWallet implements IWCCommon {
4747
return Promise.resolve();
4848
}
4949

50-
async connect(chainId: Chain["chainId"]): Promise<void> {
50+
async connect(chainId: Chain['chainId']): Promise<void> {
5151
return this.wcWallet.connect(chainId);
5252
}
5353

54-
async disconnect(chainId: Chain["chainId"]): Promise<void> {
54+
async disconnect(chainId: Chain['chainId']): Promise<void> {
5555
return this.wcWallet.disconnect();
5656
}
5757

58-
async getAccount(chainId: Chain["chainId"]): Promise<WalletAccount> {
58+
async getAccount(chainId: Chain['chainId']): Promise<WalletAccount> {
5959
if (!this.provider) {
6060
throw new Error('Provider not initialized');
6161
}
6262

63-
try {
64-
const accounts = await this.provider.request({
65-
method: 'solana_accounts',
66-
params: []
67-
}, `solana:${chainId}`) as string[];
63+
if (!this.provider.session) {
64+
throw new Error('Session not initialized');
65+
}
66+
6867

68+
const accounts = this.provider.session.namespaces.solana.accounts;
69+
if (accounts.length > 0) {
70+
// CAIP-10 format: solana:<chain_id>:<address>
71+
const account = accounts[0].split(':')[2]; // Extract the address part
72+
const publicKey = new PublicKey(account); // Validate Solana address
6973
return {
70-
address: accounts[0],
71-
algo: 'secp256k1', // Solana uses ed25519 but we'll use secp256k1 for compatibility
72-
pubkey: null,
74+
address: account,
75+
pubkey: publicKey.toBytes(),
76+
algo: 'secp256k1',
7377
username: '',
7478
isNanoLedger: null,
7579
isSmartContract: null
7680
};
77-
} catch (error) {
78-
console.log('get solana account error', error);
79-
throw error;
8081
}
82+
8183
}
8284

83-
async addSuggestChain(chainId: Chain["chainId"]): Promise<void> {
85+
async addSuggestChain(chainId: Chain['chainId']): Promise<void> {
8486
// Solana chain addition is typically handled by the wallet
85-
throw new Error("Method not implemented.");
87+
throw new Error('Method not implemented.');
8688
}
8789

88-
async getProvider(chainId: Chain["chainId"]): Promise<any> {
90+
async getProvider(chainId: Chain['chainId']): Promise<any> {
8991
return this.provider;
9092
}
9193

packages/core/src/wallets/wc-wallets/wc-wallet.ts

Lines changed: 14 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
import { Chain } from '@chain-registry/types';
2+
import type { StdSignature } from '@interchainjs/amino';
23
import { AminoSignResponse, DirectSignResponse, SignOptions } from '@interchainjs/cosmos';
34
import { StdSignDoc } from '@interchainjs/types';
45
import { PairingTypes, SessionTypes, SignClientTypes } from '@walletconnect/types';
56
import UniversalProvider, { ConnectParams, UniversalProviderOpts } from '@walletconnect/universal-provider';
67
import { fromByteArray, toByteArray } from 'base64-js';
7-
8-
9-
import type { Algo, StdSignature } from '@interchainjs/amino';
10-
import { MultiChainWallet } from '../multichain-wallet';
118
import { BroadcastMode } from 'interchainjs';
9+
1210
import { WalletConnectIcon } from '../../constant';
13-
import { WalletAccount, Wallet, SignType, DirectSignDoc, WCDirectSignResponse, WcEventTypes, WcProviderEventType } from '../../types';
11+
import { DirectSignDoc, SignType, Wallet, WalletAccount, WCDirectSignResponse, WcEventTypes, WcProviderEventType } from '../../types';
12+
import { MultiChainWallet } from '../multichain-wallet';
1413
import { isWCCommon } from './wc-common';
1514

1615

@@ -83,7 +82,7 @@ export class WCWallet extends MultiChainWallet {
8382
wallet.setWCProvider(this.provider);
8483
wallet.setWCWallet(this);
8584
}
86-
wallet.info = this.info
85+
wallet.info = this.info;
8786
wallet.chainMap = this.chainMap;
8887
});
8988

@@ -159,13 +158,8 @@ export class WCWallet extends MultiChainWallet {
159158
if (solanaChainNS.length) {
160159
connectParam.namespaces.solana = {
161160
methods: [
162-
'solana_accounts',
163161
'solana_signTransaction',
164-
'solana_signAllTransactions',
165-
'solana_signAndSendTransaction',
166-
'solana_signAndSendAllTransactions',
167162
'solana_signMessage',
168-
'solana_signIn',
169163
],
170164
chains: solanaChainNS,
171165
events: []
@@ -227,43 +221,12 @@ export class WCWallet extends MultiChainWallet {
227221
}
228222

229223
async getAccount(chainId: Chain['chainId']): Promise<WalletAccount> {
230-
231-
if (this.accountToRestore) {
232-
return this.accountToRestore;
233-
}
234-
235-
const account = await this.getCosmosAccount(chainId);
236-
237-
return {
238-
address: account.address,
239-
algo: 'secp256k1',
240-
pubkey: toByteArray(account.pubkey),
241-
username: '',
242-
isNanoLedger: null,
243-
isSmartContract: null
244-
};
224+
const chain = this.getChainById(chainId);
225+
const wallet = this.getWalletByChainType(chain.chainType);
226+
return wallet.getAccount(chainId);
245227
}
246228

247-
async getCosmosAccount(chainId: string): Promise<{ address: string, algo: Algo, pubkey: string }> {
248-
249-
try {
250229

251-
const accounts = await this.provider.request({
252-
method: 'cosmos_getAccounts',
253-
params: []
254-
}, `cosmos:${chainId}`) as any[];
255-
256-
const { address, algo, pubkey } = accounts[0];
257-
return {
258-
address,
259-
algo: algo as Algo,
260-
pubkey: pubkey,
261-
};
262-
} catch (error) {
263-
console.log('get cosmos account error', error);
264-
throw error;
265-
}
266-
}
267230

268231
async getOfflineSigner(chainId: string, preferredSignType?: SignType) {
269232
if (preferredSignType === 'amino') {
@@ -272,14 +235,14 @@ export class WCWallet extends MultiChainWallet {
272235
signAmino: async (signer: string, signDoc: StdSignDoc) => {
273236
return this.signAmino(chainId, signer, signDoc);
274237
}
275-
}
238+
};
276239
} else if (preferredSignType === 'direct') {
277240
return {
278241
getAccounts: async () => [await this.getAccount(chainId)],
279242
signDirect: async (signer: string, signDoc: DirectSignDoc) => {
280243
return this.signDirect(chainId, signer, signDoc);
281244
}
282-
}
245+
};
283246
}
284247
}
285248

@@ -370,12 +333,12 @@ export class WCWallet extends MultiChainWallet {
370333
console.error('disconnect:', error);
371334
});
372335

373-
this.provider.on("session_delete", (error: { message: string; code: number }) => {
374-
console.log("session_delete:", error);
375-
localStorage.removeItem('wc-session')
336+
this.provider.on('session_delete', (error: { message: string; code: number }) => {
337+
console.log('session_delete:', error);
338+
localStorage.removeItem('wc-session');
376339

377340
// Emit disconnect event to notify StatefulWallet
378-
this.events.emit('disconnect', '')
341+
this.events.emit('disconnect', '');
379342
});
380343

381344
this.provider.on('session_event', (error: { message: string; code: number }) => {

packages/store/src/proxied-wallets/create-proxied-wallet.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
import { isInstanceOf } from '@interchain-kit/core';
1+
import { isInstanceOf, SolanaWallet } from '@interchain-kit/core';
22
import { CosmosWallet, EthereumWallet, MultiChainWallet } from '@interchain-kit/core';
33

44
import { InterchainStore } from '../store';
55
import { createCosmosWallet } from './cosmos-wallet';
66
import { createEthereumWallet } from './ethereum-wallet';
77
import { createMultiChainWallet } from './multi-chain-wallet';
8+
import { createSolanaWallet } from './solana-wallet';
89
// import { createWCWallet } from './wc-wallet';
910

1011
export const createProxiedWallet = <T>(wallet: T, store: InterchainStore): T => {
@@ -16,6 +17,9 @@ export const createProxiedWallet = <T>(wallet: T, store: InterchainStore): T =>
1617
if (isInstanceOf(wallet, EthereumWallet)) {
1718
return createEthereumWallet(wallet, store) as T;
1819
}
20+
if (isInstanceOf(wallet, SolanaWallet)) {
21+
return createSolanaWallet(wallet, store) as T;
22+
}
1923
if (isInstanceOf(wallet, MultiChainWallet)) {
2024
Array.from(wallet.networkWalletMap.keys()).forEach(chainType => {
2125
const chainWallet = wallet.networkWalletMap.get(chainType);
@@ -25,6 +29,9 @@ export const createProxiedWallet = <T>(wallet: T, store: InterchainStore): T =>
2529
if (isInstanceOf(chainWallet, EthereumWallet)) {
2630
wallet.setNetworkWallet(chainType, createEthereumWallet(chainWallet, store));
2731
}
32+
if (isInstanceOf(chainWallet, SolanaWallet)) {
33+
wallet.setNetworkWallet(chainType, createSolanaWallet(chainWallet, store));
34+
}
2835
});
2936

3037
return createMultiChainWallet(wallet, store) as T;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { SolanaWallet } from '@interchain-kit/core';
2+
3+
import { InterchainStore } from '../store';
4+
import { createAOPProxy } from '../utils';
5+
6+
export const createSolanaWallet = (target: SolanaWallet, store: InterchainStore) => {
7+
return createAOPProxy({
8+
target,
9+
advice: {
10+
signTransaction: {
11+
onError(methodName, target, error, transaction) {
12+
store.updateChainWalletState(target.info.name, 'solana', { errorMessage: error.message });
13+
},
14+
},
15+
}
16+
});
17+
};

wallets/ledger/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,12 @@
3434
"dependencies": {
3535
"@chain-registry/types": "^2.0.1",
3636
"@interchain-kit/core": "0.3.47",
37+
"@ledgerhq/hw-app-solana": "^7.5.2",
3738
"@ledgerhq/hw-transport": "^6.31.4",
3839
"@ledgerhq/hw-transport-webhid": "^6.29.4",
40+
"@solana/web3.js": "^1.87.6",
3941
"@zondax/ledger-cosmos-js": "^4.0.0",
42+
"bs58": "^6.0.0",
4043
"buffer": "^6.0.3",
4144
"chain-registry": "^2.0.1",
4245
"crypto": "npm:crypto-es",

0 commit comments

Comments
 (0)