sdk/aptos: use qualified type instead of module address

This commit is contained in:
aki 2022-10-25 15:02:04 +00:00 committed by Evan Gray
parent 027354f319
commit a54030b6ed
7 changed files with 46 additions and 32 deletions

View File

@ -1,5 +1,11 @@
# Changelog
## 0.9.0
### Changed
Use FQTs in Aptos SDK
## 0.8.0
### Added

View File

@ -1,6 +1,6 @@
{
"name": "@certusone/wormhole-sdk",
"version": "0.8.0",
"version": "0.9.0",
"description": "SDK for interacting with Wormhole",
"homepage": "https://wormhole.com",
"main": "./lib/cjs/index.js",

View File

@ -291,29 +291,20 @@ describe("Aptos SDK tests", () => {
}
// check attestation on aptos
const aptosWrappedAddress = await getForeignAssetAptos(
const aptosWrappedType = await getForeignAssetAptos(
client,
aptosTokenBridge,
CHAIN_ID_ETH,
TEST_ERC20
);
if (!aptosWrappedAddress) {
if (!aptosWrappedType) {
throw new Error("Failed to create wrapped coin on Aptos");
}
const wrappedType = getAssetFullyQualifiedType(
aptosTokenBridge,
CHAIN_ID_ETH,
TEST_ERC20
);
if (!wrappedType) {
throw new Error("wrappedType is null");
}
const info = await getOriginalAssetAptos(
client,
aptosTokenBridge,
wrappedType
aptosWrappedType
);
expect(uint8ArrayToHex(info.assetAddress)).toEqual(
tryNativeToHexString(TEST_ERC20, CHAIN_ID_ETH)
@ -323,7 +314,7 @@ describe("Aptos SDK tests", () => {
await getIsWrappedAssetAptos(
client,
aptosTokenBridge,
aptosWrappedAddress
aptosWrappedType
)
);
@ -363,7 +354,7 @@ describe("Aptos SDK tests", () => {
// redeem on aptos
const balanceBeforeTransferAptos = ethers.BigNumber.from(
await getBalanceAptos(client, wrappedType, recipient.address())
await getBalanceAptos(client, aptosWrappedType, recipient.address())
);
const redeemPayload = await redeemOnAptos(
client,
@ -377,7 +368,7 @@ describe("Aptos SDK tests", () => {
// check balances
const balanceAfterTransferAptos = ethers.BigNumber.from(
await getBalanceAptos(client, wrappedType, recipient.address())
await getBalanceAptos(client, aptosWrappedType, recipient.address())
);
expect(
balanceAfterTransferAptos.sub(balanceBeforeTransferAptos).toString()

View File

@ -14,8 +14,8 @@ import {
ChainName,
CHAIN_ID_ALGORAND,
coalesceChainId,
ensureHexPrefix,
getForeignAssetAddress,
getAssetFullyQualifiedType,
coalesceModuleAddress,
} from "../utils";
import { Provider } from "near-api-js/lib/providers";
import { LCDClient as XplaLCDClient } from "@xpla/xpla.js";
@ -192,12 +192,12 @@ export async function getForeignAssetNear(
}
/**
* Get native module address of asset given its origin info.
* Get qualified type of asset on Aptos given its origin info.
* @param client Client used to transfer data to/from Aptos node
* @param tokenBridgeAddress Address of token bridge
* @param originChain Chain ID of chain asset is originally from
* @param originAddress Asset address on origin chain
* @returns Asset module address on Aptos
* @returns Fully qualified type of asset on Aptos
*/
export async function getForeignAssetAptos(
client: AptosClient,
@ -206,22 +206,22 @@ export async function getForeignAssetAptos(
originAddress: string
): Promise<string | null> {
const originChainId = coalesceChainId(originChain);
const assetAddress = getForeignAssetAddress(
const assetFullyQualifiedType = getAssetFullyQualifiedType(
tokenBridgeAddress,
originChainId,
originAddress
);
if (!assetAddress) {
if (!assetFullyQualifiedType) {
return null;
}
try {
// check if asset exists and throw if it doesn't
await client.getAccountResource(
assetAddress,
`0x1::coin::CoinInfo<${ensureHexPrefix(assetAddress)}::coin::T>`
coalesceModuleAddress(assetFullyQualifiedType),
`0x1::coin::CoinInfo<${assetFullyQualifiedType}>`
);
return assetAddress;
return assetFullyQualifiedType;
} catch (e) {
return null;
}

View File

@ -6,7 +6,12 @@ import { AptosClient } from "aptos";
import { ethers } from "ethers";
import { Bridge__factory } from "../ethers-contracts";
import { importTokenWasm } from "../solana/wasm";
import { CHAIN_ID_INJECTIVE, ensureHexPrefix, tryNativeToHexString } from "../utils";
import {
CHAIN_ID_INJECTIVE,
ensureHexPrefix,
coalesceModuleAddress,
tryNativeToHexString,
} from "../utils";
import { safeBigIntToNumber } from "../utils/bigint";
import { getForeignAssetInjective } from "./getForeignAsset";
@ -120,18 +125,21 @@ export function getIsWrappedAssetNear(
* Determines whether or not given address is wrapped or native to Aptos.
* @param client Client used to transfer data to/from Aptos node
* @param tokenBridgeAddress Address of token bridge
* @param assetAddress Module address of asset
* @param assetFullyQualifiedType Fully qualified type of asset
* @returns True if asset is wrapped
*/
export async function getIsWrappedAssetAptos(
client: AptosClient,
tokenBridgeAddress: string,
assetAddress: string,
assetFullyQualifiedType: string
): Promise<boolean> {
assetAddress = ensureHexPrefix(assetAddress);
assetFullyQualifiedType = ensureHexPrefix(assetFullyQualifiedType);
try {
// get origin info from asset address
await client.getAccountResource(assetAddress, `${tokenBridgeAddress}::state::OriginInfo`);
await client.getAccountResource(
coalesceModuleAddress(assetFullyQualifiedType),
`${tokenBridgeAddress}::state::OriginInfo`
);
return true;
} catch {
return false;

View File

@ -326,7 +326,7 @@ export async function getOriginalAssetAptos(
fullyQualifiedType: string
): Promise<WormholeWrappedInfo> {
if (!isValidAptosType(fullyQualifiedType)) {
throw new Error("Need fully qualified address");
throw new Error("Invalid qualified type");
}
let originInfo: OriginInfo | undefined;

View File

@ -109,7 +109,7 @@ export const getAssetFullyQualifiedType = (
if (originChain === CHAIN_ID_APTOS) {
// originAddress should be of form address::module::type
if (!isValidAptosType(originAddress)) {
console.error("Need fully qualified address for native asset");
console.error("Invalid qualified type");
return null;
}
@ -230,6 +230,15 @@ export async function getTypeFromExternalAddress(
}
}
/**
* Returns module address from given fully qualified type/module address.
* @param str FQT or module address
* @returns Module address
*/
export const coalesceModuleAddress = (str: string): string => {
return str.split("::")[0];
};
/**
* Simulates given raw transaction and either returns the resulting transaction that was submitted
* to the mempool, or throws if it fails.