sdk/aptos: use qualified type instead of module address
This commit is contained in:
parent
027354f319
commit
a54030b6ed
|
@ -1,5 +1,11 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.9.0
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
Use FQTs in Aptos SDK
|
||||||
|
|
||||||
## 0.8.0
|
## 0.8.0
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@certusone/wormhole-sdk",
|
"name": "@certusone/wormhole-sdk",
|
||||||
"version": "0.8.0",
|
"version": "0.9.0",
|
||||||
"description": "SDK for interacting with Wormhole",
|
"description": "SDK for interacting with Wormhole",
|
||||||
"homepage": "https://wormhole.com",
|
"homepage": "https://wormhole.com",
|
||||||
"main": "./lib/cjs/index.js",
|
"main": "./lib/cjs/index.js",
|
||||||
|
|
|
@ -291,29 +291,20 @@ describe("Aptos SDK tests", () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check attestation on aptos
|
// check attestation on aptos
|
||||||
const aptosWrappedAddress = await getForeignAssetAptos(
|
const aptosWrappedType = await getForeignAssetAptos(
|
||||||
client,
|
client,
|
||||||
aptosTokenBridge,
|
aptosTokenBridge,
|
||||||
CHAIN_ID_ETH,
|
CHAIN_ID_ETH,
|
||||||
TEST_ERC20
|
TEST_ERC20
|
||||||
);
|
);
|
||||||
if (!aptosWrappedAddress) {
|
if (!aptosWrappedType) {
|
||||||
throw new Error("Failed to create wrapped coin on Aptos");
|
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(
|
const info = await getOriginalAssetAptos(
|
||||||
client,
|
client,
|
||||||
aptosTokenBridge,
|
aptosTokenBridge,
|
||||||
wrappedType
|
aptosWrappedType
|
||||||
);
|
);
|
||||||
expect(uint8ArrayToHex(info.assetAddress)).toEqual(
|
expect(uint8ArrayToHex(info.assetAddress)).toEqual(
|
||||||
tryNativeToHexString(TEST_ERC20, CHAIN_ID_ETH)
|
tryNativeToHexString(TEST_ERC20, CHAIN_ID_ETH)
|
||||||
|
@ -323,7 +314,7 @@ describe("Aptos SDK tests", () => {
|
||||||
await getIsWrappedAssetAptos(
|
await getIsWrappedAssetAptos(
|
||||||
client,
|
client,
|
||||||
aptosTokenBridge,
|
aptosTokenBridge,
|
||||||
aptosWrappedAddress
|
aptosWrappedType
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -363,7 +354,7 @@ describe("Aptos SDK tests", () => {
|
||||||
|
|
||||||
// redeem on aptos
|
// redeem on aptos
|
||||||
const balanceBeforeTransferAptos = ethers.BigNumber.from(
|
const balanceBeforeTransferAptos = ethers.BigNumber.from(
|
||||||
await getBalanceAptos(client, wrappedType, recipient.address())
|
await getBalanceAptos(client, aptosWrappedType, recipient.address())
|
||||||
);
|
);
|
||||||
const redeemPayload = await redeemOnAptos(
|
const redeemPayload = await redeemOnAptos(
|
||||||
client,
|
client,
|
||||||
|
@ -377,7 +368,7 @@ describe("Aptos SDK tests", () => {
|
||||||
|
|
||||||
// check balances
|
// check balances
|
||||||
const balanceAfterTransferAptos = ethers.BigNumber.from(
|
const balanceAfterTransferAptos = ethers.BigNumber.from(
|
||||||
await getBalanceAptos(client, wrappedType, recipient.address())
|
await getBalanceAptos(client, aptosWrappedType, recipient.address())
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
balanceAfterTransferAptos.sub(balanceBeforeTransferAptos).toString()
|
balanceAfterTransferAptos.sub(balanceBeforeTransferAptos).toString()
|
||||||
|
|
|
@ -14,8 +14,8 @@ import {
|
||||||
ChainName,
|
ChainName,
|
||||||
CHAIN_ID_ALGORAND,
|
CHAIN_ID_ALGORAND,
|
||||||
coalesceChainId,
|
coalesceChainId,
|
||||||
ensureHexPrefix,
|
getAssetFullyQualifiedType,
|
||||||
getForeignAssetAddress,
|
coalesceModuleAddress,
|
||||||
} from "../utils";
|
} from "../utils";
|
||||||
import { Provider } from "near-api-js/lib/providers";
|
import { Provider } from "near-api-js/lib/providers";
|
||||||
import { LCDClient as XplaLCDClient } from "@xpla/xpla.js";
|
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 client Client used to transfer data to/from Aptos node
|
||||||
* @param tokenBridgeAddress Address of token bridge
|
* @param tokenBridgeAddress Address of token bridge
|
||||||
* @param originChain Chain ID of chain asset is originally from
|
* @param originChain Chain ID of chain asset is originally from
|
||||||
* @param originAddress Asset address on origin chain
|
* @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(
|
export async function getForeignAssetAptos(
|
||||||
client: AptosClient,
|
client: AptosClient,
|
||||||
|
@ -206,22 +206,22 @@ export async function getForeignAssetAptos(
|
||||||
originAddress: string
|
originAddress: string
|
||||||
): Promise<string | null> {
|
): Promise<string | null> {
|
||||||
const originChainId = coalesceChainId(originChain);
|
const originChainId = coalesceChainId(originChain);
|
||||||
const assetAddress = getForeignAssetAddress(
|
const assetFullyQualifiedType = getAssetFullyQualifiedType(
|
||||||
tokenBridgeAddress,
|
tokenBridgeAddress,
|
||||||
originChainId,
|
originChainId,
|
||||||
originAddress
|
originAddress
|
||||||
);
|
);
|
||||||
if (!assetAddress) {
|
if (!assetFullyQualifiedType) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// check if asset exists and throw if it doesn't
|
// check if asset exists and throw if it doesn't
|
||||||
await client.getAccountResource(
|
await client.getAccountResource(
|
||||||
assetAddress,
|
coalesceModuleAddress(assetFullyQualifiedType),
|
||||||
`0x1::coin::CoinInfo<${ensureHexPrefix(assetAddress)}::coin::T>`
|
`0x1::coin::CoinInfo<${assetFullyQualifiedType}>`
|
||||||
);
|
);
|
||||||
return assetAddress;
|
return assetFullyQualifiedType;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,12 @@ import { AptosClient } from "aptos";
|
||||||
import { ethers } from "ethers";
|
import { ethers } from "ethers";
|
||||||
import { Bridge__factory } from "../ethers-contracts";
|
import { Bridge__factory } from "../ethers-contracts";
|
||||||
import { importTokenWasm } from "../solana/wasm";
|
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 { safeBigIntToNumber } from "../utils/bigint";
|
||||||
import { getForeignAssetInjective } from "./getForeignAsset";
|
import { getForeignAssetInjective } from "./getForeignAsset";
|
||||||
|
|
||||||
|
@ -120,18 +125,21 @@ export function getIsWrappedAssetNear(
|
||||||
* Determines whether or not given address is wrapped or native to Aptos.
|
* Determines whether or not given address is wrapped or native to Aptos.
|
||||||
* @param client Client used to transfer data to/from Aptos node
|
* @param client Client used to transfer data to/from Aptos node
|
||||||
* @param tokenBridgeAddress Address of token bridge
|
* @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
|
* @returns True if asset is wrapped
|
||||||
*/
|
*/
|
||||||
export async function getIsWrappedAssetAptos(
|
export async function getIsWrappedAssetAptos(
|
||||||
client: AptosClient,
|
client: AptosClient,
|
||||||
tokenBridgeAddress: string,
|
tokenBridgeAddress: string,
|
||||||
assetAddress: string,
|
assetFullyQualifiedType: string
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
assetAddress = ensureHexPrefix(assetAddress);
|
assetFullyQualifiedType = ensureHexPrefix(assetFullyQualifiedType);
|
||||||
try {
|
try {
|
||||||
// get origin info from asset address
|
// get origin info from asset address
|
||||||
await client.getAccountResource(assetAddress, `${tokenBridgeAddress}::state::OriginInfo`);
|
await client.getAccountResource(
|
||||||
|
coalesceModuleAddress(assetFullyQualifiedType),
|
||||||
|
`${tokenBridgeAddress}::state::OriginInfo`
|
||||||
|
);
|
||||||
return true;
|
return true;
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -326,7 +326,7 @@ export async function getOriginalAssetAptos(
|
||||||
fullyQualifiedType: string
|
fullyQualifiedType: string
|
||||||
): Promise<WormholeWrappedInfo> {
|
): Promise<WormholeWrappedInfo> {
|
||||||
if (!isValidAptosType(fullyQualifiedType)) {
|
if (!isValidAptosType(fullyQualifiedType)) {
|
||||||
throw new Error("Need fully qualified address");
|
throw new Error("Invalid qualified type");
|
||||||
}
|
}
|
||||||
|
|
||||||
let originInfo: OriginInfo | undefined;
|
let originInfo: OriginInfo | undefined;
|
||||||
|
|
|
@ -109,7 +109,7 @@ export const getAssetFullyQualifiedType = (
|
||||||
if (originChain === CHAIN_ID_APTOS) {
|
if (originChain === CHAIN_ID_APTOS) {
|
||||||
// originAddress should be of form address::module::type
|
// originAddress should be of form address::module::type
|
||||||
if (!isValidAptosType(originAddress)) {
|
if (!isValidAptosType(originAddress)) {
|
||||||
console.error("Need fully qualified address for native asset");
|
console.error("Invalid qualified type");
|
||||||
return null;
|
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
|
* Simulates given raw transaction and either returns the resulting transaction that was submitted
|
||||||
* to the mempool, or throws if it fails.
|
* to the mempool, or throws if it fails.
|
||||||
|
|
Loading…
Reference in New Issue