Skip to content

Commit

Permalink
fix: improve solana transaction sign flow
Browse files Browse the repository at this point in the history
  • Loading branch information
RanGojo committed Apr 16, 2024
1 parent cd0b9a5 commit 65b7be0
Show file tree
Hide file tree
Showing 12 changed files with 456 additions and 265 deletions.
8 changes: 6 additions & 2 deletions signers/signer-solana/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,12 @@
"lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore"
},
"dependencies": {
"@solana/web3.js": "^1.67.2",
"rango-types": "^0.1.59"
"@solana/web3.js": "^1.91.4",
"rango-types": "^0.1.59",
"promise-retry": "^2.0.1"
},
"devDependencies": {
"@types/promise-retry": "^1.1.6"
},
"publishConfig": {
"access": "public"
Expand Down
58 changes: 57 additions & 1 deletion signers/signer-solana/readme.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,59 @@
# @rango-dev/signer-solana

Signer for Solana Transacations generated by Rango API
## Summary

Signer for Rango Solana Transactions

Currecntly all Rango Solana transactions are Versioned (and serialized), only Solana Wrapper is already using the legacy format. (which is used only for SOL <-> WSol routes)

## Versioned Transaction Sign Flow Overview:

1. Get connection and recent blockhash

```ts
const connection = new Connection(SOLANA_RPC_URL, {
commitment: 'confirmed',
disableRetryOnRateLimit: false,
});
const latestBlock = await connection.getLatestBlockhash('confirmed');
```

2. Prepare the transaction

```ts
const transaction = VersionedTransaction.deserialize(
new Uint8Array(tx.serializedMessage)
);
transaction.message.recentBlockhash = recentBlockhash;
```

3. Simulate the transaction

```ts
const { value } = await connection.simulateTransaction(transaction, {
replaceRecentBlockhash: true,
commitment: 'processed',
});
```

4. Sign the transaction

```ts
const signedTransaction = await solanaProvider.signTransaction(
solanaWeb3Transaction
);
const serializedTransaction = Buffer.from(signedTransaction.serialize());
```

5. Send and confirm the transaction (similar to [jupiter suggested code](https://github.com/jup-ag/jupiter-quote-api-node/blob/main/example/utils/transactionSender.ts))

````ts
const { txId, txResponse } = await transactionSenderAndConfirmationWaiter({
connection,
serializedTransaction,
blockhashWithExpiryBlockHeight: {
blockhash: latestBlock.blockhash,
lastValidBlockHeight: latestBlock.lastValidBlockHeight,
},
}); ```
````
221 changes: 0 additions & 221 deletions signers/signer-solana/src/helpers.ts

This file was deleted.

4 changes: 2 additions & 2 deletions signers/signer-solana/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export { DefaultSolanaSigner } from './signer';
export { generalSolanaTransactionExecutor } from './helpers';
export type { SolanaWeb3Signer } from './helpers';
export { generalSolanaTransactionExecutor } from './utils';
export type { SolanaWeb3Signer } from './utils';
40 changes: 4 additions & 36 deletions signers/signer-solana/src/signer.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,9 @@
import type { SolanaExternalProvider } from './utils/types';
import type { GenericSigner, SolanaTransaction } from 'rango-types';

import { executeSolanaTransaction } from './helpers';
import {
PublicKey,
SendOptions,
Transaction,
TransactionSignature,
VersionedTransaction,
} from '@solana/web3.js';

import { SignerError, SignerErrorCode } from 'rango-types';

// https://github.com/solana-labs/wallet-adapter/blob/01c6316ce0725e0a075d6adb237bbcb4128e76ad/packages/wallets/phantom/src/adapter.ts#L30
export interface SolanaExternalProvider {
isPhantom?: boolean;
publicKey?: { toBytes(): Uint8Array };
isConnected: boolean;
signTransaction<T extends Transaction | VersionedTransaction>(
transaction: T
): Promise<T>;
signAllTransactions<T extends Transaction | VersionedTransaction>(
transactions: T[]
): Promise<T[]>;
signAndSendTransaction<T extends Transaction | VersionedTransaction>(
transaction: T,
options?: SendOptions
): Promise<{ signature: TransactionSignature }>;
signMessage(message: Uint8Array): Promise<{ signature: Uint8Array }>;
request(...args: any[]): Promise<any>;
connect(...args: any[]): Promise<any>;
disconnect(): Promise<void>;
accountChanged(newPublicKey: PublicKey): any;
}
import { executeSolanaTransaction } from './utils/main';

export class DefaultSolanaSigner implements GenericSigner<SolanaTransaction> {
private provider: SolanaExternalProvider;
Expand All @@ -56,11 +28,7 @@ export class DefaultSolanaSigner implements GenericSigner<SolanaTransaction> {
}

async signAndSendTx(tx: SolanaTransaction): Promise<{ hash: string }> {
try {
const hash = await executeSolanaTransaction(tx, this.provider);
return { hash };
} catch (error) {
throw new SignerError(SignerErrorCode.SEND_TX_ERROR, undefined, error);
}
const hash = await executeSolanaTransaction(tx, this.provider);
return { hash };
}
}
16 changes: 16 additions & 0 deletions signers/signer-solana/src/utils/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Connection } from '@solana/web3.js';

const IS_DEV = !process.env.NODE_ENV || process.env.NODE_ENV === 'development';
const SOLANA_RPC_URL = !IS_DEV
? 'https://icy-crimson-wind.solana-mainnet.quiknode.pro/c83f94ebeb39a6d6a9d2ab03d4cba2c2af83c5c0/'
: 'https://fluent-still-scion.solana-mainnet.discover.quiknode.pro/fc8be9b8ac7aea382ec591359628e16d8c52ef6a/';

export function getSolanaConnection(): Connection {
return new Connection(SOLANA_RPC_URL, {
commitment: 'confirmed',
disableRetryOnRateLimit: false,
});
}

export const wait = async (time: number) =>
new Promise((resolve) => setTimeout(resolve, time));
2 changes: 2 additions & 0 deletions signers/signer-solana/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export type { SolanaWeb3Signer, SolanaExternalProvider } from './types';
export { generalSolanaTransactionExecutor } from './main';
Loading

0 comments on commit 65b7be0

Please sign in to comment.