Geode Document Hub
Search
⌃K

Communicating with Portal

Portal is The Main Gateway to Trustless Staking

Learn more about Portal here, if you want:

Portal utilizes a Modular Architecture build on top of an Isolated Storage.

This is good for us, because we can add any functionality without minding the backward compatibility. It is good for the users because no one can touch their instance of the contract storage.
However, this means, sadly, things are not that direct...
Learn more about it here, if you want:

TYPE

We have already learned a bit about IDs while initiating our Operator.
There are many TYPEs that are supported by Portal. Modules like Withdrawal Contract, Liquidity Pools, Interfaces...
However, as Node Operators, we are only interested in two of them: Operator and Pool.

Representation of an Operator' storage space:

const OPERATOR = {
"CONTROLLER": <address>,
"NAME": <bytes>,
"TYPE": 4 <uint>,
"initiated": <uint>,
"maintainer": <address>,
"totalProposedValidators": <uint>,
"totalActiveValidators": <uint>,
"feeSwitch": <uint>,
"priorFee": <uint>,
"fee": <uint>,
"periodSwitch": <uint>,
"priorPeriod": <uint>,
"validatorPeriod": <uint>,
"wallet": <uint>,
"released": <uint>
};

Representation of a Pool's storage space:

const POOL= {
"CONTROLLER": <address>,
"NAME": <bytes>,
"TYPE": 5 <uint>,
"initiated": <uint>,
"maintainer": <address>,
"surplus": <uint>,
"secured": <uint>,
"allowance": {<OPERATOR>: <uint>},
"proposedValidators": {<OPERATOR>: <uint>},
"activeValidators": {<OPERATOR>: <uint>},
"interfaces": [<address>],
"private": <uint>, // 1 = true
"whitelist": <address>,
"withdrawalCredential": <bytes>,
"withdrawalContract": <address>,
"liquidityPool": <address>,
"liquidityPoolVersion": <uint>,
"feeSwitch": <uint>,
"priorFee": <uint>,
"fee": <uint>,
"wallet": <uint>,
"validators": [<bytes>]
};
surplus, allowance and withdrawalContract are super important for us!

Reading variables from Portal

First, some helpers:

const getBytes32 = (key) => {
return ethers.utils.formatBytes32String(key);
};
​
const getBytes = (key) => {
return Web3.utils.toHex(key);
};

Reading UINT variable:

await PORTAL.readUintForId(
id,
getBytes32("surplus")
);

Reading ADDRESS variable:

await PORTAL.readAddressForId(
id,
getBytes32("CONTROLLER")
);

Reading BYTES variable:

await PORTAL.readBytesForId(
id,
getBytes32("withdrawalCredential")
);

Reading Arrays from Portal

Reading UINT array:

await PORTAL.readUintArrayForId(
id,
getBytes32("something"),
index
);

Reading ADDRESS array:

await PORTAL.readBytesArrayForId(
id,
getBytes32("interfaces"),
index
);

Reading BYTES array:

await PORTAL.readAddressArrayForId(
id,
getBytes32("validators"),
index
);

Reading Relational Data from Portal

Reading UINT data:

await PORTAL.readUintForId(
poolId,
await PORTAL.getKey(operatorId, getBytes32("allowance"))
);

Reading ADDRESS data:

await PORTAL.readAddressForId(
poolId,
await PORTAL.getKey(operatorId, getBytes32("something"))
);

Reading BYTES data:

await PORTAL.readBytesForId(
poolId,
await PORTAL.getKey(operatorId, getBytes32("something"))
);

Thats it!