diff --git a/oracles/redstone/sample-consumer/sample-consumer.spec.ts b/oracles/redstone/sample-consumer/sample-consumer.spec.ts new file mode 100644 index 0000000..1c9afbe --- /dev/null +++ b/oracles/redstone/sample-consumer/sample-consumer.spec.ts @@ -0,0 +1,136 @@ +import "@ton/test-utils" +import {SandboxContract, TreasuryContract, Blockchain} from "@ton/sandbox" +import {SampleConsumer} from "../../output/SampleConsumer_SampleConsumer" +import { + feedIdToBigInt, + getRedstoneSignedDataPackages, + getRedstoneSigners, + serializeSignedDataPackages, + serializeSigners, + signersToBigInt, +} from "../utils" +import { + SingleFeedMan, + storeReadPrice, + storeUpdatePrice, + UpdatePrice, +} from "../../output/SampleConsumer_SingleFeedMan" +import {beginCell, Cell, toNano} from "@ton/core" + +describe("SampleConsumer tests", () => { + let blockchain: Blockchain + let deployer: SandboxContract + let sampleConsumer: SandboxContract + let singleFeedMan: SandboxContract + + const feedId = "TON" + + beforeAll(async () => { + blockchain = await Blockchain.create() + deployer = await blockchain.treasury("deployer") + + const signers = getRedstoneSigners() + + singleFeedMan = blockchain.openContract( + await SingleFeedMan.fromInit( + feedIdToBigInt(feedId), + serializeSigners(signersToBigInt(signers)), + BigInt(Math.min(signers.length, 3)), + { + $$type: "PriceData", + timestamp: 0n, + price: 0n, + }, + ), + ) + + const signedDataPackages = await getRedstoneSignedDataPackages(feedId, signers) + + const signedDataPackagesCell = serializeSignedDataPackages(signedDataPackages, signers) + + const bodyStruct: UpdatePrice = { + $$type: "UpdatePrice", + feedId: feedIdToBigInt(feedId), + dataPackages: signedDataPackagesCell.asSlice(), + } + + const res = await singleFeedMan.send( + deployer.getSender(), + {value: toNano("0.05")}, + bodyStruct, + ) + + expect(res.transactions).toHaveTransaction({ + from: deployer.address, + to: singleFeedMan.address, + success: true, + op: SingleFeedMan.opcodes.UpdatePrice, + outMessagesCount: 1, + body: beginCell().store(storeUpdatePrice(bodyStruct)).endCell(), + }) + + expect(res.transactions).toHaveTransaction({ + from: singleFeedMan.address, + to: deployer.address, + op: SingleFeedMan.opcodes.PriceResponse, + }) + + sampleConsumer = blockchain.openContract( + await SampleConsumer.fromInit( + feedIdToBigInt(feedId), + { + $$type: "PriceData", + timestamp: 0n, + price: 0n, + }, + singleFeedMan.address, + ), + ) + }) + + it("should deploy sample consumer and correctly fetch price", async () => { + const fetchPriceResult = await sampleConsumer.send( + deployer.getSender(), + {value: toNano("0.05"), bounce: false}, + null, + ) + + expect(fetchPriceResult.transactions).toHaveTransaction({ + from: deployer.address, + to: sampleConsumer.address, + op: undefined, + outMessagesCount: 1, + body: new Cell(), + success: true, + deploy: true, + }) + + expect(fetchPriceResult.transactions).toHaveTransaction({ + from: sampleConsumer.address, + to: singleFeedMan.address, + op: SingleFeedMan.opcodes.ReadPrice, + body: beginCell() + .store( + storeReadPrice({ + $$type: "ReadPrice", + feedId: feedIdToBigInt(feedId), + }), + ) + .endCell(), + success: true, + outMessagesCount: 1, + }) + + expect(fetchPriceResult.transactions).toHaveTransaction({ + from: singleFeedMan.address, + to: sampleConsumer.address, + op: SingleFeedMan.opcodes.PriceResponse, + success: true, + }) + + const lastFetchedPriceData = await sampleConsumer.getLastFetchedPriceData() + // console.log(lastFetchedPriceData); + expect(lastFetchedPriceData.price).toBeGreaterThan(0n) + expect(lastFetchedPriceData.timestamp).toBeGreaterThan(0n) + }) +}) diff --git a/oracles/redstone/sample-consumer/sample-consumer.tact b/oracles/redstone/sample-consumer/sample-consumer.tact new file mode 100644 index 0000000..27e07d5 --- /dev/null +++ b/oracles/redstone/sample-consumer/sample-consumer.tact @@ -0,0 +1,30 @@ +import "../single-feed-man/single-feed-man"; + +contract SampleConsumer( + feedId: Int as uint256, + lastFetchedPriceData: PriceData, + priceFeed: Address, +) { + receive() { + message(MessageParameters { + value: 0, + to: self.priceFeed, + bounce: false, + mode: SendRemainingValue | SendBounceIfActionFail, + body: ReadPrice { + feedId: self.feedId, + }.toCell(), + }); + } + + receive(msg: PriceResponse) { + require(sender() == self.priceFeed, "Only price feed can send price response"); + require(msg.feedId == self.feedId, "Feed ID mismatch"); + + self.lastFetchedPriceData = msg.priceData; + } + + get fun lastFetchedPriceData(): PriceData { + return self.lastFetchedPriceData; + } +} diff --git a/oracles/redstone/single-feed-man/crypto.tact b/oracles/redstone/single-feed-man/crypto.tact new file mode 100644 index 0000000..627293f --- /dev/null +++ b/oracles/redstone/single-feed-man/crypto.tact @@ -0,0 +1,33 @@ +struct EcrecoverResult { + pubKey: UncompressedPubKey; + success: Bool; +} + +struct EcdsaSignature { + r: Int as uint256; + s: Int as uint256; + recoveryParam: Int as uint8; +} + +struct UncompressedPubKey { + h: Int; + x: Int; + y: Int; +} + +asm inline fun ecrecover(hash: Int, v: Int, r: Int, s: Int): EcrecoverResult { ECRECOVER NULLSWAPIFNOT NULLSWAPIFNOT2 } + +asm extends inline fun keccak(self: Builder): Int { 1 INT HASHEXT_KECCAK256 } +asm extends inline fun keccak(self: Slice): Int { 1 INT HASHEXT_KECCAK256 } + +inline fun recoverAddress(hash: Int, signature: EcdsaSignature): Int { + let result = ecrecover(hash, signature.recoveryParam, signature.r, signature.s); + + if (!result.success) { + return 0; + } + + let builder = beginCell().storeUint(result.pubKey.x, 256).storeUint(result.pubKey.y, 256); + + return builder.keccak() & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // mask to 20 bytes +} diff --git a/oracles/redstone/single-feed-man/fake-tuple.tact b/oracles/redstone/single-feed-man/fake-tuple.tact new file mode 100644 index 0000000..fa2aedf --- /dev/null +++ b/oracles/redstone/single-feed-man/fake-tuple.tact @@ -0,0 +1,120 @@ +import "./utils"; + +// only for 1-6 elements +struct FakeTuple { + dontTouchMyPizza: Cell; // it's not a cell, but a tuple (Tact has no tuples) + // https://www.youtube.com/watch?v=451XC5PigRY +} + +asm extends fun atInt(self: FakeTuple, index: Int): Int { INDEXVAR } +asm extends fun length(self: FakeTuple): Int { TLEN } +asm fun emptyTuple(): FakeTuple { NIL } +asm extends mutates fun pushInt(self: FakeTuple, value: Int) { TPUSH} + +// only for 1-6 elements +extends inline fun median(self: FakeTuple): Int { + let sortedTuple = self.sort(); + let DivModResult { quotient: q, remainder: r } = sortedTuple.length().divmod(2); + return (sortedTuple.atInt(q) + sortedTuple.atInt(q - 1 + r)) / 2; +} + +// only for 1-6 elements +asm extends fun toTuple(self: Cell): FakeTuple { + <{ + CTOS // slice + 16 LDU // length slice + s1 s0 XCPU // slice length length + 7 LESSINT // slice length f(length < 7) + 5 THROWIFNOT // slice length + <{ + PLDREF + CTOS + 160 LDU + }> PUSHCONT + REPEAT + DROP + DEPTH + TUPLEVAR + }> PUSHCONT + 1 1 CALLXARGS +} + +// only for 1-6 elements +asm extends fun sort(self: FakeTuple): FakeTuple { // not mutates + CONT:<{ + 6 EXPLODE + DEC + CONT:<{ }> + CONT:<{ MINMAX }> + CONT:<{ + MINMAX // 1 0 2 (0, 2) + -ROT // 2 1 0 + MINMAX // 2 0 1 (0, 1) + ROT // 0 1 2 + MINMAX // 0 1 2 (1, 2) + }> + CONT:<{ + MINMAX // 3 1 0 2 (0, 2) + SWAP2 // 0 2 3 1 + MINMAX // 0 2 1 3 (1, 3) + ROT // 0 1 3 2 + MINMAX // 0 1 2 3 (2, 3) + SWAP2 // 2 3 0 1 + MINMAX // 2 3 0 1 (0, 1) + 3 ROLL // 3 0 1 2 + MINMAX // 3 0 1 2 (1, 2) + 3 ROLL // 0 1 2 3 + }> + CONT:<{ + MINMAX // 2 4 1 0 3 (0, 3) + SWAP2 // 2 0 3 4 1 + MINMAX // 2 0 3 1 4 (1, 4) + s3 s4 XCHG2 // 4 1 3 0 2 + MINMAX // 4 1 3 0 2 (0, 2) + SWAP2 // 4 0 2 1 3 + MINMAX // 4 0 2 1 3 (1, 3) + s3 XCHG0 // 4 3 2 1 0 + MINMAX // 4 3 2 0 1 (0, 1) + s3 s4 s3 XCHG3 // 0 1 3 4 2 + MINMAX // 0 1 3 2 4 (2, 4) + s3 XCHG0 // 0 4 3 2 1 + MINMAX // 0 4 3 1 2 (1, 2) + SWAP2 // 0 1 2 4 3 + MINMAX // 0 1 2 3 4 (3, 4) + -ROT // 0 1 4 2 3 + MINMAX // 0 1 4 2 3 (2, 3) + ROT // 0 1 2 3 4 + }> + CONT:<{ + MINMAX // 4 2 3 1 0 5 (0, 5) + SWAP2 // 4 2 0 5 3 1 + MINMAX // 4 2 0 5 1 3 (1, 3) + 2 4 BLKSWAP // 0 5 1 3 4 2 + MINMAX // 0 5 1 3 2 4 (2, 4) + s3 XCHG0 // 0 5 4 3 2 1 + MINMAX // 0 5 4 3 1 2 (1, 2) + SWAP2 // 0 5 1 2 4 3 + MINMAX // 0 5 1 2 3 4 (3, 4) + s0 s4 s1 XCHG3 // 0 3 1 4 2 5 + MINMAX // 0 3 1 4 2 5 (2, 5) + 2 4 BLKSWAP // 1 4 2 5 0 3 + MINMAX // 1 4 2 5 0 3 (0, 3) + s5 XCHG0 // 3 4 2 5 0 1 + MINMAX // 3 4 2 5 0 1 (0, 1) + s5 s3 s2 XCHG3 // 5 4 0 1 2 3 + MINMAX // 5 4 0 1 2 3 (2, 3) + 2 4 BLKSWAP // 0 1 2 3 5 4 + MINMAX // 0 1 2 3 4 5 (4, 5) + 2 3 BLKSWAP // 0 3 4 5 1 2 + MINMAX // 0 3 4 5 1 2 (1, 2) + 2 3 BLKSWAP // 0 5 1 2 3 4 + MINMAX // 0 5 1 2 3 4 (3, 4) + 4 ROLL + }> + + 6 TUPLE + + SWAP INDEXVAR EXECUTE DEPTH TUPLEVAR + + }> 1 1 CALLXARGS +} diff --git a/oracles/redstone/single-feed-man/single-feed-man.spec.ts b/oracles/redstone/single-feed-man/single-feed-man.spec.ts new file mode 100644 index 0000000..e373afd --- /dev/null +++ b/oracles/redstone/single-feed-man/single-feed-man.spec.ts @@ -0,0 +1,163 @@ +import "@ton/test-utils" +import {SandboxContract, TreasuryContract, Blockchain} from "@ton/sandbox" +import { + ReadPrice, + SingleFeedMan, + storeReadPrice, + storeUpdatePrice, + UpdatePrice, +} from "../../output/SingleFeedMan_SingleFeedMan" +import {beginCell, toNano} from "@ton/core" +import { + getRedstoneSigners, + getRedstoneSignedDataPackages, + serializeSignedDataPackages, + serializeSigners, + signersToBigInt, + feedIdToBigInt, + deserializeSigners, +} from "../utils" + +describe("SingleFeedMan tests", () => { + let blockchain: Blockchain + let deployer: SandboxContract + let singleFeedMan: SandboxContract + let feedId = "TON" + + beforeAll(async () => { + blockchain = await Blockchain.create() + deployer = await blockchain.treasury("deployer") + + const signers = getRedstoneSigners() + + singleFeedMan = blockchain.openContract( + await SingleFeedMan.fromInit( + feedIdToBigInt(feedId), + serializeSigners(signersToBigInt(signers)), + BigInt(Math.min(signers.length, 3)), + { + $$type: "PriceData", + timestamp: 0n, + price: 0n, + }, + ), + ) + + const deployResult = await singleFeedMan.send( + deployer.getSender(), + {value: toNano("0.05"), bounce: false}, + null, + ) + + expect(deployResult.transactions).toHaveTransaction({ + to: singleFeedMan.address, + deploy: true, + success: true, + }) + }) + + it("should deploy", async () => { + const res = await singleFeedMan.getFeedId() + expect(res).toBe(feedIdToBigInt(feedId)) + + const res2 = await singleFeedMan.getLastPriceData() + expect(res2.price).toBe(0n) + expect(res2.timestamp).toBe(0n) + }) + + it("should check data packages and return correct price and timestamp (test getPriceData)", async () => { + const signers = deserializeSigners(await singleFeedMan.getSigners()) + const signedDataPackages = await getRedstoneSignedDataPackages(feedId, signers) + + const signedDataPackagesCell = serializeSignedDataPackages(signedDataPackages, signers) + + const res = await singleFeedMan.getPriceData(signedDataPackagesCell.asSlice()) + + const prices = signedDataPackages.map(signedDataPackage => + BigInt( + ~~((signedDataPackage.dataPackage.dataPoints[0].toObj().value as number) * 10 ** 8), + ), + ) + const timestamps = signedDataPackages.map(signedDataPackage => + BigInt(~~(signedDataPackage.dataPackage.timestampMilliseconds / 1000)), + ) + + // console.log(prices) + // console.log(timestamps) + const getMedian = (arr: bigint[]) => { + const sorted = arr.sort((a, b) => Number(a - b)) + const len = sorted.length + const q = Math.floor(len / 2) + const r = len % 2 + return (sorted[q] + sorted[q - 1 + r] + 1n) / 2n + } + + const medianPrice = getMedian(prices) + const minTimestamp = timestamps.reduce( + (min, curr) => (min < curr ? min : curr), + timestamps[0], + ) + + expect(res.price).toBe(medianPrice) + expect(res.timestamp).toBe(minTimestamp) + }) + + it("should correctly update price and read price (test UpdatePrice and ReadPrice)", async () => { + const signers = deserializeSigners(await singleFeedMan.getSigners()) + const signedDataPackages = await getRedstoneSignedDataPackages(feedId, signers) + + const signedDataPackagesCell = serializeSignedDataPackages(signedDataPackages, signers) + + const bodyStruct: UpdatePrice = { + $$type: "UpdatePrice", + feedId: feedIdToBigInt(feedId), + dataPackages: signedDataPackagesCell.asSlice(), + } + + const res = await singleFeedMan.send( + deployer.getSender(), + {value: toNano("0.05")}, + bodyStruct, + ) + + expect(res.transactions).toHaveTransaction({ + from: deployer.address, + to: singleFeedMan.address, + success: true, + op: SingleFeedMan.opcodes.UpdatePrice, + outMessagesCount: 1, + body: beginCell().store(storeUpdatePrice(bodyStruct)).endCell(), + }) + + expect(res.transactions).toHaveTransaction({ + from: singleFeedMan.address, + to: deployer.address, + op: SingleFeedMan.opcodes.PriceResponse, + }) + + const body2Struct: ReadPrice = { + $$type: "ReadPrice", + feedId: feedIdToBigInt(feedId), + } + + const res2 = await singleFeedMan.send( + deployer.getSender(), + {value: toNano("0.05")}, + body2Struct, + ) + + expect(res2.transactions).toHaveTransaction({ + from: deployer.address, + to: singleFeedMan.address, + op: SingleFeedMan.opcodes.ReadPrice, + outMessagesCount: 1, + body: beginCell().store(storeReadPrice(body2Struct)).endCell(), + }) + + expect(res2.transactions).toHaveTransaction({ + from: singleFeedMan.address, + to: deployer.address, + op: SingleFeedMan.opcodes.PriceResponse, + }) + }) +}) diff --git a/oracles/redstone/single-feed-man/single-feed-man.tact b/oracles/redstone/single-feed-man/single-feed-man.tact new file mode 100644 index 0000000..7593e76 --- /dev/null +++ b/oracles/redstone/single-feed-man/single-feed-man.tact @@ -0,0 +1,163 @@ +import "./crypto"; +import "./utils"; +import "./fake-tuple"; + +message(0xAB0BA_0) UpdatePrice { + feedId: Int as uint256; + dataPackages: Slice as remaining; +} + +message(0xAB0BA_1) ReadPrice { + feedId: Int as uint256; +} + +message(0xAB0BA_2) PriceResponse { + feedId: Int as uint256; + priceData: PriceData; +} + +contract SingleFeedMan( + // Feed ID to read from Redstone + storedFeedId: Int as uint256, + // // Info for checking signatures + signers: Cell, + signerCountThreshold: Int as uint8, + // // Last updated price + lastPriceData: PriceData, +) { + receive() {} + + inline fun sendPriceResponse() { + message(MessageParameters { + value: 0, + to: sender(), + bounce: false, + mode: SendRemainingValue | SendBounceIfActionFail, + body: PriceResponse { + feedId: self.storedFeedId, + priceData: self.lastPriceData, + }.toCell(), + }); + } + + receive(msg: UpdatePrice) { + require(msg.feedId == self.storedFeedId, "Feed ID mismatch"); + let priceData = self.priceData(msg.dataPackages); + self.lastPriceData = priceData; + self.sendPriceResponse(); + } + + receive(msg: ReadPrice) { + require(msg.feedId == self.storedFeedId, "Feed ID mismatch"); + self.sendPriceResponse(); + } + + get fun lastPriceData(): PriceData { + return self.lastPriceData; + } + + get fun priceData(dataPackages: Slice): PriceData { + let length = dataPackages.loadUint(16); + + let signersTuple = self.signers.toTuple(); + let pricesTuple = emptyTuple(); + let minTimestamp = 0xFFFFFFFFFFFFFFFF; + + repeat (length) { + let snakeCell = dataPackages.loadRef(); + let PackagesSnake { signedPackage, cont } = PackagesSnake.fromCell(snakeCell); + dataPackages = cont; + + let SignedDataPackageStruct { index, signature, data: dataPackage } = signedPackage; + let DataPackageStruct { dataFeedId, price, timestamp } = dataPackage.loadDataPackage(); + + let timestampIsValid = (now() - timestamp).inRange(-MAX_AHEAD_SECONDS, MAX_DELAY_SECONDS); + let feedIdIsValid = dataFeedId == self.storedFeedId; + let signIsValid = signersTuple.atInt(index) == recoverAddress(dataPackage.keccak(), signature); + + if (timestampIsValid && feedIdIsValid && signIsValid) { + pricesTuple.pushInt(price); + minTimestamp = min(minTimestamp, timestamp); + } + } + + require(pricesTuple.length() >= self.signerCountThreshold, "Not enough valid packages"); + require(minTimestamp > self.lastPriceData.timestamp, "Timestamp is not greater than last timestamp"); + + let median = pricesTuple.median(); + + return PriceData { + timestamp: minTimestamp, + price: median, + }; + } + + get fun signers(): Cell { + return self.signers; + } + + get fun feedId(): Int { + return self.storedFeedId; + } +} + +struct SignedDataPackageStruct { + index: Int as uint16; + signature: EcdsaSignature; + data: Slice; +} + +struct PackagesSnake { + signedPackage: SignedDataPackageStruct; + cont: Slice as remaining; +} + +struct DataPackageStruct { + timestamp: Int as uint48; + dataFeedId: Int as uint256; + price: Int as uint256; +} + +struct PriceData { + timestamp: Int as uint48; + price: Int as uint256; +} + +const DP_COUNT_BITS: Int = 24; +const DP_VALUE_BYTE_SIZE_BITS: Int = 32; + +const FEED_ID_BITS: Int = 256; +const PRICE_BITS: Int = 256; +const TIMESTAMP_BITS: Int = 48; +const MAX_DELAY_SECONDS: Int = 900; // 15 * 60 +const MAX_AHEAD_SECONDS: Int = 180; // 3 * 60 + +extends inline fun loadDataPackage(self: Slice): DataPackageStruct { + // this function is veeery different from FunC because the data is arranged completely differently + // not sure if the FunC code even works + // fffffffffffffffffffffff + // read package meta + let tail = self.lastBits(DP_COUNT_BITS + DP_VALUE_BYTE_SIZE_BITS + TIMESTAMP_BITS); + + let timestamp = tail.loadUint(TIMESTAMP_BITS) / 1000; + + let valueSizeBits = tail.loadUint(DP_VALUE_BYTE_SIZE_BITS) * 8; + require(valueSizeBits <= PRICE_BITS, "Value size bits must be less than or equal to price bits"); + require(valueSizeBits > 0, "Value size bits must be greater than 0"); + + let dataPointsCount = tail.loadUint(DP_COUNT_BITS); + require(dataPointsCount == 1, "Only one data point is supported"); + + // read package data + let head = self.loadBits(FEED_ID_BITS); + + let dataFeedId = head.loadUint(FEED_ID_BITS - head.numberTrailingZeros() / 8 * 8); + + let price = self.loadUint(valueSizeBits); + + return DataPackageStruct { + timestamp, + dataFeedId, + price, + }; +} diff --git a/oracles/redstone/single-feed-man/utils.tact b/oracles/redstone/single-feed-man/utils.tact new file mode 100644 index 0000000..198f1b9 --- /dev/null +++ b/oracles/redstone/single-feed-man/utils.tact @@ -0,0 +1,9 @@ +struct DivModResult { + quotient: Int; + remainder: Int; +} +asm extends fun divmod(self: Int, other: Int): DivModResult { DIVMOD } + +asm(self to from) extends fun inRange(self: Int, from: Int, to: Int): Bool { s2 PUSH MAX MIN EQUAL } + +asm extends fun numberTrailingZeros(self: Slice): Int { SDCNTTRAIL0 } diff --git a/oracles/redstone/utils.ts b/oracles/redstone/utils.ts new file mode 100644 index 0000000..a24703f --- /dev/null +++ b/oracles/redstone/utils.ts @@ -0,0 +1,156 @@ +import { + getOracleRegistryStateSync, + getSignersForDataServiceId, + requestDataPackages, +} from "@redstone-finance/sdk" +import { + DataPackage as RedstoneDataPackage, + SignedDataPackage as RedstoneSignedDataPackage, +} from "@redstone-finance/protocol" +import {RedstoneOraclesState} from "@redstone-finance/oracles-smartweave-contracts" +import {beginCell, Cell, Slice} from "@ton/core" +import { + EcdsaSignature, + SignedDataPackageStruct, + storeSignedDataPackageStruct, +} from "../output/SingleFeedMan_SingleFeedMan" +import {Signature as RedstoneSignature} from "@ethersproject/bytes" +import {getAddress, hexlify, toUtf8Bytes} from "ethers/lib/utils" + +const REDSTONE_STATE: RedstoneOraclesState = getOracleRegistryStateSync() +const DATA_SERVICE_ID = "redstone-primary-prod" + +export const bigIntToEthAddress = (bigInt: bigint) => { + return getAddress(bigInt.toString(16)) +} + +export const feedIdToBigInt = (str: string): bigint => { + return BigInt(hexlify(toUtf8Bytes(str))) +} + +export const signersToBigInt = (signers: string[]) => { + return signers.map(signer => BigInt(signer)) +} + +export const signersToStrings = (signers: bigint[]) => { + return signers.map(signer => bigIntToEthAddress(signer)) +} + +export const packSignature = (signature: RedstoneSignature): EcdsaSignature => { + return { + $$type: "EcdsaSignature", + r: BigInt(signature.r), + s: BigInt(signature.s), + recoveryParam: BigInt(signature.recoveryParam), + } +} + +export const serializeRedstoneDataPackage = (dataPackage: RedstoneDataPackage) => { + return beginCell().storeBuffer(Buffer.from(dataPackage.toBytes())).endCell() +} + +export const packSignedDataPackage = ( + dataPackage: RedstoneSignedDataPackage, + index: bigint = 0n, +): SignedDataPackageStruct => { + return { + $$type: "SignedDataPackageStruct", + index, + signature: packSignature(dataPackage.signature), + data: serializeRedstoneDataPackage(dataPackage.dataPackage).beginParse(), + } +} + +export const getRedstoneSigners = () => { + return getSignersForDataServiceId(REDSTONE_STATE, DATA_SERVICE_ID) +} + +export const getRedstoneSignedDataPackages = async ( + dataPackagesId: string, + signers: string[] | bigint[], +): Promise => { + return ( + await requestDataPackages({ + dataServiceId: DATA_SERVICE_ID, + dataPackagesIds: [dataPackagesId], + uniqueSignersCount: signers.length, + authorizedSigners: signers.map(signer => + typeof signer === "string" ? signer : bigIntToEthAddress(signer), + ), + }) + )[dataPackagesId]! +} + +function serializeTupleShort(tuple: T[], serializer: (item: T) => Cell): Cell { + let endCell: Cell | undefined + if (tuple.length > 7) { + throw new Error("Tuple length is too long") + } + + for (const item of tuple.slice().reverse()) { + let builder = beginCell().storeSlice(serializer(item).asSlice()) + + if (endCell) { + builder.storeRef(endCell) + } + + endCell = builder.endCell() + } + + let builder = beginCell().storeUint(tuple.length, 16) + + if (endCell) { + builder.storeRef(endCell) + } + + return builder.endCell() +} + +function deserializeTupleShort(cell: Cell, deserializer: (slice: Slice) => T): T[] { + let slice = cell.beginParse() + const length = slice.loadUint(16) + + if (length > 7) { + throw new Error("Tuple length is too long") + } + + const tuple = new Array(length) + + for (let i = 0; i < length; i++) { + slice = slice.loadRef().beginParse() + tuple[i] = deserializer(slice) + } + + return tuple +} + +export const serializeSignedDataPackages = ( + signedDataPackages: RedstoneSignedDataPackage[], + signers: string[], +) => { + const signedDataPackagesStructs = signedDataPackages.map(signedDataPackage => + packSignedDataPackage( + signedDataPackage, + BigInt( + signers.findIndex(signer => signer === signedDataPackage.recoverSignerAddress()), + ), + ), + ) + + return serializeTupleShort(signedDataPackagesStructs, signedDataPackageStruct => + beginCell().store(storeSignedDataPackageStruct(signedDataPackageStruct)).endCell(), + ) +} + +export const serializeSigners = (signers: bigint[] | string[]) => { + const signersBigInt = signers.map(signer => + typeof signer === "string" ? BigInt(signer) : signer, + ) + return serializeTupleShort(signersBigInt, signer => + beginCell().storeUint(signer, 160).endCell(), + ) +} + +export const deserializeSigners = (cell: Cell) => { + return deserializeTupleShort(cell, slice => bigIntToEthAddress(slice.loadUintBig(160))) +} diff --git a/package.json b/package.json index e981d7f..ca4388c 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "lint": "tact-fmt --check ./jettons && yarn misti ./tact.config.json", "lint:es": "eslint .", "lint:fix": "eslint . --fix", - "test": "yarn build && jest jettons", + "test": "yarn build && jest jettons && jest oracles", "fmt": "yarn prettier -l -w .", "fmt:check": "yarn prettier --check .", "fmt:tact": "tact-fmt --write ./jettons", @@ -18,6 +18,7 @@ "@aws-crypto/sha256-js": "^5.2.0", "@nowarp/misti": "~0.8.0", "@orbs-network/ton-access": "^2.3.3", + "@redstone-finance/ton-connector": "^0.8.0", "@tact-lang/compiler": "^1.6.10", "@tact-lang/ton-jest": "^0.0.4", "@ton/core": "^0.60.1", diff --git a/spell/custom-dictionary.txt b/spell/custom-dictionary.txt index 514cb90..cf66adb 100644 --- a/spell/custom-dictionary.txt +++ b/spell/custom-dictionary.txt @@ -26,3 +26,8 @@ TUSDT UQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJKZ workchain yada +dont +Merkle +smartweave +ethersproject +hexlify diff --git a/tact.config.json b/tact.config.json index 1a58fad..6f7114b 100644 --- a/tact.config.json +++ b/tact.config.json @@ -119,6 +119,36 @@ "inline": true } } + }, + { + "name": "SingleFeedMan", + "path": "./oracles/redstone/single-feed-man/single-feed-man.tact", + "output": "./oracles/output", + "mode": "full", + "options": { + "external": false, + "debug": false, + "ipfsAbiGetter": false, + "interfacesGetter": false, + "experimental": { + "inline": true + } + } + }, + { + "name": "SampleConsumer", + "path": "./oracles/redstone/sample-consumer/sample-consumer.tact", + "output": "./oracles/output", + "mode": "full", + "options": { + "external": false, + "debug": false, + "ipfsAbiGetter": false, + "interfacesGetter": false, + "experimental": { + "inline": true + } + } } ] } diff --git a/tsconfig.json b/tsconfig.json index 38f582f..0bd0288 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -63,5 +63,5 @@ "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, "resolveJsonModule": true }, - "include": ["jettons/**/*"] + "include": ["jettons/**/*", "oracles/**/*"] } diff --git a/yarn.lock b/yarn.lock index 7f31d64..e0250a2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -782,6 +782,348 @@ "@eslint/core" "^0.12.0" levn "^0.4.1" +"@ethersproject/abi@5.8.0", "@ethersproject/abi@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.8.0.tgz#e79bb51940ac35fe6f3262d7fe2cdb25ad5f07d9" + integrity sha512-b9YS/43ObplgyV6SlyQsG53/vkSal0MNA1fskSC4mbnCMi8R+NkcH8K9FPYNESf6jUefBUniE4SOKms0E/KK1Q== + dependencies: + "@ethersproject/address" "^5.8.0" + "@ethersproject/bignumber" "^5.8.0" + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/constants" "^5.8.0" + "@ethersproject/hash" "^5.8.0" + "@ethersproject/keccak256" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + "@ethersproject/properties" "^5.8.0" + "@ethersproject/strings" "^5.8.0" + +"@ethersproject/abstract-provider@5.8.0", "@ethersproject/abstract-provider@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.8.0.tgz#7581f9be601afa1d02b95d26b9d9840926a35b0c" + integrity sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg== + dependencies: + "@ethersproject/bignumber" "^5.8.0" + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + "@ethersproject/networks" "^5.8.0" + "@ethersproject/properties" "^5.8.0" + "@ethersproject/transactions" "^5.8.0" + "@ethersproject/web" "^5.8.0" + +"@ethersproject/abstract-signer@5.8.0", "@ethersproject/abstract-signer@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.8.0.tgz#8d7417e95e4094c1797a9762e6789c7356db0754" + integrity sha512-N0XhZTswXcmIZQdYtUnd79VJzvEwXQw6PK0dTl9VoYrEBxxCPXqS0Eod7q5TNKRxe1/5WUMuR0u0nqTF/avdCA== + dependencies: + "@ethersproject/abstract-provider" "^5.8.0" + "@ethersproject/bignumber" "^5.8.0" + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + "@ethersproject/properties" "^5.8.0" + +"@ethersproject/address@5.8.0", "@ethersproject/address@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.8.0.tgz#3007a2c352eee566ad745dca1dbbebdb50a6a983" + integrity sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA== + dependencies: + "@ethersproject/bignumber" "^5.8.0" + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/keccak256" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + "@ethersproject/rlp" "^5.8.0" + +"@ethersproject/base64@5.8.0", "@ethersproject/base64@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.8.0.tgz#61c669c648f6e6aad002c228465d52ac93ee83eb" + integrity sha512-lN0oIwfkYj9LbPx4xEkie6rAMJtySbpOAFXSDVQaBnAzYfB4X2Qr+FXJGxMoc3Bxp2Sm8OwvzMrywxyw0gLjIQ== + dependencies: + "@ethersproject/bytes" "^5.8.0" + +"@ethersproject/basex@5.8.0", "@ethersproject/basex@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.8.0.tgz#1d279a90c4be84d1c1139114a1f844869e57d03a" + integrity sha512-PIgTszMlDRmNwW9nhS6iqtVfdTAKosA7llYXNmGPw4YAI1PUyMv28988wAb41/gHF/WqGdoLv0erHaRcHRKW2Q== + dependencies: + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/properties" "^5.8.0" + +"@ethersproject/bignumber@5.8.0", "@ethersproject/bignumber@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.8.0.tgz#c381d178f9eeb370923d389284efa19f69efa5d7" + integrity sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA== + dependencies: + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + bn.js "^5.2.1" + +"@ethersproject/bytes@5.8.0", "@ethersproject/bytes@^5.6.1", "@ethersproject/bytes@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.8.0.tgz#9074820e1cac7507a34372cadeb035461463be34" + integrity sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A== + dependencies: + "@ethersproject/logger" "^5.8.0" + +"@ethersproject/constants@5.8.0", "@ethersproject/constants@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.8.0.tgz#12f31c2f4317b113a4c19de94e50933648c90704" + integrity sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg== + dependencies: + "@ethersproject/bignumber" "^5.8.0" + +"@ethersproject/contracts@5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.8.0.tgz#243a38a2e4aa3e757215ea64e276f8a8c9d8ed73" + integrity sha512-0eFjGz9GtuAi6MZwhb4uvUM216F38xiuR0yYCjKJpNfSEy4HUM8hvqqBj9Jmm0IUz8l0xKEhWwLIhPgxNY0yvQ== + dependencies: + "@ethersproject/abi" "^5.8.0" + "@ethersproject/abstract-provider" "^5.8.0" + "@ethersproject/abstract-signer" "^5.8.0" + "@ethersproject/address" "^5.8.0" + "@ethersproject/bignumber" "^5.8.0" + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/constants" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + "@ethersproject/properties" "^5.8.0" + "@ethersproject/transactions" "^5.8.0" + +"@ethersproject/hash@5.8.0", "@ethersproject/hash@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.8.0.tgz#b8893d4629b7f8462a90102572f8cd65a0192b4c" + integrity sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA== + dependencies: + "@ethersproject/abstract-signer" "^5.8.0" + "@ethersproject/address" "^5.8.0" + "@ethersproject/base64" "^5.8.0" + "@ethersproject/bignumber" "^5.8.0" + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/keccak256" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + "@ethersproject/properties" "^5.8.0" + "@ethersproject/strings" "^5.8.0" + +"@ethersproject/hdnode@5.8.0", "@ethersproject/hdnode@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.8.0.tgz#a51ae2a50bcd48ef6fd108c64cbae5e6ff34a761" + integrity sha512-4bK1VF6E83/3/Im0ERnnUeWOY3P1BZml4ZD3wcH8Ys0/d1h1xaFt6Zc+Dh9zXf9TapGro0T4wvO71UTCp3/uoA== + dependencies: + "@ethersproject/abstract-signer" "^5.8.0" + "@ethersproject/basex" "^5.8.0" + "@ethersproject/bignumber" "^5.8.0" + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + "@ethersproject/pbkdf2" "^5.8.0" + "@ethersproject/properties" "^5.8.0" + "@ethersproject/sha2" "^5.8.0" + "@ethersproject/signing-key" "^5.8.0" + "@ethersproject/strings" "^5.8.0" + "@ethersproject/transactions" "^5.8.0" + "@ethersproject/wordlists" "^5.8.0" + +"@ethersproject/json-wallets@5.8.0", "@ethersproject/json-wallets@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.8.0.tgz#d18de0a4cf0f185f232eb3c17d5e0744d97eb8c9" + integrity sha512-HxblNck8FVUtNxS3VTEYJAcwiKYsBIF77W15HufqlBF9gGfhmYOJtYZp8fSDZtn9y5EaXTE87zDwzxRoTFk11w== + dependencies: + "@ethersproject/abstract-signer" "^5.8.0" + "@ethersproject/address" "^5.8.0" + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/hdnode" "^5.8.0" + "@ethersproject/keccak256" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + "@ethersproject/pbkdf2" "^5.8.0" + "@ethersproject/properties" "^5.8.0" + "@ethersproject/random" "^5.8.0" + "@ethersproject/strings" "^5.8.0" + "@ethersproject/transactions" "^5.8.0" + aes-js "3.0.0" + scrypt-js "3.0.1" + +"@ethersproject/keccak256@5.8.0", "@ethersproject/keccak256@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.8.0.tgz#d2123a379567faf2d75d2aaea074ffd4df349e6a" + integrity sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng== + dependencies: + "@ethersproject/bytes" "^5.8.0" + js-sha3 "0.8.0" + +"@ethersproject/logger@5.8.0", "@ethersproject/logger@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.8.0.tgz#f0232968a4f87d29623a0481690a2732662713d6" + integrity sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA== + +"@ethersproject/networks@5.8.0", "@ethersproject/networks@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.8.0.tgz#8b4517a3139380cba9fb00b63ffad0a979671fde" + integrity sha512-egPJh3aPVAzbHwq8DD7Po53J4OUSsA1MjQp8Vf/OZPav5rlmWUaFLiq8cvQiGK0Z5K6LYzm29+VA/p4RL1FzNg== + dependencies: + "@ethersproject/logger" "^5.8.0" + +"@ethersproject/pbkdf2@5.8.0", "@ethersproject/pbkdf2@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.8.0.tgz#cd2621130e5dd51f6a0172e63a6e4a0c0a0ec37e" + integrity sha512-wuHiv97BrzCmfEaPbUFpMjlVg/IDkZThp9Ri88BpjRleg4iePJaj2SW8AIyE8cXn5V1tuAaMj6lzvsGJkGWskg== + dependencies: + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/sha2" "^5.8.0" + +"@ethersproject/properties@5.8.0", "@ethersproject/properties@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.8.0.tgz#405a8affb6311a49a91dabd96aeeae24f477020e" + integrity sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw== + dependencies: + "@ethersproject/logger" "^5.8.0" + +"@ethersproject/providers@5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.8.0.tgz#6c2ae354f7f96ee150439f7de06236928bc04cb4" + integrity sha512-3Il3oTzEx3o6kzcg9ZzbE+oCZYyY+3Zh83sKkn4s1DZfTUjIegHnN2Cm0kbn9YFy45FDVcuCLLONhU7ny0SsCw== + dependencies: + "@ethersproject/abstract-provider" "^5.8.0" + "@ethersproject/abstract-signer" "^5.8.0" + "@ethersproject/address" "^5.8.0" + "@ethersproject/base64" "^5.8.0" + "@ethersproject/basex" "^5.8.0" + "@ethersproject/bignumber" "^5.8.0" + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/constants" "^5.8.0" + "@ethersproject/hash" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + "@ethersproject/networks" "^5.8.0" + "@ethersproject/properties" "^5.8.0" + "@ethersproject/random" "^5.8.0" + "@ethersproject/rlp" "^5.8.0" + "@ethersproject/sha2" "^5.8.0" + "@ethersproject/strings" "^5.8.0" + "@ethersproject/transactions" "^5.8.0" + "@ethersproject/web" "^5.8.0" + bech32 "1.1.4" + ws "8.18.0" + +"@ethersproject/random@5.8.0", "@ethersproject/random@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.8.0.tgz#1bced04d49449f37c6437c701735a1a022f0057a" + integrity sha512-E4I5TDl7SVqyg4/kkA/qTfuLWAQGXmSOgYyO01So8hLfwgKvYK5snIlzxJMk72IFdG/7oh8yuSqY2KX7MMwg+A== + dependencies: + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + +"@ethersproject/rlp@5.8.0", "@ethersproject/rlp@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.8.0.tgz#5a0d49f61bc53e051532a5179472779141451de5" + integrity sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q== + dependencies: + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + +"@ethersproject/sha2@5.8.0", "@ethersproject/sha2@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.8.0.tgz#8954a613bb78dac9b46829c0a95de561ef74e5e1" + integrity sha512-dDOUrXr9wF/YFltgTBYS0tKslPEKr6AekjqDW2dbn1L1xmjGR+9GiKu4ajxovnrDbwxAKdHjW8jNcwfz8PAz4A== + dependencies: + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + hash.js "1.1.7" + +"@ethersproject/signing-key@5.8.0", "@ethersproject/signing-key@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.8.0.tgz#9797e02c717b68239c6349394ea85febf8893119" + integrity sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w== + dependencies: + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + "@ethersproject/properties" "^5.8.0" + bn.js "^5.2.1" + elliptic "6.6.1" + hash.js "1.1.7" + +"@ethersproject/solidity@5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.8.0.tgz#429bb9fcf5521307a9448d7358c26b93695379b9" + integrity sha512-4CxFeCgmIWamOHwYN9d+QWGxye9qQLilpgTU0XhYs1OahkclF+ewO+3V1U0mvpiuQxm5EHHmv8f7ClVII8EHsA== + dependencies: + "@ethersproject/bignumber" "^5.8.0" + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/keccak256" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + "@ethersproject/sha2" "^5.8.0" + "@ethersproject/strings" "^5.8.0" + +"@ethersproject/strings@5.8.0", "@ethersproject/strings@^5.7.0", "@ethersproject/strings@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.8.0.tgz#ad79fafbf0bd272d9765603215ac74fd7953908f" + integrity sha512-qWEAk0MAvl0LszjdfnZ2uC8xbR2wdv4cDabyHiBh3Cldq/T8dPH3V4BbBsAYJUeonwD+8afVXld274Ls+Y1xXg== + dependencies: + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/constants" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + +"@ethersproject/transactions@5.8.0", "@ethersproject/transactions@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.8.0.tgz#1e518822403abc99def5a043d1c6f6fe0007e46b" + integrity sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg== + dependencies: + "@ethersproject/address" "^5.8.0" + "@ethersproject/bignumber" "^5.8.0" + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/constants" "^5.8.0" + "@ethersproject/keccak256" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + "@ethersproject/properties" "^5.8.0" + "@ethersproject/rlp" "^5.8.0" + "@ethersproject/signing-key" "^5.8.0" + +"@ethersproject/units@5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.8.0.tgz#c12f34ba7c3a2de0e9fa0ed0ee32f3e46c5c2c6a" + integrity sha512-lxq0CAnc5kMGIiWW4Mr041VT8IhNM+Pn5T3haO74XZWFulk7wH1Gv64HqE96hT4a7iiNMdOCFEBgaxWuk8ETKQ== + dependencies: + "@ethersproject/bignumber" "^5.8.0" + "@ethersproject/constants" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + +"@ethersproject/wallet@5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.8.0.tgz#49c300d10872e6986d953e8310dc33d440da8127" + integrity sha512-G+jnzmgg6UxurVKRKvw27h0kvG75YKXZKdlLYmAHeF32TGUzHkOFd7Zn6QHOTYRFWnfjtSSFjBowKo7vfrXzPA== + dependencies: + "@ethersproject/abstract-provider" "^5.8.0" + "@ethersproject/abstract-signer" "^5.8.0" + "@ethersproject/address" "^5.8.0" + "@ethersproject/bignumber" "^5.8.0" + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/hash" "^5.8.0" + "@ethersproject/hdnode" "^5.8.0" + "@ethersproject/json-wallets" "^5.8.0" + "@ethersproject/keccak256" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + "@ethersproject/properties" "^5.8.0" + "@ethersproject/random" "^5.8.0" + "@ethersproject/signing-key" "^5.8.0" + "@ethersproject/transactions" "^5.8.0" + "@ethersproject/wordlists" "^5.8.0" + +"@ethersproject/web@5.8.0", "@ethersproject/web@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.8.0.tgz#3e54badc0013b7a801463a7008a87988efce8a37" + integrity sha512-j7+Ksi/9KfGviws6Qtf9Q7KCqRhpwrYKQPs+JBA/rKVFF/yaWLHJEH3zfVP2plVu+eys0d2DlFmhoQJayFewcw== + dependencies: + "@ethersproject/base64" "^5.8.0" + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + "@ethersproject/properties" "^5.8.0" + "@ethersproject/strings" "^5.8.0" + +"@ethersproject/wordlists@5.8.0", "@ethersproject/wordlists@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.8.0.tgz#7a5654ee8d1bb1f4dbe43f91d217356d650ad821" + integrity sha512-2df9bbXicZws2Sb5S6ET493uJ0Z84Fjr3pC4tu/qlnZERibZCeUVuqdtt+7Tv9xxhUxHoIekIA7avrKUWHrezg== + dependencies: + "@ethersproject/bytes" "^5.8.0" + "@ethersproject/hash" "^5.8.0" + "@ethersproject/logger" "^5.8.0" + "@ethersproject/properties" "^5.8.0" + "@ethersproject/strings" "^5.8.0" + "@humanfs/core@^0.19.1": version "0.19.1" resolved "https://registry.yarnpkg.com/@humanfs/core/-/core-0.19.1.tgz#17c55ca7d426733fe3c561906b8173c336b40a77" @@ -1181,6 +1523,66 @@ resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== +"@redstone-finance/oracles-smartweave-contracts@0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@redstone-finance/oracles-smartweave-contracts/-/oracles-smartweave-contracts-0.8.0.tgz#aadcf19b0b65b662d92a5e3001e6eea42edb84d7" + integrity sha512-7lRYSIFeOdLkamUNTzGW5oaP07eXZtfa1jnyuloyIFTgEhSKA2JiAAo7tGqAFvI10Z3kdrLPp1XM4AEVxEMlNQ== + +"@redstone-finance/protocol@0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@redstone-finance/protocol/-/protocol-0.8.0.tgz#165559e4befba2277bfd13c44fd15cc75056aa08" + integrity sha512-QnNjRnMVn8IgGJvPjNet/E5Y0h7+OngqxdboKHBf9DKxmewOdDR/iYFQAfynDafoqUmsTp/+6caAZbhVkBZvYQ== + dependencies: + decimal.js "^10.4.3" + ethers "^5.7.2" + secp256k1 "^5.0.1" + +"@redstone-finance/sdk@0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@redstone-finance/sdk/-/sdk-0.8.0.tgz#28899fafa5f27199caf4b0ec695015bbd8c9fb94" + integrity sha512-yVVbIuZFi7u8ROWQ0php3h44z6SB1U6jVNsMxRt/nfq/jy/+CGdTkAfDX5s7CJDzgV8z9apEycLoJCHaPZL0QQ== + dependencies: + "@ethersproject/bytes" "^5.6.1" + "@ethersproject/strings" "^5.7.0" + "@redstone-finance/oracles-smartweave-contracts" "0.8.0" + "@redstone-finance/protocol" "0.8.0" + "@redstone-finance/utils" "0.8.0" + "@types/lodash" "^4.14.195" + axios "^1.7.9" + ethers "^5.7.2" + lodash "^4.17.21" + zod "^3.22.4" + +"@redstone-finance/ton-connector@^0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@redstone-finance/ton-connector/-/ton-connector-0.8.0.tgz#25ab2851418c4924a466d586dff790cfadc93b37" + integrity sha512-pMkI5QzdAf7zliqfc2tcoIU7IJbtMqflHJcBPU0fioQGqbxGDtTy2jdxV1i1Uy4Vw3n8rfpBbB8P4anVdF0qxA== + dependencies: + "@orbs-network/ton-access" "^2.3.3" + "@redstone-finance/protocol" "0.8.0" + "@redstone-finance/sdk" "0.8.0" + "@redstone-finance/utils" "0.8.0" + "@ton-community/func-js" "0.6.3" + "@ton-community/func-js-bin" "^0.4.5-tvmbeta.3" + "@ton/core" "^0.56.3" + "@ton/crypto" "^3.2.0" + "@ton/ton" "^13.11.1" + dotenv "^16.0.3" + ethers "^5.7.2" + +"@redstone-finance/utils@0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@redstone-finance/utils/-/utils-0.8.0.tgz#4f70a249a8aada330669186b5d0e246b991f3310" + integrity sha512-GT+G5gYDQ2tPD9cgnIa3a3m9EK3n2fVJbl7FSfqU4q5aSpMUWFW/CY20L243bb2bz76e151RFq01p6GXn/Cs7Q== + dependencies: + "@types/lodash" "^4.14.195" + axios "^1.7.9" + consola "^2.15.3" + decimal.js "^10.4.3" + ethers "^5.7.2" + lodash "^4.17.21" + zod "^3.22.4" + "@sinclair/typebox@^0.27.8": version "0.27.8" resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" @@ -1264,6 +1666,24 @@ resolved "https://registry.yarnpkg.com/@telegraf/types/-/types-7.1.0.tgz#d8bd9b2f5070b4de46971416e890338cd89fc23d" integrity sha512-kGevOIbpMcIlCDeorKGpwZmdH7kHbqlk/Yj6dEpJMKEQw5lk0KVQY0OLXaCswy8GqlIVLd5625OB+rAntP9xVw== +"@ton-community/func-js-bin@0.4.4-newops": + version "0.4.4-newops" + resolved "https://registry.yarnpkg.com/@ton-community/func-js-bin/-/func-js-bin-0.4.4-newops.tgz#6731b46921ac61fafa3091a8e0be4b8cb92fddc6" + integrity sha512-tvbnb/rpK+L/PmT0TwZctI00hvvWgkqRlsiFLsZUqLERo5BPDDnurYHnbt/VE/2gz9pljJ5mANmhwd0K6oW/2Q== + +"@ton-community/func-js-bin@^0.4.5-tvmbeta.3": + version "0.4.6" + resolved "https://registry.yarnpkg.com/@ton-community/func-js-bin/-/func-js-bin-0.4.6.tgz#cf7f23c7f24ddc3b98ce02c04f494d258a998318" + integrity sha512-nUH0YO4nQA4oDcBfqzZ62HG2nWTd414kEDnXmvr2uMSUxJH2KW3Nsc1i1Q/aXy8ZkxqChj1Z2/hT4YcJuEzUZA== + +"@ton-community/func-js@0.6.3": + version "0.6.3" + resolved "https://registry.yarnpkg.com/@ton-community/func-js/-/func-js-0.6.3.tgz#43b30c4f99a7c3786911989bc88e607c8acd33d5" + integrity sha512-38VEr8rikSWPwAVpLgzj5A6yGVaxhomXfOp99RnjPhUNQY7iE7bT0wMUTK5iOAnFIsHyKn6AQ3V692tN1ASNcg== + dependencies: + "@ton-community/func-js-bin" "0.4.4-newops" + arg "^5.0.2" + "@ton/core@0.60.1", "@ton/core@^0.60.0", "@ton/core@^0.60.1": version "0.60.1" resolved "https://registry.yarnpkg.com/@ton/core/-/core-0.60.1.tgz#cc9a62fb308d7597b1217dc8e44c7e2dcc0aceaa" @@ -1271,6 +1691,13 @@ dependencies: symbol.inspect "1.0.1" +"@ton/core@^0.56.3": + version "0.56.3" + resolved "https://registry.yarnpkg.com/@ton/core/-/core-0.56.3.tgz#1162764573abb76032eba70f8497e5cb2ea532ee" + integrity sha512-HVkalfqw8zqLLPehtq0CNhu5KjVzc7IrbDwDHPjGoOSXmnqSobiWj8a5F+YuWnZnEbQKtrnMGNOOjVw4LG37rg== + dependencies: + symbol.inspect "1.0.1" + "@ton/crypto-primitives@2.1.0": version "2.1.0" resolved "https://registry.yarnpkg.com/@ton/crypto-primitives/-/crypto-primitives-2.1.0.tgz#8c9277c250b59aae3c819e0d6bd61e44d998e9ca" @@ -1299,7 +1726,7 @@ dependencies: node-inspect-extracted "^2.0.0" -"@ton/ton@^13.9.0": +"@ton/ton@^13.11.1", "@ton/ton@^13.9.0": version "13.11.2" resolved "https://registry.yarnpkg.com/@ton/ton/-/ton-13.11.2.tgz#e40204df6a663fdf1b862dfe8ba2a91be3c0dddc" integrity sha512-EPqW+ZTe0MmfqguJEIGMuAqTAFRKMEce95HlDx8h6CGn2y3jiMgV1/oO+WpDIOiX+1wnTu+xtajk8JTWr8nKRQ== @@ -1437,6 +1864,11 @@ dependencies: "@types/node" "*" +"@types/lodash@^4.14.195": + version "4.17.17" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.17.tgz#fb85a04f47e9e4da888384feead0de05f7070355" + integrity sha512-RRVJ+J3J+WmyOTqnz3PiBLA501eKwXl2noseKOrNo/6+XEHjTAxO4xHvxQB6QuNm+s4WRbn6rSiap8+EA+ykFQ== + "@types/long@^4.0.1": version "4.0.2" resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" @@ -1657,6 +2089,11 @@ acorn@^8.11.0, acorn@^8.14.0, acorn@^8.4.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.1.tgz#721d5dc10f7d5b5609a891773d47731796935dfb" integrity sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg== +aes-js@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" + integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw== + ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" @@ -1721,6 +2158,11 @@ arg@^4.1.0: resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== +arg@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c" + integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -1763,10 +2205,10 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== -axios@^1.6.7: - version "1.8.4" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.8.4.tgz#78990bb4bc63d2cae072952d374835950a82f447" - integrity sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw== +axios@^1.6.7, axios@^1.7.9: + version "1.10.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.10.0.tgz#af320aee8632eaf2a400b6a1979fa75856f38d54" + integrity sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw== dependencies: follow-redirects "^1.15.6" form-data "^4.0.0" @@ -1850,6 +2292,11 @@ base64url@^3.0.1: resolved "https://registry.yarnpkg.com/base64url/-/base64url-3.0.1.tgz#6399d572e2bc3f90a9a8b22d5dbb0a32d33f788d" integrity sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A== +bech32@1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" + integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== + benchmark@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/benchmark/-/benchmark-2.1.4.tgz#09f3de31c916425d498cc2ee565a0ebf3c2a5629" @@ -1886,6 +2333,16 @@ blockstore-core@1.0.5: it-take "^1.0.1" multiformats "^9.4.7" +bn.js@^4.11.9: + version "4.12.2" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.2.tgz#3d8fed6796c24e177737f7cc5172ee04ef39ec99" + integrity sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw== + +bn.js@^5.2.1: + version "5.2.2" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.2.tgz#82c09f9ebbb17107cd72cb7fd39bd1f9d0aaa566" + integrity sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -1908,6 +2365,11 @@ braces@^3.0.3: dependencies: fill-range "^7.1.1" +brorand@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== + browserslist@^4.24.0, browserslist@^4.24.4: version "4.24.4" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.4.tgz#c6b2865a3f08bcb860a0e827389003b9fe686e4b" @@ -2171,6 +2633,11 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== +consola@^2.15.3: + version "2.15.3" + resolved "https://registry.yarnpkg.com/consola/-/consola-2.15.3.tgz#2e11f98d6a4be71ff72e0bdf07bd23e12cb61550" + integrity sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw== + convert-source-map@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" @@ -2366,6 +2833,11 @@ decamelize@^1.2.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== +decimal.js@^10.4.3: + version "10.5.0" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.5.0.tgz#0f371c7cf6c4898ce0afb09836db73cd82010f22" + integrity sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw== + dedent@^1.0.0: version "1.5.3" resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.3.tgz#99aee19eb9bae55a67327717b6e848d0bf777e5a" @@ -2452,10 +2924,10 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" -dotenv@^16.4.5: - version "16.4.7" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.7.tgz#0e20c5b82950140aa99be360a8a5f52335f53c26" - integrity sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ== +dotenv@^16.0.3, dotenv@^16.4.5: + version "16.5.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.5.0.tgz#092b49f25f808f020050051d1ff258e404c78692" + integrity sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg== dunder-proto@^1.0.0: version "1.0.1" @@ -2478,6 +2950,19 @@ electron-to-chromium@^1.5.73: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.76.tgz#db20295c5061b68f07c8ea4dfcbd701485d94a3d" integrity sha512-CjVQyG7n7Sr+eBXE86HIulnL5N8xZY1sgmOPGuq/F0Rr0FJq63lg0kEtOIDfZBk44FnDLf6FUJ+dsJcuiUDdDQ== +elliptic@6.6.1, elliptic@^6.5.7: + version "6.6.1" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.6.1.tgz#3b8ffb02670bf69e382c7f65bf524c97c5405c06" + integrity sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + emittery@^0.13.1: version "0.13.1" resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" @@ -2698,6 +3183,42 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +ethers@^5.7.2: + version "5.8.0" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.8.0.tgz#97858dc4d4c74afce83ea7562fe9493cedb4d377" + integrity sha512-DUq+7fHrCg1aPDFCHx6UIPb3nmt2XMpM7Y/g2gLhsl3lIBqeAfOJIl1qEvRf2uq3BiKxmh6Fh5pfp2ieyek7Kg== + dependencies: + "@ethersproject/abi" "5.8.0" + "@ethersproject/abstract-provider" "5.8.0" + "@ethersproject/abstract-signer" "5.8.0" + "@ethersproject/address" "5.8.0" + "@ethersproject/base64" "5.8.0" + "@ethersproject/basex" "5.8.0" + "@ethersproject/bignumber" "5.8.0" + "@ethersproject/bytes" "5.8.0" + "@ethersproject/constants" "5.8.0" + "@ethersproject/contracts" "5.8.0" + "@ethersproject/hash" "5.8.0" + "@ethersproject/hdnode" "5.8.0" + "@ethersproject/json-wallets" "5.8.0" + "@ethersproject/keccak256" "5.8.0" + "@ethersproject/logger" "5.8.0" + "@ethersproject/networks" "5.8.0" + "@ethersproject/pbkdf2" "5.8.0" + "@ethersproject/properties" "5.8.0" + "@ethersproject/providers" "5.8.0" + "@ethersproject/random" "5.8.0" + "@ethersproject/rlp" "5.8.0" + "@ethersproject/sha2" "5.8.0" + "@ethersproject/signing-key" "5.8.0" + "@ethersproject/solidity" "5.8.0" + "@ethersproject/strings" "5.8.0" + "@ethersproject/transactions" "5.8.0" + "@ethersproject/units" "5.8.0" + "@ethersproject/wallet" "5.8.0" + "@ethersproject/web" "5.8.0" + "@ethersproject/wordlists" "5.8.0" + event-target-shim@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" @@ -3119,6 +3640,14 @@ has-symbols@^1.1.0: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== +hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + hasown@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" @@ -3126,6 +3655,15 @@ hasown@^2.0.2: dependencies: function-bind "^1.1.2" +hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + homedir-polyfill@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" @@ -3818,6 +4356,11 @@ jest@^29.3.1: import-local "^3.0.2" jest-cli "^29.7.0" +js-sha3@0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" + integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== + js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -4097,6 +4640,16 @@ min-indent@^1.0.0: resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== + minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -4171,6 +4724,11 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== +node-addon-api@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-5.1.0.tgz#49da1ca055e109a23d537e9de43c09cca21eb762" + integrity sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA== + node-fetch@^2.6.1, node-fetch@^2.7.0: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" @@ -4178,6 +4736,11 @@ node-fetch@^2.6.1, node-fetch@^2.7.0: dependencies: whatwg-url "^5.0.0" +node-gyp-build@^4.2.0: + version "4.8.4" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.4.tgz#8a70ee85464ae52327772a90d66c6077a900cfc8" + integrity sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ== + node-inspect-extracted@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/node-inspect-extracted/-/node-inspect-extracted-2.0.2.tgz#e5500e79f6bc03517175881c991f3bfaea67115a" @@ -4686,6 +5249,20 @@ sandwich-stream@^2.0.2: resolved "https://registry.yarnpkg.com/sandwich-stream/-/sandwich-stream-2.0.2.tgz#6d1feb6cf7e9fe9fadb41513459a72c2e84000fa" integrity sha512-jLYV0DORrzY3xaz/S9ydJL6Iz7essZeAfnAavsJ+zsJGZ1MOnsS52yRjU3uF3pJa/lla7+wisp//fxOwOH8SKQ== +scrypt-js@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" + integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== + +secp256k1@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-5.0.1.tgz#dc2c86187d48ff2da756f0f7e96417ee03c414b1" + integrity sha512-lDFs9AAIaWP9UCdtWrotXWWF9t8PWgQDcxqgAnpM9rMqxb3Oaq2J0thzPVSxBwdJgyQtkU/sYtFtbM1RSt/iYA== + dependencies: + elliptic "^6.5.7" + node-addon-api "^5.0.0" + node-gyp-build "^4.2.0" + semver-compare@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" @@ -5268,6 +5845,11 @@ write-file-atomic@^4.0.2: imurmurhash "^0.1.4" signal-exit "^3.0.7" +ws@8.18.0: + version "8.18.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" + integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== + xdg-basedir@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-5.1.0.tgz#1efba19425e73be1bc6f2a6ceb52a3d2c884c0c9"