Skip to content

Commit

Permalink
Can fetch and prepare swap (#3)
Browse files Browse the repository at this point in the history
* Can fetch and prepare swap

* Don't override common headers
  • Loading branch information
gidonkatten authored Sep 28, 2023
1 parent aabdf98 commit 2341e25
Show file tree
Hide file tree
Showing 8 changed files with 310 additions and 5 deletions.
11 changes: 11 additions & 0 deletions packages/folks-router-js-sdk/examples/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Algodv2, generateAccount, Indexer, mnemonicToSecretKey } from "algosdk";

// TODO: Replace
// export const sender = mnemonicToSecretKey("");
export const sender = generateAccount();

export const MainnetAlgodClient = new Algodv2("", "https://mainnet-api.algonode.cloud/", 443);
export const MainnetIndexerClient = new Indexer("", "https://mainnet-idx.algonode.cloud/", 443);

export const TestnetAlgodClient = new Algodv2("", "https://testnet-api.algonode.cloud/", 443);
export const TestnetIndexerClient = new Indexer("", "https://testnet-idx.algonode.cloud/", 443);
27 changes: 27 additions & 0 deletions packages/folks-router-js-sdk/examples/swap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { decodeUnsignedTransaction } from "algosdk";
import { FolksRouterClient, Network, SwapMode } from "../src";
import { MainnetAlgodClient, sender } from "./config";

async function main() {
const user = sender;
const algod = MainnetAlgodClient;
const client = new FolksRouterClient(Network.MAINNET);

// fetch quote
const quote = await client.fetchSwapQuote(
0,
31566704,
BigInt(10e6),
SwapMode.FIXED_INPUT,
);

// prepare swap
const base64txns = await client.prepareSwapTransactions(user.addr, BigInt(10), quote);
const unsignedTxns = base64txns.map(txn => decodeUnsignedTransaction(Buffer.from(txn, "base64")));
const signedTxns = unsignedTxns.map(txn => txn.signTxn(user.sk));

// submit
await algod.sendRawTransaction(signedTxns).do();
}

main().catch(console.error);
8 changes: 6 additions & 2 deletions packages/folks-router-js-sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,16 @@
"scripts": {
"clean": "rm -rf ./dist",
"build": "npm run clean && tsc",
"typecheck": "tsc --noEmit"
"typecheck": "tsc --noEmit",
"example": "ts-node --project tsconfig.json"
},
"dependencies": {
"algosdk": "^2.6.0"
"algosdk": "^2.6.0",
"axios": "^1.5.1"
},
"devDependencies": {
"@types/node": "^20.7.1",
"ts-node": "^10.9.1",
"tsconfig": "workspace:*",
"typedoc": "^0.25.1",
"typescript": "^5.2.2"
Expand Down
73 changes: 73 additions & 0 deletions packages/folks-router-js-sdk/src/FolksRouterClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import axios, { AxiosInstance} from "axios";
import { Network, SwapMode, SwapQuote, SwapTransactions } from "./types";

const BASE_URL = "https://api.folksrouter.io";

export class FolksRouterClient {
private readonly network: Network;
private readonly api: AxiosInstance;

constructor(network: Network, apiKey?: string) {
// construct url
let url = BASE_URL;
if (network === Network.TESTNET) url += "/testnet";
url += "/v1";
if (apiKey !== undefined) {
url += "/pro";
}

// set
this.network = network;
this.api = axios.create({ baseURL: url, headers: { "x-api-key": apiKey }});
}

public async fetchSwapQuote(
fromAssetId: number,
toAssetId: number,
amount: number | bigint,
swapMode: SwapMode,
maxGroupSize?: number,
feeBps?: number | bigint,
referrer?: string,
): Promise<SwapQuote> {
const { data } = await this.api.get("/fetch/quote", {
params: {
network: this.network,
fromAsset: fromAssetId,
toAsset: toAssetId,
amount,
type: swapMode,
maxGroupSize,
feeBps,
referrer,
}
});
if (!data.success) throw Error(data.errors);

const { quoteAmount, priceImpact, microalgoTxnsFee, txnPayload } = data.result;

return {
quoteAmount: BigInt(quoteAmount),
priceImpact,
microalgoTxnsFee,
txnPayload,
};
}

public async prepareSwapTransactions(
userAddress: string,
slippageBps: number | bigint,
swapQuote: SwapQuote,
): Promise<SwapTransactions> {
const { data } = await this.api.get("/prepare/swap", {
params: {
userAddress,
slippageBps,
txnPayload: swapQuote.txnPayload,
}
});
if (!data.success) throw Error(data.errors);

return data.result;
}
}
2 changes: 2 additions & 0 deletions packages/folks-router-js-sdk/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ export * from "./abiContracts";

export * from "./constants/mainnetConstants";
export * from "./constants/testnetConstants";

export * from "./FolksRouterClient";
23 changes: 22 additions & 1 deletion packages/folks-router-js-sdk/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,25 @@
export type ReferrerGroupTransaction = {
type ReferrerGroupTransaction = {
unsignedTxn: Uint8Array;
lsig?: Uint8Array;
}[];

enum Network {
MAINNET = "mainnet",
TESTNET = "testnet",
}

enum SwapMode {
FIXED_INPUT = "FIXED_INPUT",
FIXED_OUTPUT = "FIXED_OUTPUT",
}

interface SwapQuote {
quoteAmount: bigint;
priceImpact: number;
microalgoTxnsFee: number;
txnPayload: string;
}

type SwapTransactions = string[];

export { ReferrerGroupTransaction, Network, SwapMode, SwapQuote, SwapTransactions }
3 changes: 2 additions & 1 deletion packages/folks-router-js-sdk/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
"outDir": "dist",
"declarationDir": "dist/types",
"sourceMap": true,
"isolatedModules": false,
"exactOptionalPropertyTypes": false,
"resolveJsonModule": true,
},
"include": ["./src/index.ts"],
"include": ["./src/index.ts", "./examples/*"],
"exclude": ["dist", "build", "node_modules"]
}
Loading

0 comments on commit 2341e25

Please sign in to comment.