Vault Liquidity
Register Vault
Admit a vault as a just-in-time liquidity source, or remove it
POST
/
lending-external-securities-v2
/
api
/
markets
/
{marketId}
/
vault-liquidity
/
{action}
curl -X POST "https://api.trusset.org/lending-external-securities-v2/api/markets/{marketId}/vault-liquidity/register" \
-H "X-API-Key: trusset_your_key_here" \
-H "Content-Type: application/json" \
-d '{"vaultAddress": "0x4d0cfe39a3431b145d1a1393d901a36d459a1b13"}'
const base = `https://api.trusset.org/lending-external-securities-v2/api/markets/${marketId}`;
const headers = { 'X-API-Key': 'trusset_your_key_here', 'Content-Type': 'application/json' };
const res = await fetch(`${base}/vault-liquidity/register`, {
method: 'POST',
headers,
body: JSON.stringify({ vaultAddress })
});
const { data } = await res.json();
for (const warning of data.warnings ?? []) {
console.warn(warning.message);
}
const tx = await adminWallet.sendTransaction({
...data.transaction,
value: data.value,
chainId: data.chainId
});
await tx.wait();
const check = await fetch(`${base}/vault-liquidity`, { headers });
const { data: status } = await check.json();
const registered = status.registeredVaults.some(
(v: { vaultAddress: string }) => v.vaultAddress === vaultAddress.toLowerCase()
);
{
"success": true,
"data": {
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x70a0e25c7b768b87e658348b3b577678a173e038",
"data": "0x..."
},
"to": "0x70a0e25c7b768b87e658348b3b577678a173e038",
"data": "0x...",
"functionName": "registerVault",
"requiredRole": "DEFAULT_ADMIN_ROLE",
"description": "Register the vault for just-in-time draws - the vault operator must also set a per-market draw cap before anything can be drawn; registering is the admin's admission of the vault as a liquidity provider, and the vault's own register examines its investors (requires DEFAULT_ADMIN_ROLE)",
"requiredSigner": null,
"heldByThisInstance": true,
"signerAddress": "0x1234f9a07c6b53d81e2a4f70c9b385d6014a7e52",
"note": null,
"chainId": 11155111,
"value": "0"
}
}
{
"success": true,
"data": {
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x70a0e25c7b768b87e658348b3b577678a173e038",
"data": "0x..."
},
"to": "0x70a0e25c7b768b87e658348b3b577678a173e038",
"data": "0x...",
"functionName": "deregisterVault",
"requiredRole": "DEFAULT_ADMIN_ROLE",
"description": "Deregister the vault: no further draws; the LP position it already holds is untouched (requires DEFAULT_ADMIN_ROLE)",
"requiredSigner": null,
"heldByThisInstance": true,
"signerAddress": "0x1234f9a07c6b53d81e2a4f70c9b385d6014a7e52",
"note": null,
"chainId": 11155111,
"value": "0"
}
}
{
"success": false,
"error": {
"code": "NOT_A_VAULT",
"message": "The address is not a vault from the v2 vault factory."
}
}
{
"success": false,
"error": {
"code": "MARKET_PENDING_CURATOR",
"message": "This market has no lender of record yet, so changing its registered vaults is not possible. A nominated candidate must take the role before the market has an admin that can sign this."
}
}
Builds the transaction that adds a vault to the market’s draw list (
registerVault) or removes it (deregisterVault). The market admin, the wallet holding DEFAULT_ADMIN_ROLE, signs it.
Registering is the market’s admission of the vault as a liquidity provider. A current market takes deposits directly from only two callers, the operator wallet and its registered vaults. A registered vault is therefore how outside money reaches the pool: investors deposit into the vault, and the vault’s own gate examines them.
A registered vault funds nothing on its own. The switch must be on through Set Vault Liquidity, and the vault operator must set a draw cap for this market in the Issuer Portal. Get Vault Liquidity shows every leg.
Deregistering stops further draws and withdraws the vault’s admission as a provider. The position the vault already holds is untouched. It is ordinary pool liquidity and leaves the way any provider’s does.
Path Parameters
string
required
string
required
register to admit the vault, deregister to remove it. No other value is accepted.Body Parameters
string
required
The vault contract,
0x followed by 40 hex characters. A mixed-case address must pass its EIP-55 checksum, and an all-lowercase one always does. The zero address is refused.What is checked before the transaction is built
Registration runs these checks in order. Deregistration runs none beyond the address format.- The address must be a vault created by the v2 vault factory, otherwise the call is refused with
NOT_A_VAULT. When the factory cannot be read, this check is skipped. - The vault must settle in the market’s borrow asset, otherwise the call is refused with
ASSET_MISMATCH. When either asset cannot be read, the call is refused withMARKET_STATE_UNAVAILABLE. - The market’s implementation must be readable, otherwise the call is refused with
MARKET_STATE_UNAVAILABLE. - On a market still running the earlier single-register implementation, the vault must be verified on the market’s identity registry, otherwise the call is refused with
IDENTITY_NOT_VERIFIED, or withIDENTITY_GATE_RETIREDwhen that registry is the previous Trusset ID Register. A vault whose admission to that registry is waiting for removal is refused withELIGIBILITY_REMOVAL_PENDING. - On a
MARKET-priced market, the borrower register must qualify as a professional gate, otherwise the call is refused withPROFESSIONAL_BORROWER_GATE_REQUIRED. See Professional borrowers. - The vault’s investors must meet the market’s provider gate, read live from the vault and the market. See Provider gate.
Provider gate
A vault examines its depositors against its own register, when it has one, and against the provider register of every market it funds. On the current vault implementation, a vault without a register of its own adopts the provider register of the first market it funds or consents to draw for, and keeps it for good. A vault that no register examines takes no deposit at all. Registration therefore admits a vault only where those registers agree:- A vault with its own register can be registered on a market whose provider register is that same register, or that names none. Otherwise
PROVIDER_GATE_MISMATCH. - A vault without a register of its own needs the market to name a provider register, or
DEPOSITOR_GATE_REQUIRED. Unless the vault already funds this market, that register must be the one the vault adopted. A vault that has adopted none yet needs it to be the provider register of every market it funds or has consented to draw for. OtherwisePROVIDER_GATE_MISMATCH. - A vault without a register of its own that has adopted none, funds no market and still has shares in issue cannot be registered until its holders have redeemed, because nothing records which register they were examined against. It is refused with
PROVIDER_GATE_MISMATCH.
Draw order
The market draws on its registered vaults in the order they were registered. Deregistering a vault moves the most recently registered vault into the freed position, and a vault registered again joins at the end.Check the result
This API has no confirm call for registration. A well-formedtxHash in the body is ignored and the call answers with calldata again. A malformed one is refused with VALIDATION_ERROR. Once the transaction is mined, look for the vault in registeredVaults on Get Vault Liquidity.
Response Fields
object
Show child attributes
Show child attributes
string
SIGN_TRANSACTION.object
Unsigned transaction targeting the market contract, carrying
to and data only.string
The market contract, repeated at the top level.
string
The encoded call, repeated at the top level.
string
"0". On this call it sits on data itself, not inside transaction.integer
The chain your instance resolves to. On this call it sits on
data itself, not inside transaction, so pass it to the wallet explicitly.string
registerVault or deregisterVault.string
DEFAULT_ADMIN_ROLE, the market role the signing wallet must hold.string
What the transaction does, in words.
array
Present only on
register, and only when there is something to say. A warning never blocks the registration.Show child attributes
Show child attributes
string
VAULT_PREDATES_DISTRIBUTOR: the vault runs an implementation from before distributor attribution. The market books the distributor share of the vault’s interest for the vault, and the vault cannot collect it until its operator upgrades it. Nothing is lost meanwhile.string
The vault the warning is about, lowercased.
string
The position in full. Show it to the market admin before signing.
boolean
Whether a wallet registered on your instance holds
DEFAULT_ADMIN_ROLE on this market. null when the roles could not be read.string
The instance wallet that holds the role, when one does.
null otherwise.string
Always
null on this call. It names a wallet only on setters signed by the oracle or interest model owner.string
Set when no instance wallet holds the role, or when that could not be read.
null otherwise.A market still seeking a lender of record has no admin, so this call is refused with
MARKET_PENDING_CURATOR before any registration check runs. When heldByThisInstance is false, a transaction signed by an instance wallet reverts on-chain. Hand the calldata to the wallet the lender of record placed DEFAULT_ADMIN_ROLE with.curl -X POST "https://api.trusset.org/lending-external-securities-v2/api/markets/{marketId}/vault-liquidity/register" \
-H "X-API-Key: trusset_your_key_here" \
-H "Content-Type: application/json" \
-d '{"vaultAddress": "0x4d0cfe39a3431b145d1a1393d901a36d459a1b13"}'
const base = `https://api.trusset.org/lending-external-securities-v2/api/markets/${marketId}`;
const headers = { 'X-API-Key': 'trusset_your_key_here', 'Content-Type': 'application/json' };
const res = await fetch(`${base}/vault-liquidity/register`, {
method: 'POST',
headers,
body: JSON.stringify({ vaultAddress })
});
const { data } = await res.json();
for (const warning of data.warnings ?? []) {
console.warn(warning.message);
}
const tx = await adminWallet.sendTransaction({
...data.transaction,
value: data.value,
chainId: data.chainId
});
await tx.wait();
const check = await fetch(`${base}/vault-liquidity`, { headers });
const { data: status } = await check.json();
const registered = status.registeredVaults.some(
(v: { vaultAddress: string }) => v.vaultAddress === vaultAddress.toLowerCase()
);
{
"success": true,
"data": {
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x70a0e25c7b768b87e658348b3b577678a173e038",
"data": "0x..."
},
"to": "0x70a0e25c7b768b87e658348b3b577678a173e038",
"data": "0x...",
"functionName": "registerVault",
"requiredRole": "DEFAULT_ADMIN_ROLE",
"description": "Register the vault for just-in-time draws - the vault operator must also set a per-market draw cap before anything can be drawn; registering is the admin's admission of the vault as a liquidity provider, and the vault's own register examines its investors (requires DEFAULT_ADMIN_ROLE)",
"requiredSigner": null,
"heldByThisInstance": true,
"signerAddress": "0x1234f9a07c6b53d81e2a4f70c9b385d6014a7e52",
"note": null,
"chainId": 11155111,
"value": "0"
}
}
{
"success": true,
"data": {
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x70a0e25c7b768b87e658348b3b577678a173e038",
"data": "0x..."
},
"to": "0x70a0e25c7b768b87e658348b3b577678a173e038",
"data": "0x...",
"functionName": "deregisterVault",
"requiredRole": "DEFAULT_ADMIN_ROLE",
"description": "Deregister the vault: no further draws; the LP position it already holds is untouched (requires DEFAULT_ADMIN_ROLE)",
"requiredSigner": null,
"heldByThisInstance": true,
"signerAddress": "0x1234f9a07c6b53d81e2a4f70c9b385d6014a7e52",
"note": null,
"chainId": 11155111,
"value": "0"
}
}
{
"success": false,
"error": {
"code": "NOT_A_VAULT",
"message": "The address is not a vault from the v2 vault factory."
}
}
{
"success": false,
"error": {
"code": "MARKET_PENDING_CURATOR",
"message": "This market has no lender of record yet, so changing its registered vaults is not possible. A nominated candidate must take the role before the market has an admin that can sign this."
}
}
Error Codes
| Code | HTTP | Cause |
|---|---|---|
VALIDATION_ERROR | 400 | vaultAddress is missing or not 0x followed by 40 hex characters, or a txHash is present that is not 0x followed by 64 hex characters. error.details names the field |
INVALID_VAULT | 400 | vaultAddress is the zero address, or a mixed-case address that fails its EIP-55 checksum |
MISSING_MARKET_ID | 400 | marketId is longer than 100 characters |
NOT_A_VAULT | 400 | register only. The address is not a vault from the v2 vault factory |
ASSET_MISMATCH | 409 | register only. The vault settles in another asset than the market’s borrow asset, so it could never fund this market |
IDENTITY_NOT_VERIFIED | 400 | register only, on a market running the earlier single-register implementation. The vault is not verified on the market’s identity registry. details carries register, requiredProfile and accessList |
IDENTITY_GATE_RETIRED | 409 | register only, on the earlier single-register implementation. Returned instead of IDENTITY_NOT_VERIFIED when the market’s register is the previous Trusset ID Register, which takes no new identities. details carries register, gate (identity), retired: true and currentRegistry. The admin moves the market onto the current implementation with Upgrade Market, then installs the current register with Set Identity Gates |
MARKET_NOT_FOUND | 404 | No market with this ID on your instance |
MARKET_PENDING_CURATOR | 409 | The market has no lender of record yet, so no admin exists to sign. See Lender of record |
PROFESSIONAL_BORROWER_GATE_REQUIRED | 409 | register only. The market is MARKET-priced and its borrower register does not qualify as a professional gate. details.field is borrowerRegistry |
PROVIDER_GATE_MISMATCH | 409 | register only. The vault’s own register, the register it adopted, or the provider register of a market it already funds differs from this market’s provider register. Also a vault with no register of its own that funds no market while its shares are still held |
DEPOSITOR_GATE_REQUIRED | 409 | register only. The vault has no register of its own and the market names no provider register |
PROVIDER_GATE_RETIRED | 409 | register only. The vault has no register of its own, does not fund this market yet, and the market’s provider register is the previous Trusset ID Register. The vault would adopt that register for life and refuse every depositor verified since it moved. Move the market’s provider register to the current Trusset ID Register with Set Identity Gates first |
ELIGIBILITY_REMOVAL_PENDING | 409 | register only, on the earlier single-register implementation. The vault’s admission to the market’s identity registry is waiting for removal. details carries register and wallet |
MARKET_STATE_UNAVAILABLE | 503 | register only. The market’s implementation, its price source and borrower register, the vault’s register, the register it adopted, its share supply, this market’s provider register or the markets the vault funds could not be read. Retry shortly |
STATE_UNAVAILABLE | 503 | register only. The verification profiles behind a MARKET market’s borrower register, or the pending removals on the single-register implementation’s identity registry, could not be read. Retry shortly |
VAULTS_NOT_CONFIGURED | 503 | register only. Operator vaults are not configured on your instance’s network |
⌘I
curl -X POST "https://api.trusset.org/lending-external-securities-v2/api/markets/{marketId}/vault-liquidity/register" \
-H "X-API-Key: trusset_your_key_here" \
-H "Content-Type: application/json" \
-d '{"vaultAddress": "0x4d0cfe39a3431b145d1a1393d901a36d459a1b13"}'
const base = `https://api.trusset.org/lending-external-securities-v2/api/markets/${marketId}`;
const headers = { 'X-API-Key': 'trusset_your_key_here', 'Content-Type': 'application/json' };
const res = await fetch(`${base}/vault-liquidity/register`, {
method: 'POST',
headers,
body: JSON.stringify({ vaultAddress })
});
const { data } = await res.json();
for (const warning of data.warnings ?? []) {
console.warn(warning.message);
}
const tx = await adminWallet.sendTransaction({
...data.transaction,
value: data.value,
chainId: data.chainId
});
await tx.wait();
const check = await fetch(`${base}/vault-liquidity`, { headers });
const { data: status } = await check.json();
const registered = status.registeredVaults.some(
(v: { vaultAddress: string }) => v.vaultAddress === vaultAddress.toLowerCase()
);
{
"success": true,
"data": {
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x70a0e25c7b768b87e658348b3b577678a173e038",
"data": "0x..."
},
"to": "0x70a0e25c7b768b87e658348b3b577678a173e038",
"data": "0x...",
"functionName": "registerVault",
"requiredRole": "DEFAULT_ADMIN_ROLE",
"description": "Register the vault for just-in-time draws - the vault operator must also set a per-market draw cap before anything can be drawn; registering is the admin's admission of the vault as a liquidity provider, and the vault's own register examines its investors (requires DEFAULT_ADMIN_ROLE)",
"requiredSigner": null,
"heldByThisInstance": true,
"signerAddress": "0x1234f9a07c6b53d81e2a4f70c9b385d6014a7e52",
"note": null,
"chainId": 11155111,
"value": "0"
}
}
{
"success": true,
"data": {
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x70a0e25c7b768b87e658348b3b577678a173e038",
"data": "0x..."
},
"to": "0x70a0e25c7b768b87e658348b3b577678a173e038",
"data": "0x...",
"functionName": "deregisterVault",
"requiredRole": "DEFAULT_ADMIN_ROLE",
"description": "Deregister the vault: no further draws; the LP position it already holds is untouched (requires DEFAULT_ADMIN_ROLE)",
"requiredSigner": null,
"heldByThisInstance": true,
"signerAddress": "0x1234f9a07c6b53d81e2a4f70c9b385d6014a7e52",
"note": null,
"chainId": 11155111,
"value": "0"
}
}
{
"success": false,
"error": {
"code": "NOT_A_VAULT",
"message": "The address is not a vault from the v2 vault factory."
}
}
{
"success": false,
"error": {
"code": "MARKET_PENDING_CURATOR",
"message": "This market has no lender of record yet, so changing its registered vaults is not possible. A nominated candidate must take the role before the market has an admin that can sign this."
}
}
