Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions apps/demo-wallet/src/components/ConnectRequestModal.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useState, useMemo } from 'react';
import type { EventConnectRequest, WalletInterface } from '@ton/walletkit';
import type { EventConnectRequest, IWallet } from '@ton/walletkit';

import { Button } from './Button';
import { Card } from './Card';
Expand All @@ -13,10 +13,10 @@ const log = createComponentLogger('ConnectRequestModal');

interface ConnectRequestModalProps {
request: EventConnectRequest;
availableWallets: WalletInterface[];
availableWallets: IWallet[];
savedWallets: SavedWallet[];
isOpen: boolean;
onApprove: (selectedWallet: WalletInterface) => void;
onApprove: (selectedWallet: IWallet) => void;
onReject: (reason?: string) => void;
}

Expand All @@ -28,7 +28,7 @@ export const ConnectRequestModal: React.FC<ConnectRequestModalProps> = ({
onApprove,
onReject,
}) => {
const [selectedWallet, setSelectedWallet] = useState<WalletInterface | null>(availableWallets[0] || null);
const [selectedWallet, setSelectedWallet] = useState<IWallet | null>(availableWallets[0] || null);
const [isLoading, setIsLoading] = useState(false);
const [showAllWallets, setShowAllWallets] = useState(false);

Expand Down
99 changes: 61 additions & 38 deletions apps/demo-wallet/src/stores/slices/walletSlice.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
import {
TonWalletKit,
type WalletInterface,
type IWalletAdapter,
type EventConnectRequest,
type EventTransactionRequest,
type EventSignDataRequest,
type EventDisconnect,
ExtensionStorageAdapter,
type WalletInitConfig,
createWalletInitConfigSigner,
createWalletInitConfigMnemonic,
MnemonicToKeyPair,
type IWallet,
Signer,
WalletV5R1Adapter,
WalletV4R2Adapter,
DefaultSignature,
CHAIN,
type ITonWalletKit,
createDeviceInfo,
createWalletManifest,
type ToncenterTransaction,
SEND_TRANSACTION_ERROR_CODES,
MnemonicToKeyPair,
type WalletSigner,
} from '@ton/walletkit';
import { createWalletInitConfigLedger, createLedgerPath, createWalletV4R2Ledger } from '@ton/v4ledger-adapter';
import TransportWebHID from '@ledgerhq/hw-transport-webhid';
Expand Down Expand Up @@ -117,15 +119,15 @@ function transformToncenterTransaction(tx: ToncenterTransaction): PreviewTransac
};
}

