Working With AssetId´s
Asset ids delineates an asset at an index in a market pool.
Types of Asset ids
AssetId
The AssetId type is a union type of the following types of assets.
type AssetId =
| CategoricalAssetId
| ScalarAssetId
| ZtgAssetId
| PoolShareAssetId;
Categorical Assets
The categorical asset id specifies which market it belongs to by the market id and the index in the outcome assets vector it is.
type CategoricalAssetId = {
CategoricalOutcome: [MarketId, number];
};
Scalar Assets
The scalar asset id specifies which market it belongs to by the market id and if its the long or short asset.
type ScalarAssetId = {
ScalarOutcome: [MarketId, "Short" | "Long"];
};
Ztg Assets (base asset)
The ZTG asset is currently the only base asset a market/pool can have.
This will be expanded in the near future to be able to be other base assets like stable coins.
type ZtgAssetId = {
Ztg: null;
};
Pool Share Assets
Pool shares are earned/minted when you provide liquidity to a market. The number represents the pool id the pool-shares belong to.
type PoolShareAssetId = {
PoolShare: number;
};
Parsing Asset Ids
The sdk exposes the following function that helps to normalize/parse a AssetId
from a string
, object
or ZeitgeistPrimitivesAsset
declare const parseAssetId = (
raw: string | object | ZeitgeistPrimitivesAsset,
): E.IEither<SyntaxError, AssetId>
All of the following examples will parse to the same AssetId
const assetId: AssetId = parseAssetId({ CategoricalOutcome: [1, 2] }).unwrap();
const assetId: AssetId = parseAssetId('{"CategoricalOutcome":[1,2]}').unwrap();
const assetId: AssetId = parseAssetId(
api.createType("ZeitgeistPrimitivesAsset", { categoricalOutcome: [1, 2] })
).unwrap();
Note that the unwrap
method in Either
values will throw an error if it
cannot parse the value as expected and should be handled.
Typeguards for Asset Ids
The sdk exposes certain type guards that can type check asset ids at runtime.
import {
AssetId,
getIndexOf,
IOCategoricalAssetId,
IOMarketOutcomeAssetId,
IOScalarAssetId,
parseAssetId,
} from "@zeitgeistpm/sdk";
const categoricalAssetId: AssetId = parseAssetId({
CategoricalOutcome: [1, 2],
}).unwrap();
const scalarAssetId: AssetId = parseAssetId({
ScalarOutcome: [1, "Short"],
}).unwrap();
/**
* We can narrow all the way down to a concrete type
*/
if (IOCategoricalAssetId.is(categoricalAssetId)) {
console.log(categoricalAssetId.CategoricalOutcome);
}
if (IOScalarAssetId.is(scalarAssetId)) {
console.log(scalarAssetId.ScalarOutcome);
}
/**
* Or down to the union type of possible outcome asset id types
*/
if (IOMarketOutcomeAssetId.is(categoricalAssetId)) {
/**
* Getting the index of asset ids is only applicable to Market Outcome Asset ids
*/
console.log(getIndexOf(categoricalAssetId));
}
Corelating AssetId and Outcome Metadata
The asset ids that represent market outcomes IE:
MarketOutcomeAssetId
which is either a
ScalarAssetId
or a
CategoricalAssetId
stores the index of the asset that is corelated to the market.categories
.
declare const market: Market<FullContext>;
declare const assetId: MarketOutcomeAssetId;
const { name, ticker, color } = market.categories![getIndexOf(assetId)]!;
Example
In this example we are using parseAssetId
to normalize the asset ids of a
market so that we can correlate them with the category metadata(name of outcome)
and also to fetch the market pools balance of those assets.
import { MarketStatus } from "@zeitgeistpm/indexer";
import {
create,
FullContext,
getIndexOf,
IOMarketOutcomeAssetId,
mainnet,
MarketOutcomeAssetId,
parseAssetId,
Sdk,
ZTG,
} from "@zeitgeistpm/sdk";
import { isNotNull } from "@zeitgeistpm/utility/dist/null";
const sdk: Sdk<FullContext> = await create(mainnet());
/**
* We fetch all active sports markets.
*/
const activeSportsMarkets = await sdk.model.markets.list({
limit: 10,
where: {
tags_containsAll: ["Sports"],
status_eq: MarketStatus.Active,
},
});
for (const market of activeSportsMarkets) {
/**
* We fetch the pool for each market.
*/
const pool = await sdk.model.swaps
.getPool({ marketId: market.marketId })
.then((pool) => pool.unwrap()!);
/**
* Massage the outcome assets so that they are all valid outcome assets.
* We dont care about the base asset or pool shares here.
*/
const assetIds: MarketOutcomeAssetId[] = market.outcomeAssets
.filter(isNotNull)
.map((raw) => parseAssetId(raw).unwrap())
.filter(IOMarketOutcomeAssetId.is.bind(IOMarketOutcomeAssetId));
/**
* We fetch the balances for each outcome asset.
* We also use the getIndexOf helper to corealte the asset id to the market category.
*/
const assetsData = await Promise.all(
assetIds.map(async (assetId) => {
const balance = await pool.getAssetBalance(assetId);
const category = market.categories?.[getIndexOf(assetId)];
return { balance, category };
})
);
/**
* Print the balances for each outcome asset of the market.
*/
console.log(`${market.marketId}: ${market.question}`);
for (const { category, balance } of assetsData) {
console.log(` ${category?.name}: Volume: ${balance.div(ZTG).toFixed(2)}`);
}
console.log("--------------------------------");
}
Result
At the time of writing this documentation the results of this script is the following:
85: Which team will be the champion of the Kings League tournament organized by Gerard Pique and Ibai Llanos?
Ultimate Mostoles: 75.86 Mosto
1K FC: 75.86 1K FC
Saiyans FC: 107.13 Saiyans
Kunisports: 107.13 Kuni
El Barrio: 107.13 Barrio
Los Troncos FC: 107.13 Troncos
Porcinos FC: 107.13 Porcino
Rayo de Barcelona: 107.13 Rayo
Jijantes FC: 107.13 Jija
PIO FC: 107.13 PIO
XBUYER TEAM: 107.13 Xbuy
Aniquiladores FC: 107.13 Aniq
--------------------------------
21: Who will win the UEFA Champions League Cup in 2022/ 23?
Liverpool FC: 6877.49 LIV
FC Bayern München: 3896.01 BAY
Real Madrid CF: 3085.29 MAD
Manchester City F.C: 3058.22 MCI
Chelsea FC: 6917.83 CHL
Paris Saint-Germain: 2835.22 PSG
F.C. Barcelona: 9248.22 BAR
A.C. Milan: 9463.22 ACM
SSC Napoli: 6981.16 NAP
OTHER: 6463.22 OTH
--------------------------------