Skip to content

Commit

Permalink
Merge branch 'ton-deploy' into ton-sdk
Browse files Browse the repository at this point in the history
  • Loading branch information
cctdaniel authored Oct 16, 2024
2 parents d459517 + fa4b9b9 commit 24c6afd
Show file tree
Hide file tree
Showing 4 changed files with 430 additions and 536 deletions.
328 changes: 328 additions & 0 deletions target_chains/ton/contracts/wrappers/BaseWrapper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,328 @@
import {
Address,
beginCell,
Cell,
Contract,
ContractProvider,
Dictionary,
Sender,
SendMode,
toNano,
} from "@ton/core";
import { createCellChain } from "../tests/utils";
import { createGuardianSetsDict } from "../tests/utils/wormhole";
import { HexString, Price } from "@pythnetwork/price-service-sdk";
import { DataSource } from "@pythnetwork/xc-admin-common";

export class BaseWrapper implements Contract {
constructor(
readonly address: Address,
readonly init?: { code: Cell; data: Cell }
) {}

static createFromAddress(address: Address) {
return new this(address);
}

static createInitData(config: {
priceFeedId?: HexString;
timePeriod?: number;
price?: Price;
emaPrice?: Price;
singleUpdateFee?: number;
dataSources?: DataSource[];
guardianSetIndex: number;
guardianSet: string[];
chainId: number;
governanceChainId: number;
governanceContract: string;
governanceDataSource?: DataSource;
}): Cell {
const priceDict = Dictionary.empty(
Dictionary.Keys.BigUint(256),
Dictionary.Values.Cell()
);

if (
config.priceFeedId &&
config.price &&
config.emaPrice &&
config.timePeriod
) {
const priceCell = beginCell()
.storeInt(
config.price.getPriceAsNumberUnchecked() * 10 ** -config.price.expo,
64
)
.storeUint(
config.price.getConfAsNumberUnchecked() * 10 ** -config.price.expo,
64
)
.storeInt(config.price.expo, 32)
.storeUint(config.price.publishTime, 64)
.endCell();

const emaPriceCell = beginCell()
.storeInt(
config.emaPrice.getPriceAsNumberUnchecked() *
10 ** -config.emaPrice.expo,
64
)
.storeUint(
config.emaPrice.getConfAsNumberUnchecked() *
10 ** -config.emaPrice.expo,
64
)
.storeInt(config.emaPrice.expo, 32)
.storeUint(config.emaPrice.publishTime, 64)
.endCell();

const priceFeedCell = beginCell()
.storeRef(priceCell)
.storeRef(emaPriceCell)
.storeUint(config.timePeriod, 32)
.endCell();

priceDict.set(BigInt(config.priceFeedId), priceFeedCell);
}

// Create a dictionary for data sources
const dataSourcesDict = Dictionary.empty(
Dictionary.Keys.Uint(32),
Dictionary.Values.Cell()
);
// Create a dictionary for valid data sources
const isValidDataSourceDict = Dictionary.empty(
Dictionary.Keys.BigUint(256),
Dictionary.Values.Bool()
);

if (config.dataSources) {
config.dataSources.forEach((source, index) => {
const sourceCell = beginCell()
.storeUint(source.emitterChain, 16)
.storeBuffer(Buffer.from(source.emitterAddress, "hex"))
.endCell();
dataSourcesDict.set(index, sourceCell);
const cellHash = BigInt("0x" + sourceCell.hash().toString("hex"));
isValidDataSourceDict.set(cellHash, true);
});
}

// Group price feeds and update fee
const priceFeedsCell = beginCell()
.storeDict(priceDict)
.storeUint(config.singleUpdateFee || 0, 256)
.endCell();

// Group data sources information
const dataSourcesCell = beginCell()
.storeDict(dataSourcesDict)
.storeUint(config.dataSources ? config.dataSources.length : 0, 32)
.storeDict(isValidDataSourceDict)
.endCell();

// Group guardian set information
const guardianSetCell = beginCell()
.storeUint(config.guardianSetIndex, 32)
.storeDict(
createGuardianSetsDict(config.guardianSet, config.guardianSetIndex)
)
.endCell();

// Group chain and governance information
const governanceCell = beginCell()
.storeUint(config.chainId, 16)
.storeUint(config.governanceChainId, 16)
.storeBuffer(Buffer.from(config.governanceContract, "hex"))
.storeDict(Dictionary.empty()) // consumed_governance_actions
.storeRef(
config.governanceDataSource
? beginCell()
.storeUint(config.governanceDataSource.emitterChain, 16)
.storeBuffer(
Buffer.from(config.governanceDataSource.emitterAddress, "hex")
)
.endCell()
: beginCell().endCell()
) // governance_data_source
.storeUint(0, 64) // last_executed_governance_sequence, set to 0 for initial state
.storeUint(0, 32) // governance_data_source_index, set to 0 for initial state
.storeUint(0, 256) // upgrade_code_hash, set to 0 for initial state
.endCell();

// Create the main cell with references to grouped data
return beginCell()
.storeRef(priceFeedsCell)
.storeRef(dataSourcesCell)
.storeRef(guardianSetCell)
.storeRef(governanceCell)
.endCell();
}

async sendDeploy(provider: ContractProvider, via: Sender, value: bigint) {
await provider.internal(via, {
value,
sendMode: SendMode.PAY_GAS_SEPARATELY,
body: beginCell().endCell(),
});
}

async getCurrentGuardianSetIndex(
provider: ContractProvider,
methodName: string
) {
const result = await provider.get(methodName, []);
return result.stack.readNumber();
}

async sendUpdateGuardianSet(
provider: ContractProvider,
via: Sender,
vm: Buffer
) {
const messageBody = beginCell()
.storeUint(1, 32) // OP_UPDATE_GUARDIAN_SET
.storeRef(createCellChain(vm))
.endCell();

await provider.internal(via, {
value: toNano("0.1"),
sendMode: SendMode.PAY_GAS_SEPARATELY,
body: messageBody,
});
}

async sendUpdatePriceFeeds(
provider: ContractProvider,
via: Sender,
updateData: Buffer,
updateFee: bigint
) {
const messageBody = beginCell()
.storeUint(2, 32) // OP_UPDATE_PRICE_FEEDS
.storeRef(createCellChain(updateData))
.endCell();

await provider.internal(via, {
value: updateFee,
sendMode: SendMode.PAY_GAS_SEPARATELY,
body: messageBody,
});
}

async getChainId(provider: ContractProvider, methodName: string) {
const result = await provider.get(methodName, []);
return result.stack.readNumber();
}

async getPriceUnsafe(
provider: ContractProvider,
priceFeedId: HexString,
methodName: string
) {
const result = await provider.get(methodName, [
{ type: "int", value: BigInt(priceFeedId) },
]);

const price = result.stack.readNumber();
const conf = result.stack.readNumber();
const expo = result.stack.readNumber();
const publishTime = result.stack.readNumber();

return {
price,
conf,
expo,
publishTime,
};
}

async getPriceNoOlderThan(
provider: ContractProvider,
timePeriod: number,
priceFeedId: HexString,
methodName: string
) {
const result = await provider.get(methodName, [
{ type: "int", value: BigInt(timePeriod) },
{ type: "int", value: BigInt(priceFeedId) },
]);

const price = result.stack.readNumber();
const conf = result.stack.readNumber();
const expo = result.stack.readNumber();
const publishTime = result.stack.readNumber();

return {
price,
conf,
expo,
publishTime,
};
}

async getEmaPriceUnsafe(
provider: ContractProvider,
priceFeedId: HexString,
methodName: string
) {
const result = await provider.get(methodName, [
{ type: "int", value: BigInt(priceFeedId) },
]);

const price = result.stack.readNumber();
const conf = result.stack.readNumber();
const expo = result.stack.readNumber();
const publishTime = result.stack.readNumber();

return {
price,
conf,
expo,
publishTime,
};
}

async getEmaPriceNoOlderThan(
provider: ContractProvider,
timePeriod: number,
priceFeedId: HexString,
methodName: string
) {
const result = await provider.get(methodName, [
{ type: "int", value: BigInt(timePeriod) },
{ type: "int", value: BigInt(priceFeedId) },
]);

const price = result.stack.readNumber();
const conf = result.stack.readNumber();
const expo = result.stack.readNumber();
const publishTime = result.stack.readNumber();

return {
price,
conf,
expo,
publishTime,
};
}

async getUpdateFee(
provider: ContractProvider,
vm: Buffer,
methodName: string
) {
const result = await provider.get(methodName, [
{ type: "slice", cell: createCellChain(vm) },
]);

return result.stack.readNumber();
}

async getSingleUpdateFee(provider: ContractProvider, methodName: string) {
const result = await provider.get(methodName, []);

return result.stack.readNumber();
}
}
Loading

0 comments on commit 24c6afd

Please sign in to comment.