sdk/js: fix terra transfer, getOriginalAsset

Change-Id: I8c7609d133c32cea9a773e05fa6c115c4a8e8666
This commit is contained in:
Evan Gray 2021-08-30 21:07:09 -04:00
parent f7979ee8b1
commit 7589d33665
12 changed files with 87 additions and 62 deletions

View File

@ -158,21 +158,23 @@ async function terra(
wallet: ConnectedWallet,
asset: string,
amount: string,
decimals: number,
targetChain: ChainId,
targetAddress: Uint8Array
) {
dispatch(setIsSending(true));
try {
const msg = await transferFromTerra(
const amountParsed = parseUnits(amount, decimals).toString();
const msgs = await transferFromTerra(
wallet.terraAddress,
TERRA_TOKEN_BRIDGE_ADDRESS,
asset,
amount,
amountParsed,
targetChain,
targetAddress
);
const result = await wallet.post({
msgs: [msg],
msgs: [...msgs],
memo: "Wormhole - Initiate Transfer",
});
enqueueSnackbar("Transaction confirmed", { variant: "success" });
@ -276,6 +278,7 @@ export function useHandleTransfer() {
terraWallet,
sourceAsset,
amount,
decimals,
targetChain,
targetAddress
);

View File

@ -2,6 +2,7 @@ import {
CHAIN_ID_ETH,
CHAIN_ID_SOLANA,
CHAIN_ID_TERRA,
canonicalAddress,
} from "@certusone/wormhole-sdk";
import { arrayify, zeroPad } from "@ethersproject/bytes";
import {
@ -22,7 +23,6 @@ import {
} from "../store/selectors";
import { setTargetAddressHex } from "../store/transferSlice";
import { uint8ArrayToHex } from "../utils/array";
import { canonicalAddress } from "../utils/terra";
function useSyncTargetAddress(shouldFire: boolean) {
const dispatch = useDispatch();

View File

@ -3,10 +3,10 @@ import {
CHAIN_ID_ETH,
CHAIN_ID_SOLANA,
CHAIN_ID_TERRA,
humanAddress,
} from "@certusone/wormhole-sdk";
import { PublicKey } from "@solana/web3.js";
import { hexValue } from "ethers/lib/utils";
import { humanAddress } from "./terra";
export const uint8ArrayToHex = (a: Uint8Array) =>
Buffer.from(a).toString("hex");

View File

@ -6,6 +6,7 @@ import {
WormholeWrappedInfo,
} from "@certusone/wormhole-sdk";
import { Connection } from "@solana/web3.js";
import { LCDClient } from "@terra-money/terra.js";
import { ethers } from "ethers";
import { uint8ArrayToHex } from "./array";
import {
@ -13,9 +14,7 @@ import {
SOLANA_HOST,
SOL_TOKEN_BRIDGE_ADDRESS,
TERRA_HOST,
TERRA_TEST_TOKEN_ADDRESS,
} from "./consts";
import { LCDClient } from "@terra-money/terra.js";
export interface StateSafeWormholeWrappedInfo {
isWrapped: boolean;

View File

@ -3,7 +3,6 @@ import {
ConnectedWallet as TerraConnectedWallet,
} from "@terra-money/wallet-provider";
import { LCDClient } from "@terra-money/terra.js";
import bech32 from "bech32";
// TODO: Loop txInfo for timed out transactions.
// lcd.tx.txInfo(transaction.result.txhash);
@ -17,10 +16,3 @@ export async function waitForTerraExecution(
});
return transaction;
}
export function canonicalAddress(humanAddress: string) {
return new Uint8Array(bech32.fromWords(bech32.decode(humanAddress).words));
}
export function humanAddress(canonicalAddress: Uint8Array) {
return bech32.encode("terra", bech32.toWords(canonicalAddress));
}

View File

@ -15,6 +15,7 @@
"@solana/web3.js": "^1.24.0",
"@terra-money/terra.js": "^1.8.10",
"@terra-money/wallet-provider": "^1.2.4",
"bech32": "^2.0.0",
"js-base64": "^3.6.1",
"protobufjs": "^6.11.2",
"rxjs": "^7.3.0"
@ -710,6 +711,12 @@
"ws": "7.4.6"
}
},
"node_modules/@ethersproject/providers/node_modules/bech32": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz",
"integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==",
"dev": true
},
"node_modules/@ethersproject/providers/node_modules/ws": {
"version": "7.4.6",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
@ -1342,11 +1349,6 @@
"node": ">=12"
}
},
"node_modules/@terra-money/terra.js/node_modules/bech32": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz",
"integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg=="
},
"node_modules/@terra-money/wallet-provider": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/@terra-money/wallet-provider/-/wallet-provider-1.2.4.tgz",
@ -1743,10 +1745,9 @@
]
},
"node_modules/bech32": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz",
"integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==",
"dev": true
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz",
"integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg=="
},
"node_modules/bindings": {
"version": "1.5.0",
@ -4000,6 +4001,12 @@
"ws": "7.4.6"
},
"dependencies": {
"bech32": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz",
"integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==",
"dev": true
},
"ws": {
"version": "7.4.6",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
@ -4428,13 +4435,6 @@
"tmp": "^0.2.1",
"utf-8-validate": "^5.0.5",
"ws": "^7.4.2"
},
"dependencies": {
"bech32": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz",
"integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg=="
}
}
},
"@terra-money/wallet-provider": {
@ -4785,10 +4785,9 @@
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
},
"bech32": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz",
"integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==",
"dev": true
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz",
"integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg=="
},
"bindings": {
"version": "1.5.0",

View File

@ -52,6 +52,7 @@
"@solana/web3.js": "^1.24.0",
"@terra-money/terra.js": "^1.8.10",
"@terra-money/wallet-provider": "^1.2.4",
"bech32": "^2.0.0",
"js-base64": "^3.6.1",
"protobufjs": "^6.11.2",
"rxjs": "^7.3.0"

View File

@ -1,5 +1,6 @@
export * from "./ethers-contracts";
export * from "./solana";
export * from "./terra";
export * from "./rpc";
export * from "./utils";
export * from "./bridge";

View File

@ -0,0 +1,8 @@
import { bech32 } from "bech32";
export function canonicalAddress(humanAddress: string) {
return new Uint8Array(bech32.fromWords(bech32.decode(humanAddress).words));
}
export function humanAddress(canonicalAddress: Uint8Array) {
return bech32.encode("terra", bech32.toWords(canonicalAddress));
}

View File

@ -0,0 +1 @@
export * from "./address";

View File

@ -1,10 +1,16 @@
import { Connection, PublicKey } from "@solana/web3.js";
import { ethers } from "ethers";
import { arrayify } from "ethers/lib/utils";
import { arrayify, zeroPad } from "ethers/lib/utils";
import { TokenImplementation__factory } from "../ethers-contracts";
import { ChainId, CHAIN_ID_ETH, CHAIN_ID_SOLANA, CHAIN_ID_TERRA } from "../utils";
import {
ChainId,
CHAIN_ID_ETH,
CHAIN_ID_SOLANA,
CHAIN_ID_TERRA,
} from "../utils";
import { getIsWrappedAssetEth } from "./getIsWrappedAsset";
import { LCDClient } from "@terra-money/terra.js";
import { canonicalAddress } from "../terra";
export interface WormholeWrappedInfo {
isWrapped: boolean;
@ -54,9 +60,9 @@ export async function getOriginalAssetTerra(
wrappedAddress: string
): Promise<WormholeWrappedInfo> {
const result: {
asset_address: string,
asset_chain: ChainId,
bridge: string,
asset_address: string;
asset_chain: ChainId;
bridge: string;
} = await client.wasm.contractQuery(wrappedAddress, {
wrapped_asset_info: {},
});
@ -64,14 +70,14 @@ export async function getOriginalAssetTerra(
return {
isWrapped: true,
chainId: result.asset_chain,
assetAddress: arrayify(result.asset_address),
assetAddress: new Uint8Array(Buffer.from(result.asset_address, "base64")),
};
}
return {
isWrapped: false,
chainId: CHAIN_ID_TERRA,
assetAddress: arrayify(wrappedAddress),
}
isWrapped: false,
chainId: CHAIN_ID_TERRA,
assetAddress: zeroPad(canonicalAddress(wrappedAddress), 32),
};
}
/**

View File

@ -1,5 +1,6 @@
import { Token, TOKEN_PROGRAM_ID } from "@solana/spl-token";
import { Connection, Keypair, PublicKey, Transaction } from "@solana/web3.js";
import { MsgExecuteContract } from "@terra-money/terra.js";
import { ethers } from "ethers";
import {
Bridge__factory,
@ -7,8 +8,6 @@ import {
} from "../ethers-contracts";
import { getBridgeFeeIx, ixFromRust } from "../solana";
import { ChainId, CHAIN_ID_SOLANA, createNonce } from "../utils";
import { ConnectedWallet as TerraConnectedWallet } from "@terra-money/wallet-provider";
import { MsgExecuteContract } from "@terra-money/terra.js";
export async function transferFromEth(
tokenBridgeAddress: string,
@ -45,26 +44,42 @@ export async function transferFromTerra(
walletAddress: string,
tokenBridgeAddress: string,
tokenAddress: string,
amount: ethers.BigNumberish,
amount: string,
recipientChain: ChainId,
recipientAddress: Uint8Array
) {
const nonce = Math.round(Math.random() * 100000);
return new MsgExecuteContract(
walletAddress,
tokenBridgeAddress,
{
initiate_transfer: {
asset: tokenAddress,
amount: amount,
recipient_chain: recipientChain,
recipient: recipientAddress,
fee: 1000,
nonce: nonce,
return [
new MsgExecuteContract(
walletAddress,
tokenAddress,
{
increase_allowance: {
spender: tokenBridgeAddress,
amount: amount,
expires: {
never: {},
},
},
},
},
{ uluna: 10000 }
);
{ uluna: 10000 }
),
new MsgExecuteContract(
walletAddress,
tokenBridgeAddress,
{
initiate_transfer: {
asset: tokenAddress,
amount: amount,
recipient_chain: recipientChain,
recipient: Buffer.from(recipientAddress).toString("base64"),
fee: "0",
nonce: nonce,
},
},
{ uluna: 10000 }
),
];
}
export async function transferFromSolana(