Skip to content

Commit

Permalink
algorand to avax working
Browse files Browse the repository at this point in the history
  • Loading branch information
barnjamin committed Dec 29, 2023
1 parent 8290886 commit 090aa63
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 29 deletions.
2 changes: 1 addition & 1 deletion examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
},
"sideEffects": false,
"scripts": {
"algo": "cd ../platforms/algorand/protocols/tokenBridge && npm run build && cd - && tsx src/algoTokenBridge.ts",
"algo": "cd ../platforms/algorand/protocols/core && npm run build && cd - && tsx src/algoTokenBridge.ts",
"tb": "tsx src/tokenBridge.ts",
"cctp": "tsx src/cctp.ts",
"demo": "tsx src/index.ts",
Expand Down
8 changes: 5 additions & 3 deletions examples/src/algoTokenBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ import "@wormhole-foundation/connect-sdk-evm-tokenbridge";
const wh = new Wormhole("Testnet", [AlgorandPlatform, EvmPlatform]);

// Grab chain Contexts -- these hold a reference to a cached rpc client
const sendChain = wh.getChain("Avalanche");
const rcvChain = wh.getChain("Algorand");
const sendChain = wh.getChain("Algorand");
const rcvChain = wh.getChain("Avalanche");

// Shortcut to allow transferring native gas token - worked 12-28-23
const token: TokenId | "native" = "native";
Expand Down Expand Up @@ -85,7 +85,9 @@ import "@wormhole-foundation/connect-sdk-evm-tokenbridge";
// and attempt to fetch details about its progress.
let recoverTxid = undefined;
// let recoverTxid = "0xdab98de823cd9e2ec3975bf366503dcd896a47a7ce3764fb964cc84b54f7159c"; // Avalanche-->Algorand
// recoverTxid = "0x83b4438b9135eef05734beea4fd4e41d644b1d07196c491e9576bf0ed24a9797";
// recoverTxid = "NLI5KZSGDVO6JFZCJTN6VA7PSCWJB22FBGC33CPHQWGXFDOFKFVA";
// recoverTxid = "3I552XXYJZ52G6WH7KVAM2CNNSWAZJTYNYUDTIKK3342NU2U2J4A";
recoverTxid = "T3C2VCOGZPW2OAPZZ4V5YWA2KM3PZWYSEVAQDZE5YQGCTAO75IRA";

// Finally create and perform the transfer given the parameters set above
const xfer = !recoverTxid
Expand Down
22 changes: 17 additions & 5 deletions platforms/algorand/protocols/core/src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,24 +133,36 @@ export class AlgorandWormholeCore<N extends Network, C extends AlgorandChains>
async parseTransaction(txId: string): Promise<WormholeMessageId[]> {
const result = await this.connection.pendingTransactionInformation(txId).do();
const ptr = modelsv2.PendingTransactionResponse.from_obj_for_encoding(result);
return this.parseTx(ptr);
}

private parseTx(ptr: modelsv2.PendingTransactionResponse): WormholeMessageId[] {
const msgs: WormholeMessageId[] = [];

if (ptr.innerTxns && ptr.innerTxns.length > 0) {
msgs.push(...ptr.innerTxns.flatMap((tx) => this.parseTx(tx)));
}

// Expect target is core app
if (BigInt(ptr.txn.txn.apid) !== this.coreAppId) throw new Error("Invalid app id");
if (BigInt(ptr.txn.txn.apid) !== this.coreAppId) return msgs;

// Expect logs
if (!ptr.logs || ptr.logs.length === 0) return msgs;

// Expect publish messeage as first arg
const args = ptr.txn.txn.apaa;
if (
args.length !== 3 ||
!encoding.bytes.equals(new Uint8Array(args[0]), AlgorandWormholeCore.publishMessage)
)
throw new Error("Invalid transaction arguments");

if (!ptr.logs || ptr.logs.length === 0) throw new Error("No logs found to parse sequence");
return msgs;

const sequence = encoding.bignum.decode(ptr.logs[0]);
console.log(ptr.txn.txn);
const emitter = new AlgorandAddress(ptr.txn.txn.snd).toUniversalAddress();
msgs.push({ chain: this.chain, emitter, sequence });

return [{ chain: this.chain, emitter, sequence }];
return msgs;
}

private createUnsignedTx(
Expand Down
4 changes: 4 additions & 0 deletions platforms/algorand/src/address.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ export class AlgorandAddress implements Address {
return new UniversalAddress(this.toUint8Array());
}

toInt(): bigint {
return encoding.bignum.decode(this.toUint8Array());
}

static instanceof(address: any): address is AlgorandAddress {
return address.constructor.platform === AlgorandPlatform._platform;
}
Expand Down
35 changes: 15 additions & 20 deletions platforms/algorand/src/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ import {
import {
Algodv2,
SignedTransaction,
bytesToBigInt,
decodeSignedTransaction,
waitForConfirmation,
modelsv2,
waitForConfirmation,
} from "algosdk";
import { AlgorandAddress, AlgorandZeroAddress } from "./address";
import { AlgorandChain } from "./chain";
import { AlgorandChains, AlgorandPlatformType, AnyAlgorandAddress, _platform } from "./types";
import { AlgorandAddress, AlgorandZeroAddress } from "./address";
import { safeBigIntToNumber } from "./utilities";

/**
* @category Algorand
Expand Down Expand Up @@ -76,28 +76,21 @@ export class AlgorandPlatform<N extends Network> extends PlatformContext<N, Algo
};

static anyAlgorandAddressToAsaId(address: AnyAlgorandAddress): number {
/*
QUESTIONBW: Redeeming on Algorand an incoming Avalanche USDC transfer is failing here.
It seems like I need to use the StorageLsig class to get the storage contract and then decode its state,
but this module is in the tokenBridge module, which I shouldn't need to import here in the platform itself
*/
console.log("addressArg", address);
const addr = new AlgorandAddress(address.toString());
console.log("addr", addr);
const lastEightBytes = addr.toUint8Array().slice(-8);
const asaId = Number(bytesToBigInt(lastEightBytes));
console.log("asaId", asaId);
return asaId;
const addr = new AlgorandAddress(address);
return safeBigIntToNumber(addr.toInt());
}

static async getDecimals(
chain: Chain,
rpc: Algodv2,
token: AnyAlgorandAddress | "native",
): Promise<bigint> {
if (token === "native") return BigInt(decimals.nativeDecimals(AlgorandPlatform._platform));
const asaId = this.anyAlgorandAddressToAsaId(token);
const assetResp = await rpc.getAssetByID(asaId).do();
// It may come in as a universal address
const assetId = token === "native" ? 0 : this.anyAlgorandAddressToAsaId(token);

if (assetId === 0) return BigInt(decimals.nativeDecimals(AlgorandPlatform._platform));

const assetResp = await rpc.getAssetByID(assetId).do();
const asset = modelsv2.Asset.from_obj_for_encoding(assetResp);
if (!asset.params || !asset.params.decimals) throw new Error("Could not fetch token details");
return BigInt(asset.params.decimals);
Expand All @@ -109,12 +102,14 @@ export class AlgorandPlatform<N extends Network> extends PlatformContext<N, Algo
walletAddr: string,
token: AnyAlgorandAddress | "native",
): Promise<bigint | null> {
if (token === "native") {
const asaId = token === "native" ? 0 : this.anyAlgorandAddressToAsaId(token);

if (asaId === 0) {
const resp = await rpc.accountInformation(walletAddr).do();
const accountInfo = modelsv2.Account.from_obj_for_encoding(resp);
return BigInt(accountInfo.amount);
}
const asaId = this.anyAlgorandAddressToAsaId(token);

const acctAssetInfoResp = await rpc.accountAssetInformation(walletAddr, asaId).do();
const accountAssetInfo = modelsv2.AssetHolding.from_obj_for_encoding(acctAssetInfoResp);
return BigInt(accountAssetInfo.amount);
Expand Down

0 comments on commit 090aa63

Please sign in to comment.