Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions apps/price_pusher/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"pyth-price-pusher": "./dist/index.cjs"
},
"dependencies": {
"@aptos-labs/ts-sdk": "^1.39.0",
"@aptos-labs/ts-sdk": "^6.3.1",
"@coral-xyz/anchor": "^0.30.0",
"@injectivelabs/networks": "1.14.47",
"@injectivelabs/sdk-ts": "1.14.50",
Expand All @@ -22,7 +22,6 @@
"@ton/crypto": "^3.3.0",
"@ton/ton": "^15.1.0",
"@types/pino": "^7.0.5",
"aptos": "^1.8.5",
"express": "^4.18.2",
"fuels": "catalog:",
"jito-ts": "^3.0.1",
Expand Down
83 changes: 50 additions & 33 deletions apps/price_pusher/src/aptos/aptos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import { HermesClient } from "@pythnetwork/hermes-client";
import { AptosAccount, AptosClient } from "aptos";
import {
Account,
Aptos,
AptosConfig,
Network,
} from "@aptos-labs/ts-sdk";
import type { Logger } from "pino";

import type { IPricePusher, PriceInfo, PriceItem } from "../interface.js";
Expand All @@ -26,23 +31,28 @@ export class AptosPriceListener extends ChainPriceListener {
}

async getOnChainPriceInfo(priceId: string): Promise<PriceInfo | undefined> {
const client = new AptosClient(this.endpoint);

const res = await client.getAccountResource(
this.pythModule,
`${this.pythModule}::state::LatestPriceInfo`,
const client = new Aptos(
new AptosConfig({ network: Network.CUSTOM, fullnode: this.endpoint }),
);

const res = await client.getAccountResource<{ info: { handle: string } }>({
accountAddress: this.pythModule,
resourceType: `${this.pythModule}::state::LatestPriceInfo`,
});

try {
// This depends upon the pyth contract storage on Aptos and should not be undefined.
// If undefined, there has been some change and we would need to update accordingly.
const handle = (res.data as any).info.handle;
const handle = res.info.handle;

const priceItemRes = await client.getTableItem(handle, {
key_type: `${this.pythModule}::price_identifier::PriceIdentifier`,
value_type: `${this.pythModule}::price_info::PriceInfo`,
key: {
bytes: priceId,
const priceItemRes = await client.getTableItem<any>({
handle,
data: {
key_type: `${this.pythModule}::price_identifier::PriceIdentifier`,
value_type: `${this.pythModule}::price_info::PriceInfo`,
key: {
bytes: priceId,
},
},
});

Expand Down Expand Up @@ -138,28 +148,31 @@ export class AptosPricePusher implements IPricePusher {
return;
}

const account = AptosAccount.fromDerivePath(
APTOS_ACCOUNT_HD_PATH,
this.mnemonic,
const account = Account.fromDerivationPath({
path: APTOS_ACCOUNT_HD_PATH,
mnemonic: this.mnemonic,
});
const client = new Aptos(
new AptosConfig({ network: Network.CUSTOM, fullnode: this.endpoint }),
);
const client = new AptosClient(this.endpoint);

const sequenceNumber = await this.tryGetNextSequenceNumber(client, account);
const rawTx = await client.generateTransaction(
account.address(),
{
const transaction = await client.transaction.build.simple({
sender: account.accountAddress,
data: {
function: `${this.pythContractAddress}::pyth::update_price_feeds_with_funder`,
type_arguments: [],
arguments: [priceFeedUpdateData],
functionArguments: [priceFeedUpdateData],
},
{
sequence_number: sequenceNumber.toFixed(0),
options: {
accountSequenceNumber: sequenceNumber,
},
);
});

try {
const signedTx = await client.signTransaction(account, rawTx);
const pendingTx = await client.submitTransaction(signedTx);
const pendingTx = await client.signAndSubmitTransaction({
signer: account,
transaction,
});

this.logger.debug(
{ hash: pendingTx.hash },
Expand All @@ -185,13 +198,13 @@ export class AptosPricePusher implements IPricePusher {

// Wait for the transaction to be confirmed. If it fails, reset the sequence number.
private async waitForTransactionConfirmation(
client: AptosClient,
client: Aptos,
txHash: string,
): Promise<void> {
try {
await client.waitForTransaction(txHash, {
checkSuccess: true,
timeoutSecs: 10,
await client.waitForTransaction({
transactionHash: txHash,
options: { checkSuccess: true, timeoutSecs: 10 },
});

this.logger.info({ hash: txHash }, `Transaction confirmed.`);
Expand All @@ -209,8 +222,8 @@ export class AptosPricePusher implements IPricePusher {
// to predict the next sequence number if possible; if not, it fetches the number from
// the blockchain itself (and caches it for later).
private async tryGetNextSequenceNumber(
client: AptosClient,
account: AptosAccount,
client: Aptos,
account: Account,
): Promise<number> {
if (this.lastSequenceNumber === undefined) {
// Fetch from the blockchain if we don't have the local cache.
Expand All @@ -222,7 +235,11 @@ export class AptosPricePusher implements IPricePusher {
try {
this.sequenceNumberLocked = true;
this.lastSequenceNumber = Number(
(await client.getAccount(account.address())).sequence_number,
(
await client.getAccountInfo({
accountAddress: account.accountAddress,
})
).sequence_number,
);
this.logger.debug(
`Fetched account sequence number: ${this.lastSequenceNumber}`,
Expand Down
12 changes: 6 additions & 6 deletions apps/price_pusher/src/aptos/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import fs from "node:fs";

import { HermesClient } from "@pythnetwork/hermes-client";
import { AptosAccount } from "aptos";
import { Account } from "@aptos-labs/ts-sdk";
import pino from "pino";
import type { Options } from "yargs";

Expand Down Expand Up @@ -84,11 +84,11 @@ export default {
}

const mnemonic = fs.readFileSync(mnemonicFile, "utf8").trim();
const account = AptosAccount.fromDerivePath(
APTOS_ACCOUNT_HD_PATH,
const account = Account.fromDerivationPath({
path: APTOS_ACCOUNT_HD_PATH,
mnemonic,
);
logger.info(`Pushing from account address: ${account.address()}`);
});
logger.info(`Pushing from account address: ${account.accountAddress}`);

let priceItems = priceConfigs.map(({ id, alias }) => ({ id, alias }));

Expand Down Expand Up @@ -144,7 +144,7 @@ export default {
// Create and start the balance tracker if metrics are enabled
if (metrics) {
const balanceTracker = createAptosBalanceTracker({
address: account.address().toString(),
address: account.accountAddress.toString(),
endpoint,
network: "aptos",
updateInterval: pushingFrequency,
Expand Down
2 changes: 1 addition & 1 deletion contract_manager/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"author": "",
"dependencies": {
"@aptos-labs/ts-sdk": "^6.3.1",
"@certusone/wormhole-sdk": "^0.9.8",
"@coral-xyz/anchor": "^0.29.0",
"@cosmjs/cosmwasm-stargate": "^0.32.3",
Expand Down Expand Up @@ -30,7 +31,6 @@
"@ton/crypto": "^3.3.0",
"@ton/ton": "^15.1.0",
"@types/yargs": "catalog:",
"aptos": "^1.5.0",
"axios": "^0.24.0",
"bs58": "^5.0.0",
"extract-files": "^13.0.0",
Expand Down
67 changes: 44 additions & 23 deletions contract_manager/src/core/chains.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,13 @@ import {
import { keyPairFromSeed } from "@ton/crypto";
import type { ContractProvider, OpenedContract, Sender } from "@ton/ton";
import { Address, TonClient, WalletContractV4 } from "@ton/ton";
import type { TxnBuilderTypes } from "aptos";
import { AptosAccount, AptosClient, CoinClient } from "aptos";
import {
Account,
Aptos,
AptosConfig,
Ed25519PrivateKey,
Network as AptosNetwork,
} from "@aptos-labs/ts-sdk";
import * as bs58 from "bs58";
import type { BN, WalletUnlocked } from "fuels";
import { Provider, Wallet } from "fuels";
Expand Down Expand Up @@ -1152,8 +1157,10 @@ export class AptosChain extends Chain {
super(id, mainnet, wormholeChainName, nativeToken);
}

getClient(): AptosClient {
return new AptosClient(this.rpcUrl);
getClient(): Aptos {
return new Aptos(
new AptosConfig({ network: AptosNetwork.CUSTOM, fullnode: this.rpcUrl }),
);
}

/**
Expand Down Expand Up @@ -1190,36 +1197,50 @@ export class AptosChain extends Chain {
}

getAccountAddress(privateKey: PrivateKey): Promise<string> {
const account = new AptosAccount(
new Uint8Array(Buffer.from(privateKey, "hex")),
);
return Promise.resolve(account.address().toString());
const account = Account.fromPrivateKey({
privateKey: new Ed25519PrivateKey(privateKey),
});
return Promise.resolve(account.accountAddress.toString());
}

async getAccountBalance(privateKey: PrivateKey): Promise<number> {
const client = this.getClient();
const account = new AptosAccount(
new Uint8Array(Buffer.from(privateKey, "hex")),
const account = Account.fromPrivateKey({
privateKey: new Ed25519PrivateKey(privateKey),
});
return (
Number(
await client.getAccountAPTAmount({
accountAddress: account.accountAddress,
}),
) /
10 ** 8
);
const coinClient = new CoinClient(client);
return Number(await coinClient.checkBalance(account)) / 10 ** 8;
}

async sendTransaction(
senderPrivateKey: PrivateKey,
txPayload: TxnBuilderTypes.TransactionPayloadEntryFunction,
txPayload: {
function: `${string}::${string}::${string}`;
functionArguments: any[];
},
): Promise<TxResult> {
const client = this.getClient();
const sender = new AptosAccount(
new Uint8Array(Buffer.from(senderPrivateKey, "hex")),
);
const result = await client.generateSignSubmitWaitForTransaction(
sender,
txPayload,
{
maxGasAmount: BigInt(30_000),
},
);
const sender = Account.fromPrivateKey({
privateKey: new Ed25519PrivateKey(senderPrivateKey),
});
const transaction = await client.transaction.build.simple({
sender: sender.accountAddress,
data: txPayload,
options: { maxGasAmount: 30_000 },
});
const pending = await client.signAndSubmitTransaction({
signer: sender,
transaction,
});
const result = await client.waitForTransaction({
transactionHash: pending.hash,
});
return { id: result.hash, info: result };
}
}
Expand Down
Loading