Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add versioned transaction methods to adapter interface #558

Merged
merged 39 commits into from
Sep 15, 2022
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
5269c16
Bump @solana/web3.js version to v1.59.1
jstarry Sep 12, 2022
5ce4a3c
Add versioned transaction methods to adapter interface
jstarry Sep 8, 2022
1529a5b
feedback
jstarry Sep 12, 2022
9ce97d6
update web3.js consistent with master
jordaaash Sep 13, 2022
d5e9fd8
Merge branch 'master' into versioned-tx
jordaaash Sep 13, 2022
6762d53
update lockfile
jordaaash Sep 13, 2022
8098e7b
organize imports, lint fix
jordaaash Sep 13, 2022
f2f13b2
refactor versioned transaction methods
jordaaash Sep 13, 2022
f395866
fix react types
jordaaash Sep 13, 2022
af2257a
add type guard for versioned txs
jordaaash Sep 13, 2022
f731ea1
alpha adapter test
jordaaash Sep 13, 2022
98ca6e8
fixes
jordaaash Sep 13, 2022
aed4d7a
fixes
jordaaash Sep 13, 2022
793b161
check out wallets from master
jordaaash Sep 14, 2022
4b9132b
add supportedTransactionVersions flag to wallets
jordaaash Sep 14, 2022
eb4011d
infer types
jordaaash Sep 14, 2022
20bc5ed
organize imports
jordaaash Sep 14, 2022
04a6205
have signAllTransactions check for versioned txs
jordaaash Sep 14, 2022
80d1d48
infer supportedTransactionVersions type from field
jordaaash Sep 15, 2022
f2d50d6
fix sign / signAll in all adapters
jordaaash Sep 15, 2022
46ef36c
remove hack
jordaaash Sep 15, 2022
a46ff71
Add versioned transaction methods to adapter interface
jstarry Sep 8, 2022
43cde10
feedback
jstarry Sep 12, 2022
6505731
organize imports, lint fix
jordaaash Sep 13, 2022
aa1e381
refactor versioned transaction methods
jordaaash Sep 13, 2022
1e8b5ee
fix react types
jordaaash Sep 13, 2022
87b3943
add type guard for versioned txs
jordaaash Sep 13, 2022
6cc7d90
alpha adapter test
jordaaash Sep 13, 2022
4369e40
fixes
jordaaash Sep 13, 2022
8819905
fixes
jordaaash Sep 13, 2022
bde0bb2
check out wallets from master
jordaaash Sep 14, 2022
c2d14da
add supportedTransactionVersions flag to wallets
jordaaash Sep 14, 2022
a801e06
infer types
jordaaash Sep 14, 2022
ebe79ec
organize imports
jordaaash Sep 14, 2022
1c0b0f6
have signAllTransactions check for versioned txs
jordaaash Sep 14, 2022
6266bd8
infer supportedTransactionVersions type from field
jordaaash Sep 15, 2022
6533919
fix sign / signAll in all adapters
jordaaash Sep 15, 2022
18878eb
remove hack
jordaaash Sep 15, 2022
ddf04df
Merge branch 'versioned-tx' of https://github.com/jstarry/wallet-adap…
jordaaash Sep 15, 2022
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
16 changes: 12 additions & 4 deletions packages/core/base/src/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Connection, PublicKey, SendOptions, Signer, Transaction, Transacti
import EventEmitter from 'eventemitter3';
import type { WalletError } from './errors.js';
import { WalletNotConnectedError } from './errors.js';
import type { SupportedTransactionVersions, TransactionOrVersionedTransaction } from './types.js';

export { EventEmitter };

