瀏覽代碼

sdk/aptos: use qualified type instead of module address

aki 3 年之前
父節點
當前提交
a54030b6ed

+ 6 - 0
sdk/js/CHANGELOG.md

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

+ 1 - 1
sdk/js/package.json

@@ -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",

+ 6 - 15
sdk/js/src/token_bridge/__tests__/aptos-integration.ts

@@ -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()

+ 9 - 9
sdk/js/src/token_bridge/getForeignAsset.ts

@@ -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;
   }

+ 13 - 5
sdk/js/src/token_bridge/getIsWrappedAsset.ts

@@ -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;

+ 1 - 1
sdk/js/src/token_bridge/getOriginalAsset.ts

@@ -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;

+ 10 - 1
sdk/js/src/utils/aptos.ts

@@ -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.