Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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: 3 additions & 0 deletions contract_manager/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,13 @@
"@pythnetwork/pyth-sdk-solidity": "workspace:^",
"@pythnetwork/pyth-starknet-js": "^0.2.1",
"@pythnetwork/pyth-sui-js": "workspace:*",
"@pythnetwork/pyth-ton-js": "workspace:*",
"@pythnetwork/solana-utils": "workspace:^",
"@pythnetwork/xc-admin-common": "workspace:*",
"@solana/web3.js": "^1.73.0",
"@sqds/mesh": "^1.0.6",
"@ton/crypto": "^3.3.0",
"@ton/ton": "^15.1.0",
"@types/yargs": "^17.0.32",
"aptos": "^1.5.0",
"axios": "^0.24.0",
Expand Down
110 changes: 110 additions & 0 deletions contract_manager/src/chains.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ import { TokenId } from "./token";
import { BN, Provider, Wallet, WalletUnlocked } from "fuels";
import { FUEL_ETH_ASSET_ID } from "@pythnetwork/pyth-fuel-js";
import { Contract, RpcProvider, Signer, ec, shortString } from "starknet";
import {
TonClient,
WalletContractV4,
ContractProvider,
Address,
OpenedContract,
Sender,
} from "@ton/ton";
import { keyPairFromSeed } from "@ton/crypto";
import { PythContract } from "@pythnetwork/pyth-ton-js";

export type ChainConfig = Record<string, string> & {
mainnet: boolean;
Expand Down Expand Up @@ -738,3 +748,103 @@ export class StarknetChain extends Chain {
return new RpcProvider({ nodeUrl: this.rpcUrl });
}
}

export class TonChain extends Chain {
static type = "TonChain";

constructor(
id: string,
mainnet: boolean,
wormholeChainName: string,
nativeToken: TokenId | undefined,
public rpcUrl: string
) {
super(id, mainnet, wormholeChainName, nativeToken);
}

async getClient(): Promise<TonClient> {
// add apiKey if facing rate limit
const client = new TonClient({
endpoint: this.rpcUrl,
});
return client;
}

async getContract(address: string): Promise<OpenedContract<PythContract>> {
const client = await this.getClient();
const contract = client.open(
PythContract.createFromAddress(Address.parse(address))
);
return contract;
}

async getContractProvider(address: string): Promise<ContractProvider> {
const client = await this.getClient();
return client.provider(Address.parse(address));
}

async getWallet(privateKey: PrivateKey): Promise<WalletContractV4> {
const keyPair = keyPairFromSeed(Buffer.from(privateKey, "hex"));
return WalletContractV4.create({
publicKey: keyPair.publicKey,
workchain: 0,
});
}

async getSender(privateKey: PrivateKey): Promise<Sender> {
const client = await this.getClient();
const keyPair = keyPairFromSeed(Buffer.from(privateKey, "hex"));
const wallet = WalletContractV4.create({
publicKey: keyPair.publicKey,
workchain: 0,
});
const provider = client.open(wallet);
return provider.sender(keyPair.secretKey);
}

/**
* Returns the payload for a governance contract upgrade instruction for contracts deployed on this chain
* @param digest hex string of the 32 byte digest for the new package without the 0x prefix
*/
generateGovernanceUpgradePayload(digest: string): Buffer {
// This might throw an error because the Fuel contract doesn't support upgrades yet (blocked on Fuel releasing Upgradeability standard)
return new UpgradeContract256Bit(this.wormholeChainName, digest).encode();
}

getType(): string {
return TonChain.type;
}

toJson(): KeyValueConfig {
return {
id: this.id,
wormholeChainName: this.wormholeChainName,
mainnet: this.mainnet,
rpcUrl: this.rpcUrl,
type: TonChain.type,
};
}

static fromJson(parsed: ChainConfig): TonChain {
if (parsed.type !== TonChain.type) throw new Error("Invalid type");
return new TonChain(
parsed.id,
parsed.mainnet,
parsed.wormholeChainName,
parsed.nativeToken,
parsed.rpcUrl
);
}

async getAccountAddress(privateKey: PrivateKey): Promise<string> {
const wallet = await this.getWallet(privateKey);
return wallet.address.toString();
}

async getAccountBalance(privateKey: PrivateKey): Promise<number> {
const wallet = await this.getWallet(privateKey);
const provider = await this.getContractProvider(wallet.address.toString());
const balance = await wallet.getBalance(provider);
return Number(balance) / 10 ** 9;
}
}
1 change: 1 addition & 0 deletions contract_manager/src/contracts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from "./fuel";
export * from "./sui";
export * from "./wormhole";
export * from "./evm_abis";
export * from "./ton";
Loading
Loading