async function createWalletConfig(params: {
async function createWalletAdapter(params: {
mnemonic?: string[];
useWalletInterfaceType: 'signer' | 'mnemonic' | 'ledger';
ledgerAccountNumber?: number;
storedLedgerConfig?: LedgerConfig;
network: 'mainnet' | 'testnet';
walletKit: ITonWalletKit;
version?: 'v5r1' | 'v4r2';
}): Promise<WalletInitConfig> {
}): Promise<IWalletAdapter> {
const {
mnemonic,
useWalletInterfaceType,
Expand All @@ -149,29 +151,50 @@ async function createWalletConfig(params: {
}
const keyPair = await MnemonicToKeyPair(mnemonic);

return createWalletInitConfigSigner({
publicKey: keyPair.publicKey,
version: version,
network: chainNetwork,
// Create custom signer with confirmation dialog
const customSigner: WalletSigner = {
sign: async (bytes: Uint8Array) => {
if (confirm('Are you sure you want to sign?')) {
return DefaultSignature(bytes, keyPair.secretKey);
}

throw new Error('User did not confirm');
},
});
publicKey: keyPair.publicKey,
};

// Create adapter with the appropriate version
if (version === 'v5r1') {
return await WalletV5R1Adapter.create(customSigner, {
client: walletKit.getApiClient(),
network: chainNetwork,
});
} else {
return await WalletV4R2Adapter.create(customSigner, {
client: walletKit.getApiClient(),
network: chainNetwork,
});
}
}
case 'mnemonic': {
if (!mnemonic) {
throw new Error('Mnemonic required for mnemonic wallet type');
}
return createWalletInitConfigMnemonic({
mnemonic,
version: version,
mnemonicType: 'ton',
network: chainNetwork,
});

// Use Signer.fromMnemonic to create signer with publicKey
const signer = await Signer.fromMnemonic(mnemonic, { type: 'ton' });

// Create adapter with the appropriate version
if (version === 'v5r1') {
return await WalletV5R1Adapter.create(signer, {
client: walletKit.getApiClient(),
network: chainNetwork,
});
} else {
return await WalletV4R2Adapter.create(signer, {
client: walletKit.getApiClient(),
network: chainNetwork,
});
}
}
case 'ledger': {
// For Ledger, we need to request WebUSB transport
Expand Down Expand Up @@ -287,11 +310,11 @@ export const createWalletSlice: WalletSliceCreator = (set: SetState, get) => ({

for (const savedWallet of savedWallets) {
try {
let walletConfig: WalletInitConfig;
let walletAdapter: IWalletAdapter;

if (savedWallet.walletType === 'ledger' && savedWallet.ledgerConfig) {
// Load Ledger wallet
walletConfig = await createWalletConfig({
walletAdapter = await createWalletAdapter({
useWalletInterfaceType: 'ledger',
ledgerAccountNumber: savedWallet.ledgerConfig.accountIndex,
storedLedgerConfig: savedWallet.ledgerConfig,
Expand All @@ -307,7 +330,7 @@ export const createWalletSlice: WalletSliceCreator = (set: SetState, get) => ({
);
const mnemonic = JSON.parse(mnemonicJson) as string[];

walletConfig = await createWalletConfig({
walletAdapter = await createWalletAdapter({
mnemonic,
useWalletInterfaceType: savedWallet.walletInterfaceType,
ledgerAccountNumber: state.auth.ledgerAccountNumber,
Expand All @@ -323,7 +346,7 @@ export const createWalletSlice: WalletSliceCreator = (set: SetState, get) => ({

// debugger;

await walletKit.addWallet(walletConfig);
await walletKit.addWallet(walletAdapter);
log.info(`Loaded wallet ${savedWallet.name} (${savedWallet.address})`);
} catch (error) {
log.error(`Failed to load wallet ${savedWallet.name}:`, error);
Expand Down Expand Up @@ -433,7 +456,7 @@ export const createWalletSlice: WalletSliceCreator = (set: SetState, get) => ({

// Create wallet using walletkit
const network = state.auth.network || 'testnet';
const walletConfig = await createWalletConfig({
const walletAdapter = await createWalletAdapter({
mnemonic,
useWalletInterfaceType: state.auth.useWalletInterfaceType || 'mnemonic',
ledgerAccountNumber: state.auth.ledgerAccountNumber,
Expand All @@ -443,9 +466,9 @@ export const createWalletSlice: WalletSliceCreator = (set: SetState, get) => ({
version,
});

const wallet = await state.wallet.walletKit.addWallet(walletConfig);
const wallet = await state.wallet.walletKit.addWallet(walletAdapter);
// const wallets = state.wallet.walletKit.getWallets();
// const wallet = wallets.find((w) => w.getAddress() === walletConfig.getAddress());
// const wallet = wallets.find((w) => w.getAddress() === walletAdapter.getAddress());

if (!wallet) {
throw new Error('Failed to find created wallet');
Expand Down Expand Up @@ -525,17 +548,17 @@ export const createWalletSlice: WalletSliceCreator = (set: SetState, get) => ({

// Create wallet using walletkit with Ledger configuration
const network = state.auth.network || 'testnet';
const walletConfig = await createWalletConfig({
const walletAdapter = await createWalletAdapter({
useWalletInterfaceType: 'ledger',
ledgerAccountNumber: state.auth.ledgerAccountNumber,
storedLedgerConfig: undefined,
network,
walletKit: state.wallet.walletKit,
});

const wallet = await state.wallet.walletKit.addWallet(walletConfig);
const wallet = await state.wallet.walletKit.addWallet(walletAdapter);
// const wallets = state.wallet.walletKit.getWallets();
// const wallet = wallets.find((w) => w.getAddress() === walletConfig.getAddress());
// const wallet = wallets.find((w) => w.getAddress() === walletAdapter.getAddress());

if (!wallet) {
throw new Error('Failed to find created Ledger wallet');
Expand Down Expand Up @@ -629,7 +652,7 @@ export const createWalletSlice: WalletSliceCreator = (set: SetState, get) => ({
const network = state.auth.network || 'testnet';

if (savedWallet.walletType === 'ledger') {
const walletConfig = await createWalletConfig({
const walletAdapter = await createWalletAdapter({
useWalletInterfaceType: 'ledger',
ledgerAccountNumber: savedWallet.ledgerConfig?.accountIndex,
storedLedgerConfig: savedWallet.ledgerConfig,
Expand All @@ -638,15 +661,15 @@ export const createWalletSlice: WalletSliceCreator = (set: SetState, get) => ({
version: savedWallet.version || 'v4r2',
});

await state.wallet.walletKit.addWallet(walletConfig);
await state.wallet.walletKit.addWallet(walletAdapter);
} else if (savedWallet.encryptedMnemonic) {
const decryptedString = await SimpleEncryption.decrypt(
savedWallet.encryptedMnemonic,
state.auth.currentPassword,
);
const mnemonic = JSON.parse(decryptedString) as string[];

const walletConfig = await createWalletConfig({
const walletAdapter = await createWalletAdapter({
mnemonic,
useWalletInterfaceType: savedWallet.walletInterfaceType,
ledgerAccountNumber: state.auth.ledgerAccountNumber,
Expand All @@ -656,7 +679,7 @@ export const createWalletSlice: WalletSliceCreator = (set: SetState, get) => ({
version: savedWallet.version || 'v5r1',
});

await state.wallet.walletKit.addWallet(walletConfig);
await state.wallet.walletKit.addWallet(walletAdapter);
}

// Get the newly loaded wallet
Expand Down Expand Up @@ -770,23 +793,23 @@ export const createWalletSlice: WalletSliceCreator = (set: SetState, get) => ({
const network = state.auth.network || 'testnet';

if (savedWallet.walletType === 'ledger') {
const walletConfig = await createWalletConfig({
const walletAdapter = await createWalletAdapter({
useWalletInterfaceType: 'ledger',
ledgerAccountNumber: savedWallet.ledgerConfig?.accountIndex,
storedLedgerConfig: savedWallet.ledgerConfig,
network,
walletKit: state.wallet.walletKit,
});

await state.wallet.walletKit.addWallet(walletConfig);
await state.wallet.walletKit.addWallet(walletAdapter);
} else if (savedWallet.encryptedMnemonic) {
const decryptedString = await SimpleEncryption.decrypt(
savedWallet.encryptedMnemonic,
state.auth.currentPassword,
);
const mnemonic = JSON.parse(decryptedString) as string[];

const walletConfig = await createWalletConfig({
const walletAdapter = await createWalletAdapter({
mnemonic,
useWalletInterfaceType: savedWallet.walletInterfaceType,
ledgerAccountNumber: state.auth.ledgerAccountNumber,
Expand All @@ -795,7 +818,7 @@ export const createWalletSlice: WalletSliceCreator = (set: SetState, get) => ({
walletKit: state.wallet.walletKit,
});

await state.wallet.walletKit.addWallet(walletConfig);
await state.wallet.walletKit.addWallet(walletAdapter);
}
}

Expand Down Expand Up @@ -968,7 +991,7 @@ export const createWalletSlice: WalletSliceCreator = (set: SetState, get) => ({
});
},

approveConnectRequest: async (selectedWallet: WalletInterface) => {
approveConnectRequest: async (selectedWallet: IWallet) => {
const state = get();
if (!state.wallet.pendingConnectRequest) {
log.error('No pending connect request to approve');
Expand Down
6 changes: 3 additions & 3 deletions apps/demo-wallet/src/types/store.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { StateCreator } from 'zustand';
import type {
WalletInterface,
IWallet,
EventConnectRequest,
EventTransactionRequest,
EventSignDataRequest,
Expand Down Expand Up @@ -120,7 +120,7 @@ export interface WalletSlice extends WalletState {
// TON Connect actions
handleTonConnectUrl: (url: string) => Promise<void>;
showConnectRequest: (request: EventConnectRequest) => void;
approveConnectRequest: (selectedWallet: WalletInterface) => Promise<void>;
approveConnectRequest: (selectedWallet: IWallet) => Promise<void>;
rejectConnectRequest: (reason?: string) => Promise<void>;
closeConnectModal: () => void;

Expand All @@ -142,7 +142,7 @@ export interface WalletSlice extends WalletState {

// Getters
getDecryptedMnemonic: (walletId?: string) => Promise<string[] | null>;
getAvailableWallets: () => WalletInterface[];
getAvailableWallets: () => IWallet[];
getActiveWallet: () => SavedWallet | undefined;
}

Expand Down
4 changes: 2 additions & 2 deletions apps/demo-wallet/src/types/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type {
EventConnectRequest,
EventTransactionRequest,
EventSignDataRequest,
WalletInterface,
IWallet,
ITonWalletKit,
} from '@ton/walletkit';

Expand Down Expand Up @@ -40,7 +40,7 @@ export interface WalletState {
transactions: PreviewTransaction[];

// Walletkit instance and current wallet
currentWallet?: WalletInterface;
currentWallet?: IWallet;

// Connect request state
pendingConnectRequest?: EventConnectRequest;
Expand Down
4 changes: 2 additions & 2 deletions packages/v4ledger-adapter/src/WalletV4R2LedgerAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { CHAIN, toHexString } from '@tonconnect/protocol';
import { TonTransport } from '@ton-community/ton-ledger';
import Transport from '@ledgerhq/hw-transport';
import {
WalletInitInterface,
IWalletAdapter,
ApiClient,
formatWalletAddress,
CallForSuccess,
Expand Down Expand Up @@ -54,7 +54,7 @@ export function createWalletInitConfigLedger(params: WalletInitConfigLedgerInter
* WalletV4R2 Ledger adapter that implements WalletInterface for WalletV4R2 contracts
* using Ledger hardware wallet for signing
*/
export class WalletV4R2LedgerAdapter implements WalletInitInterface {
export class WalletV4R2LedgerAdapter implements IWalletAdapter {
private createTransport: () => Promise<Transport>;
private config: WalletV4R2LedgerAdapterConfig;
private derivationPath: number[];
Expand Down
6 changes: 3 additions & 3 deletions packages/v4ledger-adapter/src/examples/ledger-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import util from 'util';
// import { Address } from '@ton/core'; // Not used in this example
import * as dotenv from 'dotenv';
import TransportNodeHid from '@ledgerhq/hw-transport-node-hid';
import { ApiClientToncenter, CHAIN, ConnectTransactionParamMessage, WalletInterface } from '@ton/walletkit';
import { ApiClientToncenter, CHAIN, ConnectTransactionParamMessage, IWallet } from '@ton/walletkit';
import { wrapWalletInterface } from '@ton/walletkit';

import { createLedgerPath, createWalletV4R2Ledger } from '../utils';
Expand All @@ -29,7 +29,7 @@ async function createLedgerWallet(
testnet: boolean = false,
workchain: number = 0,
account: number = 0,
): Promise<WalletInterface> {
): Promise<IWallet> {
logInfo('🔌 Connecting to Ledger device...');

try {
Expand Down Expand Up @@ -58,7 +58,7 @@ async function createLedgerWallet(
}
}

async function logWallet(wallet: WalletInterface) {
async function logWallet(wallet: IWallet) {
const address = wallet.getAddress();
logInfo('📍 Wallet address:', address);

Expand Down
Loading
Loading