Skip to content

Commit

Permalink
chore: add register preferred and getting tns info (#905)
Browse files Browse the repository at this point in the history
  • Loading branch information
ice-chillios authored Jul 12, 2024
1 parent 79917cb commit 59971c5
Show file tree
Hide file tree
Showing 16 changed files with 166 additions and 40 deletions.
8 changes: 8 additions & 0 deletions .changeset/sixty-queens-wave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@swapkit/plugin-thorchain": minor
"@swapkit/helpers": minor
"@swapkit/core": minor
"@swapkit/api": minor
---

tns resovling and register for preferred asset on TC
29 changes: 28 additions & 1 deletion packages/plugins/thorchain/src/basePlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
SwapKitError,
getMemoForDeposit,
getMemoForLeaveAndBond,
getMemoForNamePreferredAssetRegister,
getMemoForNameRegister,
getMemoForSaverDeposit,
getMemoForSaverWithdraw,
Expand Down Expand Up @@ -151,6 +152,31 @@ export function basePlugin({
return depositToProtocol({ assetValue, memo: getMemoForNameRegister(params) });
}

function registerPreferredAsset({
assetValue,
payoutAddress,
name,
ownerAddress,
}: {
assetValue: AssetValue;
payoutAddress?: string;
name: string;
ownerAddress: string;
}) {
const payout = payoutAddress || getWallet(assetValue.chain as SupportedChain).address;

return depositToProtocol({
assetValue,
memo: getMemoForNamePreferredAssetRegister({
asset: assetValue.toString(),
chain: assetValue.chain,
name,
owner: ownerAddress,
payout,
}),
});
}

function nodeAction({ type, assetValue, address }: NodeActionParams) {
const memo =
type === MemoType.UNBOND
Expand Down Expand Up @@ -296,13 +322,14 @@ export function basePlugin({
return {
addLiquidity,
addLiquidityPart,
depositToPool,
approveAssetValue,
createLiquidity,
depositToPool,
getInboundDataByChain,
isAssetValueApproved,
nodeAction,
register,
registerPreferredAsset,
savings,
withdraw,
};
Expand Down
8 changes: 8 additions & 0 deletions packages/plugins/thorchain/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ export type RegisterThornameParams = {
preferredAsset?: string;
};

export type RegisterPreferredAssetParams = {
assetValue: AssetValue;
name: string;
chain: string;
address: string;
owner: string;
};

type CommonWithdrawParams = {
assetValue: AssetValue;
memo?: string;
Expand Down
14 changes: 13 additions & 1 deletion packages/swapkit/api/src/microgard/endpoints.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { AssetValue, BaseDecimal, RequestClient, SwapKitNumber } from "@swapkit/helpers";
import {
AssetValue,
BaseDecimal,
type Chain,
RequestClient,
SwapKitNumber,
} from "@swapkit/helpers";
import type { LiquidityPositionRaw, PoolDetail, PoolPeriod, THORNameDetails } from "./types.ts";

const baseUrl = "https://mu.thorswap.net";
Expand All @@ -25,6 +31,12 @@ export function getLiquidityPositionsRaw(addresses: string[]) {
);
}

export async function getTNSChainAddress({ chain, tns }: { chain: Chain; tns: string }) {
const tnsDetails = await getTHORNameDetails(tns);

return tnsDetails?.entries?.find((e) => e.chain.toLowerCase() === chain.toLowerCase())?.address;
}

export async function getLiquidityPositions(addresses: string[]) {
const rawLiquidityPositions = await getLiquidityPositionsRaw(addresses);

Expand Down
15 changes: 14 additions & 1 deletion packages/swapkit/api/src/thornode/endpoints.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { RequestClient } from "@swapkit/helpers";
import { AssetValue, RequestClient } from "@swapkit/helpers";
import type {
InboundAddressesItem,
LastBlockItem,
MimirData,
NodeItem,
THORNodeTNSDetails,
ThornodeEndpointParams,
} from "./types.ts";

Expand Down Expand Up @@ -39,3 +40,15 @@ export function getMimirInfo(params?: ThornodeEndpointParams) {
export function getInboundAddresses(params?: ThornodeEndpointParams) {
return RequestClient.get<InboundAddressesItem[]>(`${baseUrl(params)}/inbound_addresses`);
}

export function getTHORNodeTNSDetails(params: ThornodeEndpointParams & { name: string }) {
return RequestClient.get<THORNodeTNSDetails>(`${baseUrl(params)}/thorname/${params.name}`);
}

export async function getTNSPreferredAsset(tns: string) {
const tnsDetails = await getTHORNodeTNSDetails({ name: tns });

if (!tnsDetails.preferred_asset || tnsDetails.preferred_asset === ".") return undefined;

return AssetValue.from({ asyncTokenLookup: true, asset: tnsDetails.preferred_asset });
}
12 changes: 12 additions & 0 deletions packages/swapkit/api/src/thornode/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@ export type ThornodeEndpointParams = {
stagenet?: boolean;
};

export type THORNodeTNSDetails = {
name: string;
expire_block_height: number;
owner: string;
preferred_asset: string;
affiliate_collector_rune: string;
aliases: {
chain: string;
address: string;
}[];
};

export type InboundAddressesItem = {
address: string;
chain: string;
Expand Down
4 changes: 3 additions & 1 deletion packages/swapkit/core/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -439,15 +439,17 @@ export function SwapKit<
...availablePlugins,
...connectWalletMethods,

approveAssetValue,
getAddress,
getBalance,
getExplorerAddressUrl: getAddressUrl,
getExplorerTxUrl: getTxUrl,
getWallet,
getAllWallets,
getWalletWithBalance,

approveAssetValue,
isAssetValueApproved,

estimateTransactionFee,
swap,
transfer,
Expand Down
16 changes: 16 additions & 0 deletions packages/swapkit/helpers/src/helpers/__tests__/derivationPath.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { describe, expect, test } from "bun:test";

import type { DerivationPathArray } from "../../types";
import { derivationPathToString } from "../derivationPath";

describe("derivationPathToString", () => {
test("should return the correct string for a full path", () => {
const path = [1, 2, 3, 4, 5] as DerivationPathArray;
expect(derivationPathToString(path)).toEqual("m/1'/2'/3'/4/5");
});

test("should return the correct string for a short path", () => {
const path = [1, 2, 3, 4] as DerivationPathArray;
expect(derivationPathToString(path)).toEqual("m/1'/2'/3'/4");
});
});
16 changes: 16 additions & 0 deletions packages/swapkit/helpers/src/helpers/__tests__/memo.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Chain, MemoType } from "../../types";
import {
getMemoForDeposit,
getMemoForLeaveAndBond,
getMemoForNamePreferredAssetRegister,
getMemoForNameRegister,
getMemoForSaverDeposit,
getMemoForSaverWithdraw,
Expand Down Expand Up @@ -52,6 +53,21 @@ describe("getMemoForNameRegister", () => {
});
});

describe("getMemoForNamePreferredAssetRegister", () => {
test("returns correct memo for single side", () => {
const result = getMemoForNamePreferredAssetRegister({
name: "asdfg",
chain: Chain.Ethereum,
owner: "thor1234",
asset: "ETH.USDC-0XA0B86991C6218B36C1D19D4A2E9EB0CE3606EB48",
payout: "0x6621d872f17109d6601c49edba526ebcfd332d5d",
});
expect(result).toBe(
"~:asdfg:ETH:0x6621d872f17109d6601c49edba526ebcfd332d5d:thor1234:ETH.USDC-0XA0B86991C6218B36C1D19D4A2E9EB0CE3606EB48",
);
});
});

describe("getMemoForDeposit", () => {
test("returns correct memo for single side", () => {
const result = getMemoForDeposit({ chain: Chain.Ethereum, symbol: "ETH" });
Expand Down
16 changes: 2 additions & 14 deletions packages/swapkit/helpers/src/helpers/__tests__/others.test.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,8 @@
import { describe, expect, test } from "bun:test";
import { Chain, type DerivationPathArray } from "../../types";
import { Chain } from "../../types";

import { findAssetBy } from "../asset.ts";
import { derivationPathToString, getTHORNameCost } from "../others.ts";

describe("derivationPathToString", () => {
test("should return the correct string for a full path", () => {
const path = [1, 2, 3, 4, 5] as DerivationPathArray;
expect(derivationPathToString(path)).toEqual("m/1'/2'/3'/4/5");
});

test("should return the correct string for a short path", () => {
const path = [1, 2, 3, 4] as DerivationPathArray;
expect(derivationPathToString(path)).toEqual("m/1'/2'/3'/4");
});
});
import { getTHORNameCost } from "../others.ts";

describe("getTHORNameCost", () => {
describe("for correct values", () => {
Expand Down
8 changes: 8 additions & 0 deletions packages/swapkit/helpers/src/helpers/derivationPath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ const updatedLastIndex = (path: DerivationPathArray, index: number) => {
return newPath as DerivationPathArray;
};

export function derivationPathToString([network, chainId, account, change, index]:
| [number, number, number, number, number | undefined]
| DerivationPathArray) {
const shortPath = typeof index !== "number";

return `m/${network}'/${chainId}'/${account}'/${change}${shortPath ? "" : `/${index}`}`;
}

export function getDerivationPathFor({ chain, index, addressIndex = 0, type }: Params) {
if (EVMChains.includes(chain as EVMChain)) {
if (type === "legacy") return [44, 60, 0, index] as DerivationPathArray;
Expand Down
18 changes: 18 additions & 0 deletions packages/swapkit/helpers/src/helpers/memo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,24 @@ export function getMemoForNameRegister({
return `${baseMemo}${ownerAssignmentOrChangePart}`;
}

export function getMemoForNamePreferredAssetRegister({
name,
chain,
asset,
payout,
owner,
}: {
name: string;
chain: Chain;
asset: string;
payout: string;
owner: string;
}) {
const memo = [name, chain, payout, owner, asset].join(":");

return `${MemoType.NAME_REGISTER}:${memo}`;
}

export function getMemoForLoan(
memoType: MemoType.OPEN_LOAN | MemoType.CLOSE_LOAN,
{
Expand Down
9 changes: 0 additions & 9 deletions packages/swapkit/helpers/src/helpers/others.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { type ErrorKeys, SwapKitError } from "../modules/swapKitError";
import { Chain } from "../types";
import type { DerivationPathArray } from "../types/derivationPath";

// 10 rune for register, 1 rune per year
// MINIMUM_REGISTRATION_FEE = 11
Expand All @@ -25,14 +24,6 @@ export function getMAYANameCost(numberOfYears: number) {
return Math.round((10 + numberOfYears * 1.0512) * 1e10) / 1e10;
}

export function derivationPathToString([network, chainId, account, change, index]:
| [number, number, number, number, number | undefined]
| DerivationPathArray) {
const shortPath = typeof index !== "number";

return `m/${network}'/${chainId}'/${account}'/${change}${shortPath ? "" : `/${index}`}`;
}

export function wrapWithThrow<T>(fn: () => T, errorKey?: ErrorKeys) {
try {
return fn();
Expand Down
9 changes: 0 additions & 9 deletions packages/swapkit/helpers/src/helpers/web3wallets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,6 @@ declare const window: {
braveSolana: Todo;
} & Window;

// declare global {
// interface Window {
// ethereum: EthereumWindowProvider;
// trustwallet: EthereumWindowProvider;
// coinbaseWalletExtension: EthereumWindowProvider;
// braveSolana: Todo;
// }
// }

type NetworkParams = {
chainId: ChainId;
chainName: string;
Expand Down
2 changes: 1 addition & 1 deletion packages/swapkit/helpers/src/types/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ export type WalletTxParams = {
};

export enum MemoType {
NAME_REGISTER = "~",
BOND = "BOND",
DEPOSIT = "+",
LEAVE = "LEAVE",
NAME_REGISTER = "~",
UNBOND = "UNBOND",
WITHDRAW = "-",
OPEN_LOAN = "$+",
Expand Down
22 changes: 19 additions & 3 deletions playgrounds/vite/src/TNS/index.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
import { AssetValue } from "@swapkit/sdk";
import { Chain } from "@swapkit/sdk";
import { AssetValue, Chain, SwapKitApi, type THORNameDetails } from "@swapkit/sdk";
import { useCallback, useState } from "react";
import type { SwapKitClient } from "../swapKitClient";

export default function TNS({ skClient }: { skClient: SwapKitClient }) {
const [selectedChain, setSelectedChain] = useState(Chain.THORChain);
const [name, setName] = useState("");
const [tnsSearch, setTnsSearch] = useState("");
const [tnsDetail, setTnsDetail] = useState<THORNameDetails>();

const checkTns = useCallback(async () => {
const tnsDetail = await SwapKitApi.getTHORNameDetails(tnsSearch);
setTnsDetail(tnsDetail);
}, [tnsSearch]);

const registerTns = useCallback(async () => {
// const owner = skClient.getAddress(Chain.THORChain);
const address = skClient.getAddress(selectedChain);

try {
const txHash = await skClient.thorchain.registerThorname({
const txHash = await skClient.thorchain.registerTHORName({
assetValue: AssetValue.from({ chain: Chain.THORChain, value: 1 }),
address,
name,
Expand All @@ -30,6 +36,16 @@ export default function TNS({ skClient }: { skClient: SwapKitClient }) {
<div>
<h3>TNS</h3>

<div>
<span>Check TNS info</span>
<input onChange={(e) => setTnsSearch(e.target.value)} value={tnsSearch} />
<button onClick={checkTns} type="button">
Check
</button>

{tnsDetail && <div>{JSON.stringify(tnsDetail)}</div>}
</div>

<div style={{ cursor: skClient ? "default" : "not-allowed" }}>
<div
style={{
Expand Down

0 comments on commit 59971c5

Please sign in to comment.