Skip to content

Commit

Permalink
solana signing
Browse files Browse the repository at this point in the history
  • Loading branch information
nnoln committed Nov 15, 2024
1 parent 6ecd5d0 commit 42e6f2f
Show file tree
Hide file tree
Showing 6 changed files with 467 additions and 27 deletions.
9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,16 @@
"ethers": "6.8.1",
"ethers-multicall-provider": "^5.0.0",
"lodash": "^4.17.21",
"long": "^5.2.3"
"long": "^5.2.3",
"@solana/web3.js": "1.95.3",
"@project-serum/anchor": "^0.26.0",
"bs58": "^6.0.0"
},
"resolutions": {
"semver": "^7.5.4"
},
"devDependencies": {
"@0xsquid/squid-types": "0.1.85",
"@0xsquid/squid-types": "0.1.117",
"@babel/core": "^7.18.10",
"@babel/preset-env": "^7.18.10",
"@babel/preset-typescript": "^7.18.6",
Expand Down Expand Up @@ -102,4 +105,4 @@
"publish": false
}
}
}
}
1 change: 1 addition & 0 deletions src/handlers/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from "./evm";
export * from "./cosmos";
export * from "./solana";
53 changes: 53 additions & 0 deletions src/handlers/solana/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { Wallet, web3 } from "@project-serum/anchor";
import { Connection, VersionedTransaction } from "@solana/web3.js";
import { ExecuteRoute, SolanaSigner, SolanaTxResponse } from "types";

export class SolanaHandler {
async executeRoute({ data }: { data: ExecuteRoute }): Promise<SolanaTxResponse> {
const { route } = data;
const signer = data.signer as SolanaSigner;

const connection = new Connection(web3.clusterApiUrl("mainnet-beta"), "confirmed");

// currently we support signing only for Jupiter
const swapRequest = route.transactionRequest!.data;

// build tx object
const swapTransactionBuf = Buffer.from(swapRequest, "base64");
let transaction = VersionedTransaction.deserialize(swapTransactionBuf);

let tx: string;

// sign tx using provided signer
if (signer instanceof Wallet || signer.constructor.name === "NodeWallet") {
// offline signer
const wallet = signer as Wallet;
transaction.sign([wallet.payer]);

// send tx onchain
const rawTransaction = transaction.serialize();
const txid = await connection.sendRawTransaction(rawTransaction, {
skipPreflight: true,
maxRetries: 2,
});

// verify tx was broadcasted
const latestBlockHash = await connection.getLatestBlockhash();
await connection.confirmTransaction({
blockhash: latestBlockHash.blockhash,
lastValidBlockHeight: latestBlockHash.lastValidBlockHeight + 10,
signature: txid,
});

tx = txid;
} else {
// phantom wallet signer
const { signature } = signer.signAndSendTransaction(transaction);
await connection.getSignatureStatus(signature, { searchTransactionHistory: true });

tx = signature;
}

return { tx };
}
}
6 changes: 5 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
import HttpAdapter from "./adapter/HttpAdapter";
import { Config, ExecuteRoute, GetStatus, TransactionResponses } from "./types";

import { CosmosHandler, EvmHandler } from "./handlers";
import { CosmosHandler, EvmHandler, SolanaHandler } from "./handlers";
import { TokensChains } from "./utils/TokensChains";

import { getCosmosChainsForChainIds } from "./utils/cosmos";
Expand All @@ -29,6 +29,7 @@ export class Squid extends TokensChains {
private handlers = {
evm: new EvmHandler(),
cosmos: new CosmosHandler(),
solana: new SolanaHandler(),
};

public initialized = false;
Expand Down Expand Up @@ -150,6 +151,9 @@ export class Squid extends TokensChains {
params: cosmosParams,
});

case ChainType.SOLANA:
return this.handlers.solana.executeRoute({ data });

default:
throw new Error(`Method not supported given chain type ${fromChain.chainType}`);
}
Expand Down
16 changes: 14 additions & 2 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { SigningStargateClient } from "@cosmjs/stargate";

import { EvmWallet, TransactionResponse, RpcProvider, Contract, GasData } from "./ethers";
import { TxRaw } from "cosmjs-types/cosmos/tx/v1beta1/tx";
import { VersionedTransaction } from "@solana/web3.js";
import { Wallet } from "@project-serum/anchor";

export * from "@0xsquid/squid-types";
export * from "./cosmos";
Expand Down Expand Up @@ -36,8 +38,14 @@ export type ExecutionSettings = {

export type CosmosSigner = SigningStargateClient;

export interface PhantomSigner {
signAndSendTransaction(tx: VersionedTransaction): { signature: string };
}

export type SolanaSigner = Wallet | PhantomSigner;

export type ExecuteRoute = {
signer: EvmWallet | CosmosSigner;
signer: EvmWallet | CosmosSigner | SolanaSigner;
route: _RouteResponse["route"];
executionSettings?: ExecutionSettings;
overrides?: OverrideParams;
Expand All @@ -49,7 +57,11 @@ export type RouteResponse = _RouteResponse & {
integratorId?: string;
};

export type TransactionResponses = TransactionResponse | TxRaw;
export type SolanaTxResponse = {
tx: string;
};

export type TransactionResponses = TransactionResponse | TxRaw | SolanaTxResponse;

export type GetStatus = {
transactionId: string;
Expand Down
Loading

0 comments on commit 42e6f2f

Please sign in to comment.