@elizaos/plugin-squid-router
Version:
ElizaOS plugin for cross-chain token swaps using Squid Router
197 lines (177 loc) • 5.54 kB
text/typescript
import type {
IAgentRuntime,
Memory,
Provider,
ProviderResult,
State,
} from "@elizaos/core";
import { Squid } from "@0xsquid/sdk";
import { ethers } from "ethers";
import {
type ChainData,
ChainType,
type RouteRequest,
type RouteResponse,
type Token,
} from "@0xsquid/squid-types";
import { validateSquidRouterConfig } from "../helpers/utils.ts";
import type {
ExecuteRoute,
TransactionResponses,
} from "@0xsquid/sdk/dist/types";
import { nativeTokenConstant, type SquidToken } from "../types";
const getSDK = (baseUrl: string, integratorId: string): Squid => {
const squid = new Squid({
baseUrl: baseUrl,
integratorId: integratorId,
});
return squid;
};
export class SquidRouterProvider {
private squid: Squid;
constructor(
private squidSDKUrl: string,
private squidIntegratorID: string
) {
this.squid = getSDK(squidSDKUrl, squidIntegratorID);
}
async initialize(): Promise<void> {
if (!this.squid.initialized) {
await this.squid.init();
}
}
getSquidObject(): Squid {
return this.squid;
}
getChains(): ChainData[] {
return this.squid.chains;
}
getTokens(): Token[] {
return this.squid.tokens;
}
getChain(targetChainName: string): ChainData | undefined {
const normalizedTarget = targetChainName.toLowerCase();
const targetChain = this.getChains().find(
(chain) => chain.networkName.toLowerCase() === normalizedTarget
);
//For now only support EVM. Will add Cosmos, Solana in later releases
if (targetChain && targetChain.chainType === ChainType.EVM) {
return targetChain;
}
return undefined;
}
getToken(
targetChain: ChainData,
targetTokenSymbol: string
): SquidToken | undefined {
const normalizedTargetToken = targetTokenSymbol.toLowerCase();
if (normalizedTargetToken === targetChain.nativeCurrency.symbol) {
return {
address: nativeTokenConstant,
isNative: true,
symbol: targetTokenSymbol,
decimals: targetChain.nativeCurrency.decimals,
enabled: true,
};
}
const targetToken = this.getTokens().find(
(token) =>
token.symbol.toLowerCase() === normalizedTargetToken &&
token.chainId === targetChain.chainId
);
if (!targetToken) {
return undefined;
}
return {
address: targetToken.address,
isNative: false,
symbol: targetTokenSymbol,
decimals: targetToken.decimals,
enabled: targetToken.disabled ?? true,
};
}
async getRoute(route: RouteRequest): Promise<RouteResponse> {
return await this.squid.getRoute(route);
}
async executeRoute(route: ExecuteRoute): Promise<TransactionResponses> {
return await this.squid.executeRoute(route);
}
async getEVMSignerForChain(
chain: ChainData,
runtime: IAgentRuntime
): Promise<ethers.Signer> {
try {
if (chain.chainType === ChainType.EVM) {
const provider = new ethers.JsonRpcProvider(chain.rpc);
return new ethers.Wallet(
runtime.getSetting("SQUID_EVM_PRIVATE_KEY"),
provider
);
}
throw new Error("Cannot instantiate EVM signer for non-EVM chain"); // Fix: Use template literal and remove else
} catch (error) {
throw new Error(`Cannot instantiate EVM signer: ${error}`); // Fix: Use template literal
}
}
// async getEVMSignerForChain(chain: ChainData, runtime): Promise<ethers.Signer> {
// try {
// if(chain.chainType === ChainType.EVM) {
// const provider = new ethers.JsonRpcProvider(chain.rpc);
// return new ethers.Wallet(runtime.getSetting("SQUID_EVM_PRIVATE_KEY"), provider);
// } else {
// throw Error("Cannot instantiate EVM signer for non-EVM chain");
// }
// } catch (error) {
// throw Error("Cannot instantiate EVM signer: "+error);
// }
// }
}
export const initSquidRouterProvider = async (runtime: IAgentRuntime) => {
await validateSquidRouterConfig(runtime);
const sdkUrl = runtime.getSetting("SQUID_SDK_URL");
const integratorId = runtime.getSetting("SQUID_INTEGRATOR_ID");
return new SquidRouterProvider(sdkUrl, integratorId);
};
const squidRouterProvider: Provider = {
name: "squidRouter",
get: async (
runtime: IAgentRuntime,
_message: Memory,
state: State
): Promise<ProviderResult> => {
try {
const provider = await initSquidRouterProvider(runtime);
await provider.initialize();
const chains = provider.getChains();
const tokens = provider.getTokens();
return {
text: "Squid Router provider setup successful.",
values: {
sdkUrl: runtime.getSetting("SQUID_SDK_URL"),
integratorId: runtime.getSetting("SQUID_INTEGRATOR_ID"),
address: runtime.getSetting("SQUID_EVM_ADDRESS"),
chainsCount: chains.length,
tokensCount: tokens.length,
},
data: {
chains: chains.map((chain) => ({
chainId: chain.chainId,
chainName: chain.networkName,
chainType: chain.chainType,
})),
initialized: true,
},
};
} catch (error) {
console.error("Error in Squid Router provider:", error);
return {
text: "Error initializing Squid Router provider",
values: {
error: error instanceof Error ? error.message : String(error),
},
};
}
},
};
// Module exports
export { squidRouterProvider };