Expand All @@ -28,11 +29,13 @@ export interface WalletAdapterProps<Name extends string = string> {
publicKey: PublicKey | null;
connecting: boolean;
connected: boolean;
supportedTransactionVersions: SupportedTransactionVersions;

connect(): Promise<void>;
disconnect(): Promise<void>;

sendTransaction(
transaction: Transaction,
transaction: TransactionOrVersionedTransaction<this['supportedTransactionVersions']>,
connection: Connection,
options?: SendTransactionOptions
): Promise<TransactionSignature>;
Expand Down Expand Up @@ -69,22 +72,27 @@ export enum WalletReadyState {
Unsupported = 'Unsupported',
}

export abstract class BaseWalletAdapter extends EventEmitter<WalletAdapterEvents> implements WalletAdapter {
abstract name: WalletName;
export abstract class BaseWalletAdapter<Name extends string = string>
extends EventEmitter<WalletAdapterEvents>
implements WalletAdapter<Name>
{
abstract name: WalletName<Name>;
abstract url: string;
abstract icon: string;
abstract readyState: WalletReadyState;
abstract publicKey: PublicKey | null;
abstract connecting: boolean;
abstract supportedTransactionVersions: SupportedTransactionVersions;

get connected() {
return !!this.publicKey;
}

abstract connect(): Promise<void>;
abstract disconnect(): Promise<void>;

abstract sendTransaction(
transaction: Transaction,
transaction: TransactionOrVersionedTransaction<this['supportedTransactionVersions']>,
connection: Connection,
options?: SendTransactionOptions
): Promise<TransactionSignature>;
Expand Down
114 changes: 85 additions & 29 deletions packages/core/base/src/signer.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,78 @@
import type { Connection, Transaction, TransactionSignature } from '@solana/web3.js';
import type { SendTransactionOptions, WalletAdapter } from './adapter.js';
import type { Connection, TransactionSignature } from '@solana/web3.js';
import type { SendTransactionOptions, WalletAdapter, WalletAdapterProps } from './adapter.js';
import { BaseWalletAdapter } from './adapter.js';
import { WalletSendTransactionError, WalletSignTransactionError } from './errors.js';
import type { TransactionOrVersionedTransaction } from './types.js';

export interface SignerWalletAdapterProps {
signTransaction(transaction: Transaction): Promise<Transaction>;
signAllTransactions(transaction: Transaction[]): Promise<Transaction[]>;
export interface SignerWalletAdapterProps<Name extends string = string> extends WalletAdapterProps<Name> {
signTransaction<T extends TransactionOrVersionedTransaction<this['supportedTransactionVersions']>>(
transaction: T
): Promise<T>;
signAllTransactions<T extends TransactionOrVersionedTransaction<this['supportedTransactionVersions']>>(
transactions: T[]
): Promise<T[]>;
Comment on lines +8 to +13
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I think these types are very reasonable now. By inferring SupportedTransactionVersions from the actual implementer, and making the methods return the type they were called with, existing code that expects signTransaction(transaction: Transaction): Promise<Transaction> will just work.

}

export type SignerWalletAdapter = WalletAdapter & SignerWalletAdapterProps;
export type SignerWalletAdapter<Name extends string = string> = WalletAdapter<Name> & SignerWalletAdapterProps<Name>;

export abstract class BaseSignerWalletAdapter extends BaseWalletAdapter implements SignerWalletAdapter {
export abstract class BaseSignerWalletAdapter<Name extends string = string>
extends BaseWalletAdapter<Name>
implements SignerWalletAdapter<Name>
{
async sendTransaction(
transaction: Transaction,
transaction: TransactionOrVersionedTransaction<this['supportedTransactionVersions']>,
connection: Connection,
options: SendTransactionOptions = {}
): Promise<TransactionSignature> {
let emit = true;
try {
try {
const { signers, ...sendOptions } = options;
if ('message' in transaction) {
if (!this.supportedTransactionVersions)
throw new WalletSendTransactionError(
`Sending versioned transactions isn't supported by this wallet`
);

const { version } = transaction.message;
if (!this.supportedTransactionVersions.has(version))
throw new WalletSendTransactionError(
`Sending transaction version ${version} isn't supported by this wallet`
);

try {
transaction = await this.signTransaction(transaction);

const rawTransaction = transaction.serialize();

return await connection.sendRawTransaction(rawTransaction, options);
} catch (error: any) {
// If the error was thrown by `signTransaction`, rethrow it and don't emit a duplicate event
if (error instanceof WalletSignTransactionError) {
emit = false;
throw error;
}
throw new WalletSendTransactionError(error?.message, error);
}
} else {
try {
const { signers, ...sendOptions } = options;

transaction = await this.prepareTransaction(transaction, connection, sendOptions);
transaction = await this.prepareTransaction(transaction, connection, sendOptions);

signers?.length && transaction.partialSign(...signers);
signers?.length && transaction.partialSign(...signers);

transaction = await this.signTransaction(transaction);
transaction = await this.signTransaction(transaction);

const rawTransaction = transaction.serialize();
const rawTransaction = transaction.serialize();

return await connection.sendRawTransaction(rawTransaction, sendOptions);
} catch (error: any) {
// If the error was thrown by `signTransaction`, rethrow it and don't emit a duplicate event
if (error instanceof WalletSignTransactionError) {
emit = false;
throw error;
return await connection.sendRawTransaction(rawTransaction, sendOptions);
} catch (error: any) {
// If the error was thrown by `signTransaction`, rethrow it and don't emit a duplicate event
if (error instanceof WalletSignTransactionError) {
emit = false;
throw error;
}
throw new WalletSendTransactionError(error?.message, error);
}
throw new WalletSendTransactionError(error?.message, error);
}
} catch (error: any) {
if (emit) {
Expand All @@ -46,26 +82,46 @@ export abstract class BaseSignerWalletAdapter extends BaseWalletAdapter implemen
}
}

abstract signTransaction(transaction: Transaction): Promise<Transaction>;
abstract signTransaction<T extends TransactionOrVersionedTransaction<this['supportedTransactionVersions']>>(
transaction: T
): Promise<T>;

async signAllTransactions<T extends TransactionOrVersionedTransaction<this['supportedTransactionVersions']>>(
transactions: T[]
): Promise<T[]> {
for (const transaction of transactions) {
if ('message' in transaction) {
if (!this.supportedTransactionVersions)
throw new WalletSignTransactionError(
`Signing versioned transactions isn't supported by this wallet`
);

const { version } = transaction.message;
if (!this.supportedTransactionVersions.has(version))
throw new WalletSignTransactionError(
`Signing transaction version ${version} isn't supported by this wallet`
);
}
}

async signAllTransactions(transactions: Transaction[]): Promise<Transaction[]> {
const signedTransactions: Transaction[] = [];
const signedTransactions: T[] = [];
for (const transaction of transactions) {
signedTransactions.push(await this.signTransaction(transaction));
}
return signedTransactions;
}
}

export interface MessageSignerWalletAdapterProps {
export interface MessageSignerWalletAdapterProps<Name extends string = string> extends WalletAdapterProps<Name> {
signMessage(message: Uint8Array): Promise<Uint8Array>;
}

export type MessageSignerWalletAdapter = WalletAdapter & MessageSignerWalletAdapterProps;
export type MessageSignerWalletAdapter<Name extends string = string> = WalletAdapter<Name> &
MessageSignerWalletAdapterProps<Name>;

export abstract class BaseMessageSignerWalletAdapter
extends BaseSignerWalletAdapter
implements MessageSignerWalletAdapter
export abstract class BaseMessageSignerWalletAdapter<Name extends string = string>
extends BaseSignerWalletAdapter<Name>
implements MessageSignerWalletAdapter<Name>
{
abstract signMessage(message: Uint8Array): Promise<Uint8Array>;
}
7 changes: 7 additions & 0 deletions packages/core/base/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { Transaction, TransactionVersion, VersionedTransaction } from '@solana/web3.js';
import type { WalletAdapter } from './adapter.js';
import type { MessageSignerWalletAdapter, SignerWalletAdapter } from './signer.js';

Expand All @@ -8,3 +9,9 @@ export enum WalletAdapterNetwork {
Testnet = 'testnet',
Devnet = 'devnet',
}

export type SupportedTransactionVersions = Set<TransactionVersion> | null;

export type TransactionOrVersionedTransaction<S extends SupportedTransactionVersions> = S extends null
? Transaction
: Transaction | VersionedTransaction;
27 changes: 17 additions & 10 deletions packages/core/react/src/WalletProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import type { Adapter, SendTransactionOptions, WalletError, WalletName } from '@solana/wallet-adapter-base';
import type {
Adapter,
MessageSignerWalletAdapterProps,
SignerWalletAdapterProps,
WalletAdapterProps,
WalletError,
WalletName,
} from '@solana/wallet-adapter-base';
import { WalletNotConnectedError, WalletNotReadyError, WalletReadyState } from '@solana/wallet-adapter-base';
import type { Connection, PublicKey, Transaction } from '@solana/web3.js';
import type { PublicKey } from '@solana/web3.js';
import type { FC, ReactNode } from 'react';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { WalletNotSelectedError } from './errors.js';
Expand Down Expand Up @@ -230,8 +237,8 @@ export const WalletProvider: FC<WalletProviderProps> = ({
}, [isDisconnecting, adapter, setName]);

// Send a transaction using the provided connection
const sendTransaction = useCallback(
async (transaction: Transaction, connection: Connection, options?: SendTransactionOptions) => {
const sendTransaction: WalletAdapterProps['sendTransaction'] = useCallback(
async (transaction, connection, options) => {
jordaaash marked this conversation as resolved.
Show resolved Hide resolved
if (!adapter) throw handleError(new WalletNotSelectedError());
if (!connected) throw handleError(new WalletNotConnectedError());
return await adapter.sendTransaction(transaction, connection, options);
Expand All @@ -240,10 +247,10 @@ export const WalletProvider: FC<WalletProviderProps> = ({
);

// Sign a transaction if the wallet supports it
const signTransaction = useMemo(
const signTransaction: SignerWalletAdapterProps['signTransaction'] | undefined = useMemo(
Copy link
Collaborator

@jordaaash jordaaash Sep 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This type is still not perfect in the sense that a dev will see (transaction: Transaction | VersionedTransaction) as the parameter type, so they have to know to check the adapter for supportedTransactionVersions. But it is functional and nonbreaking, because it will always be expected to return whichever type it was called with.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That seems totally fine to me

() =>
adapter && 'signTransaction' in adapter
? async (transaction: Transaction): Promise<Transaction> => {
? async (transaction) => {
if (!connected) throw handleError(new WalletNotConnectedError());
return await adapter.signTransaction(transaction);
}
Expand All @@ -252,10 +259,10 @@ export const WalletProvider: FC<WalletProviderProps> = ({
);

// Sign multiple transactions if the wallet supports it
const signAllTransactions = useMemo(
const signAllTransactions: SignerWalletAdapterProps['signAllTransactions'] | undefined = useMemo(
() =>
adapter && 'signAllTransactions' in adapter
? async (transactions: Transaction[]): Promise<Transaction[]> => {
? async (transactions) => {
if (!connected) throw handleError(new WalletNotConnectedError());
return await adapter.signAllTransactions(transactions);
}
Expand All @@ -264,10 +271,10 @@ export const WalletProvider: FC<WalletProviderProps> = ({
);

// Sign an arbitrary message if the wallet supports it
const signMessage = useMemo(
const signMessage: MessageSignerWalletAdapterProps['signMessage'] | undefined = useMemo(
() =>
adapter && 'signMessage' in adapter
? async (message: Uint8Array): Promise<Uint8Array> => {
? async (message) => {
if (!connected) throw handleError(new WalletNotConnectedError());
return await adapter.signMessage(message);
}
Expand Down
1 change: 1 addition & 0 deletions packages/core/react/src/__tests__/WalletProvider-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ describe('WalletProvider', () => {
});
});
sendTransaction = jest.fn();
supportedTransactionVersions = null;
}
class FooWalletAdapter extends MockWalletAdapter {
name = 'FooWallet' as WalletName<'FooWallet'>;
Expand Down
15 changes: 8 additions & 7 deletions packages/core/react/src/useWallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import type {
MessageSignerWalletAdapterProps,
SendTransactionOptions,
SignerWalletAdapterProps,
WalletAdapterProps,
WalletName,
WalletReadyState,
} from '@solana/wallet-adapter-base';
import type { Connection, PublicKey, Transaction, TransactionSignature } from '@solana/web3.js';
import type { Connection, PublicKey, Transaction, VersionedTransaction } from '@solana/web3.js';
import { createContext, useContext } from 'react';

export interface Wallet {
Expand All @@ -26,12 +27,8 @@ export interface WalletContextState {
select(walletName: WalletName): void;
connect(): Promise<void>;
disconnect(): Promise<void>;
sendTransaction(
transaction: Transaction,
connection: Connection,
options?: SendTransactionOptions
): Promise<TransactionSignature>;

sendTransaction: WalletAdapterProps['sendTransaction'];
signTransaction: SignerWalletAdapterProps['signTransaction'] | undefined;
signAllTransactions: SignerWalletAdapterProps['signAllTransactions'] | undefined;
signMessage: MessageSignerWalletAdapterProps['signMessage'] | undefined;
Expand All @@ -53,7 +50,11 @@ const DEFAULT_CONTEXT = {
disconnect() {
return Promise.reject(console.error(constructMissingProviderErrorMessage('get', 'disconnect')));
},
sendTransaction(_transaction: Transaction, _connection: Connection, _options?: SendTransactionOptions) {
sendTransaction(
_transaction: VersionedTransaction | Transaction,
_connection: Connection,
_options?: SendTransactionOptions
) {
return Promise.reject(console.error(constructMissingProviderErrorMessage('get', 'sendTransaction')));
},
signTransaction(_transaction: Transaction) {
Expand Down
9 changes: 5 additions & 4 deletions packages/wallets/alpha/src/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export class AlphaWalletAdapter extends BaseMessageSignerWalletAdapter {
url = 'https://github.com/babilu-online/alpha-wallet';
icon =
'data:image/svg+xml;base64,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';
readonly supportedTransactionVersions = null;
jordaaash marked this conversation as resolved.
Show resolved Hide resolved

private _connecting: boolean;
private _wallet: AlphaWallet | null;
Expand Down Expand Up @@ -185,13 +186,13 @@ export class AlphaWalletAdapter extends BaseMessageSignerWalletAdapter {
}
}

async signTransaction(transaction: Transaction): Promise<Transaction> {
async signTransaction<T extends Transaction>(transaction: T): Promise<T> {
Copy link
Collaborator

@jordaaash jordaaash Sep 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We know that transaction will only ever be Transaction now because supportedTransactionVersions is null, but we still have to implement it this way because the interface declares it like this. All this means is that if a subtype of Transaction was passed to signTransaction, the wallet should return the same subtype. In practice, this doesn't matter because there are no subclasses of Transaction in web3.js to worry about.

try {
const wallet = this._wallet;
if (!wallet) throw new WalletNotConnectedError();

try {
return (await wallet.signTransaction(transaction)) || transaction;
return ((await wallet.signTransaction(transaction)) as T) || transaction;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we have to perform the one ugly bit, where we cast Transaction as T even though we know it will be valid.

} catch (error: any) {
throw new WalletSignTransactionError(error?.message, error);
}
Expand All @@ -201,13 +202,13 @@ export class AlphaWalletAdapter extends BaseMessageSignerWalletAdapter {
}
}

async signAllTransactions(transactions: Transaction[]): Promise<Transaction[]> {
async signAllTransactions<T extends Transaction>(transactions: T[]): Promise<T[]> {
try {
const wallet = this._wallet;
if (!wallet) throw new WalletNotConnectedError();

try {
return (await wallet.signAllTransactions(transactions)) || transactions;
return ((await wallet.signAllTransactions(transactions)) as T[]) || transactions;
} catch (error: any) {
throw new WalletSignTransactionError(error?.message, error);
}
Expand Down
Loading