Skip to content

Commit

Permalink
chore: support convert to alloy token
Browse files Browse the repository at this point in the history
  • Loading branch information
trung2891 committed Sep 12, 2024
1 parent de90fb7 commit 4c1b44a
Show file tree
Hide file tree
Showing 6 changed files with 240 additions and 102 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,5 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts

.env
18 changes: 18 additions & 0 deletions components/page/bridge/helper.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
import { token } from "@oraichain/oraidex-common/build/typechain-types/@openzeppelin/contracts";
import {
AlloyedPool,
OsmosisAlloyedPools,
OsmosisTokenList,
} from "../../../constants/tokens";
import { fromBech32, toBech32 } from "@cosmjs/encoding";
import { Environment } from "@/constants/ton";

export const getAddressCosmos = (addr, prefix = "osmo") => {
if (!addr) throw "Address not found";
const { data } = fromBech32(addr);
const cosmosAddress = toBech32(prefix, data);
return cosmosAddress;
};

export const canConvertToAlloyedToken = (
coingeckoId: string
): AlloyedPool | undefined => {
const hasAlloyed = OsmosisTokenList(Environment.Mainnet).find(
(token) => token.coingeckoId == coingeckoId && token?.alloyedToken
);
return hasAlloyed
? OsmosisAlloyedPools.find((pool) => pool.alloyedToken == hasAlloyed.denom)
: undefined;
};
212 changes: 183 additions & 29 deletions components/page/bridge/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import {
useAuthOraiAddress,
useAuthTonAddress,
} from "@/stores/authentication/selector";
import { toBinary } from "@cosmjs/cosmwasm-stargate";
import { ExecuteInstruction, toBinary } from "@cosmjs/cosmwasm-stargate";
import {
BigDecimal,
CW20_DECIMALS,
Expand All @@ -41,6 +41,8 @@ import {
CosmosChainId,
calculateTimeoutTimestamp,
getCosmosGasPrice,
OSMOSIS_ROUTER_CONTRACT,
getEncodedExecuteContractMsgs,
} from "@oraichain/oraidex-common";
import {
BridgeAdapter,
Expand Down Expand Up @@ -84,15 +86,17 @@ import { useCoinGeckoPrices } from "@/hooks/useCoingecko";
import SelectCommon from "@/components/commons/select";
import { NetworkWithIcon } from "@/constants/chainInfo";
import {
SwapAndAction,
UniversalSwapHelper,
buildUniversalSwapMemo,
} from "@oraichain/oraidex-universal-swap";
import { coin } from "@cosmjs/proto-signing";
import { Coin, coin, coins } from "@cosmjs/proto-signing";
import { getCosmWasmClient } from "@/libs/cosmjs";
import { GasPrice } from "@cosmjs/stargate";
import { getAddressCosmos } from "./helper";
import { canConvertToAlloyedToken, getAddressCosmos } from "./helper";
import { ArrowDownIcon } from "@/assets/icons/arrow";


const Bridge = () => {
const oraiAddress = useAuthOraiAddress();
const tonAddress = useAuthTonAddress();
Expand Down Expand Up @@ -304,6 +308,46 @@ const Bridge = () => {
}
};

const buildOsorSwapMsg = ({ user_swap, min_asset, timeout_timestamp, post_swap_action, affiliates }: SwapAndAction, isInitial: boolean, fromAddress?: string, funds?: Coin[]) => {
const msg = {
msg: {
swap_and_action: {
user_swap,
min_asset,
timeout_timestamp,
post_swap_action,
affiliates,
},
}
};

if (isInitial) {
if (!fromAddress) {
throw new Error("Missing fromAddress");
}
return {
msgActionSwap: {
sender: fromAddress,
contractAddress: OSMOSIS_ROUTER_CONTRACT,
funds,
...msg
}
};
}

return {
msgActionSwap: {
wasm: {
contract: OSMOSIS_ROUTER_CONTRACT,
...msg
}
}
};
};




const handleBridgeFromTon = async () => {
try {
if (!oraiAddress) throw "Please connect OWallet or Kelpr!";
Expand Down Expand Up @@ -348,11 +392,46 @@ const Bridge = () => {
: BRIDGE_TON_TO_ORAI_MINIMUM_GAS.toString();
const timeout = BigInt(Math.floor(new Date().getTime() / 1000) + 3600);


let memo = beginCell().endCell();

if (toNetwork.id === NetworkList["osmosis-1"].id) {
const osmosisAddress = await window.Keplr.getKeplrAddr(toNetwork.id);
let osmosisReceiver = osmosisAddress;
if (!osmosisAddress) throw "Please connect OWallet or Kelpr!";

let osorRouterMemo = "";
let hasAlloyedPool = canConvertToAlloyedToken(token.coingeckoId);
if (hasAlloyedPool) {
osmosisReceiver = OSMOSIS_ROUTER_CONTRACT;
let { msgActionSwap } = buildOsorSwapMsg({
user_swap: {
swap_exact_asset_in: {
swap_venue_name: "osmosis-poolmanager",
operations: [{
pool: hasAlloyedPool.poolId,
denom_in: hasAlloyedPool.sourceToken,
denom_out: hasAlloyedPool.alloyedToken
}]
}
},
min_asset: {
native: {
denom: hasAlloyedPool.alloyedToken,
amount: "0"
}
}, // consider add minimum receive (Currently, alloy pool is swap 1-1, so no't need to add min_asset
timeout_timestamp: Number(calculateTimeoutTimestamp(3600)),
post_swap_action: {
transfer: {
to_address: osmosisAddress,
},
},
affiliates: []
}, false);
osorRouterMemo = JSON.stringify(msgActionSwap);
}

const buildMemoSwap = buildUniversalSwapMemo(
{
minimumReceive: "0",
Expand All @@ -364,8 +443,8 @@ const Bridge = () => {
{
sourceChannel: "channel-13",
sourcePort: "transfer",
receiver: osmosisAddress,
memo: "",
receiver: osmosisReceiver,
memo: osorRouterMemo,
recoverAddress: oraiAddress,
},
undefined
Expand Down Expand Up @@ -541,24 +620,99 @@ const Bridge = () => {
},
});
}
if (isFromOraichainToOsmosis) {
let hasAlloyedPool = canConvertToAlloyedToken(token.coingeckoId);
if (hasAlloyedPool) {
let { msgActionSwap } = buildOsorSwapMsg({
user_swap: {
swap_exact_asset_in: {
swap_venue_name: "osmosis-poolmanager",
operations: [{
pool: hasAlloyedPool.poolId,
denom_in: hasAlloyedPool.sourceToken,
denom_out: hasAlloyedPool.alloyedToken
}]
}
},
min_asset: {
native: {
denom: hasAlloyedPool.alloyedToken,
amount: "0"
}
}, // consider add minimum receive (Currently, alloy pool is swap 1-1, so no't need to add min_asset
timeout_timestamp: Number(calculateTimeoutTimestamp(3600)),
post_swap_action: {
transfer: {
to_address: toAddress,
},
},
affiliates: []
}, false);
memo = JSON.stringify(msgActionSwap);
toAddress = OSMOSIS_ROUTER_CONTRACT;
}
}

const ibcInfo = UniversalSwapHelper.getIbcInfo(fromChainId, toChainId);
const msgTransfer = [
{
typeUrl: "/ibc.applications.transfer.v1.MsgTransfer",
value: MsgTransfer.fromPartial({
sourcePort: ibcInfo.source,
sourceChannel: ibcInfo.channel,
token: coin(
toAmount(amount, token.decimal).toString(),
token.denom
),
sender: fromAddress,
receiver: toAddress,
memo,
timeoutTimestamp: calculateTimeoutTimestamp(ibcInfo.timeout),
}),
},
];
let executeMsg;
if (fromNetwork.id === NetworkList["osmosis-1"].id && token.alloyedToken) {
let hasAlloyedPool = canConvertToAlloyedToken(token.coingeckoId);
if (!hasAlloyedPool) throw new Error("AlloyPool does not exist!");
// need convert from alloyed first
let { msgActionSwap } = buildOsorSwapMsg({
user_swap: {
swap_exact_asset_in: {
swap_venue_name: "osmosis-poolmanager",
operations: [{
pool: hasAlloyedPool.poolId,
denom_in: hasAlloyedPool.alloyedToken,
denom_out: hasAlloyedPool.sourceToken
}]
}
},
min_asset: {
native: {
denom: hasAlloyedPool.sourceToken,
amount: "0"
}
}, // consider add minimum receive (Currently, alloy pool is swap 1-1, so no't need to add min_asset
timeout_timestamp: Number(calculateTimeoutTimestamp(3600)),
post_swap_action: {
ibc_transfer: {
ibc_info: {
source_channel: ibcInfo.channel,
receiver: toAddress,
memo,
recover_address: fromAddress
}
}
},
affiliates: []
}, true, fromAddress, coins(
toAmount(amount, token.decimal).toString(),
token.denom
));

executeMsg = getEncodedExecuteContractMsgs(fromAddress, [msgActionSwap as ExecuteInstruction])

} else
executeMsg = [
{
typeUrl: "/ibc.applications.transfer.v1.MsgTransfer",
value: MsgTransfer.fromPartial({
sourcePort: ibcInfo.source,
sourceChannel: ibcInfo.channel,
token: coin(
toAmount(amount, token.decimal).toString(),
token.denom
),
sender: fromAddress,
receiver: toAddress,
memo,
timeoutTimestamp: calculateTimeoutTimestamp(ibcInfo.timeout),
}),
},
];

const findCosmosChain = cosmosChains.find(
(chain) => chain.chainId === fromNetwork.id
Expand All @@ -576,7 +730,7 @@ const Bridge = () => {
);
const tx = await client.signAndBroadcast(
fromAddress,
msgTransfer,
executeMsg,
"auto"
);

Expand Down Expand Up @@ -979,10 +1133,10 @@ const Bridge = () => {
{/* <span className={styles.value}>1 TON</span> */}
<span className={styles.value}>
{toNetwork.id === NetworkList.ton.id ||
fromNetwork.id === NetworkList.ton.id
fromNetwork.id === NetworkList.ton.id
? numberWithCommas(bridgeFee || 0, undefined, {
maximumFractionDigits: CW20_DECIMALS,
})
maximumFractionDigits: CW20_DECIMALS,
})
: "0"}{" "}
{token?.symbol}
</span>
Expand All @@ -994,9 +1148,9 @@ const Bridge = () => {
{!token
? "--"
: formatDisplayNumber(
new BigDecimal(tokenFee).mul(amount || 0).toNumber(),
DECIMAL_TOKEN_FEE
)}{" "}
new BigDecimal(tokenFee).mul(amount || 0).toNumber(),
DECIMAL_TOKEN_FEE
)}{" "}
{token?.symbol}
</span>
</div>
Expand Down
31 changes: 31 additions & 0 deletions constants/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export type TokenType = {
denom: string;
coingeckoId: string;
decimal: number;
alloyedToken?: boolean;
};

export const TON_DENOM = `factory/orai1wuvhex9xqs3r539mvc6mtm7n20fcj3qr2m0y9khx6n5vtlngfzes3k0rq9/ton`;
Expand Down Expand Up @@ -72,9 +73,12 @@ export const OraichainTokenList = (network: Environment): TokenType[] => [
export const OsmosisTokenDenom = {
[Environment.Mainnet]: {
ton: "ibc/905889A7F0B94F1CE1506D9BADF13AE9141E4CBDBCD565E1DFC7AE418B3E3E98",
allTon:
"factory/osmo12lnwf54yd30p6amzaged2atln8k0l32n7ncxf04ctg7u7ymnsy7qkqgsw4/alloyed/allTON",
},
[Environment.Staging]: {
ton: "ibc/64BF62F8C7C0B1AADBCFBCB45E778DA144E86804420AC5AD4F29D141A14A031B",
alloyedTon: "", // not exist
},
};

Expand All @@ -89,6 +93,17 @@ export const OsmosisTokenList = (network: Environment): TokenType[] => [
coingeckoId: "the-open-network",
decimal: 9,
},
{
chainId: "osmosis-1",
name: "Alloyed Ton",
symbol: "allTON",
Icon: TonNetworkICon,
contractAddress: null,
denom: OsmosisTokenDenom[network].allTon,
coingeckoId: "the-open-network",
decimal: 9,
alloyedToken: true,
},
];

export const TonTokenList = (network: Environment): TokenType[] => [
Expand Down Expand Up @@ -139,3 +154,19 @@ export const TonTokenList = (network: Environment): TokenType[] => [
// ]
// : []),
];

export type AlloyedPool = {
poolId: string;
alloyedToken: string;
sourceToken: string;
};

export const OsmosisAlloyedPools: AlloyedPool[] = [
{
poolId: "2161",
alloyedToken:
"factory/osmo12lnwf54yd30p6amzaged2atln8k0l32n7ncxf04ctg7u7ymnsy7qkqgsw4/alloyed/allTON",
sourceToken:
"ibc/905889A7F0B94F1CE1506D9BADF13AE9141E4CBDBCD565E1DFC7AE418B3E3E98",
},
];
Loading

0 comments on commit 4c1b44a

Please sign in to comment.