> For the complete documentation index, see [llms.txt](https://docs.kpk.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kpk.io/funds/integration/monitor-a-request.md).

# Monitor a request

Once a subscription or redemption request is in place, its whole lifecycle can be monitored either by reading the events emitted by the shares contract, or by synchronously querying it.

<figure><picture><source srcset="/files/jACl5BEQ9cxtdUuGLIbk" media="(prefers-color-scheme: dark)"><img src="/files/iPpU0bvivKZ0iKaSrwDw" alt=""></picture><figcaption></figcaption></figure>

## Asynchronous: events

The key events for tracking a request's lifecycle:

#### Subscription

<table><thead><tr><th width="256.34765625">Event</th><th>Description</th></tr></thead><tbody><tr><td><strong>SubscriptionRequest</strong></td><td>Subscription request created</td></tr><tr><td><strong>SubscriptionApproval</strong></td><td>Subscription request approved</td></tr><tr><td><strong>SubscriptionCancellation</strong></td><td>Subscription request cancelled by the user or receiver</td></tr><tr><td><strong>SubscriptionDenial</strong></td><td>Subscription request denied by a fund operator</td></tr><tr><td><strong>SubscriptionRequestExpired</strong></td><td>Subscription request expired without action</td></tr></tbody></table>

#### Redemption

<table><thead><tr><th width="256.49609375">Event</th><th>Description</th></tr></thead><tbody><tr><td><strong>RedemptionRequest</strong></td><td>Redemption request created</td></tr><tr><td><strong>RedemptionApproval</strong></td><td>Redemption request approved</td></tr><tr><td><strong>RedemptionCancellation</strong></td><td>Redemption request cancelled by the user or receiver</td></tr><tr><td><strong>RedemptionDenial</strong></td><td>Redemption request denied by a fund operator</td></tr><tr><td><strong>RedemptionRequestExpired</strong></td><td>Redemption request expired without action</td></tr></tbody></table>

The `requestId` returned when you create a request is the key to filter on. For example, to capture the id from your own subscription:

{% tabs %}
{% tab title="viem" %}

```typescript
import { createPublicClient, http, parseAbiItem } from "viem";
import { mainnet } from "viem/chains";

const SHARES = "0x...";
const client = createPublicClient({ chain: mainnet, transport: http() });

const logs = await client.getLogs({
  address: SHARES,
  event: parseAbiItem(
    "event SubscriptionRequest(address indexed investor, uint256 requestId, address indexed receiver, address indexed subscriptionAsset, uint256 assetsAmount, uint256 sharesAmount, uint64 timestamp, uint64 cancelableFrom, uint64 expiryAt)"
  ),
  args: { investor: "0xYourAddress" },
  fromBlock: "earliest",
});
for (const log of logs) console.log("requestId:", log.args.requestId);
```

{% endtab %}

{% tab title="ethers.js" %}

```typescript
import { ethers } from "ethers";

const SHARES = "0x...";
const abi = [
  "event SubscriptionRequest(address indexed investor, uint256 requestId, address indexed receiver, address indexed subscriptionAsset, uint256 assetsAmount, uint256 sharesAmount, uint64 timestamp, uint64 cancelableFrom, uint64 expiryAt)",
];

const provider = new ethers.JsonRpcProvider("https://eth.llamarpc.com");
const shares = new ethers.Contract(SHARES, abi, provider);

const filter = shares.filters.SubscriptionRequest("0xYourAddress");
const events = await shares.queryFilter(filter);
for (const e of events) console.log("requestId:", e.args.requestId.toString());
```

{% endtab %}

{% tab title="Python" %}

```python
from web3 import Web3

SHARES = "0x..."
abi = [{
    "name": "SubscriptionRequest", "type": "event", "anonymous": False,
    "inputs": [
        {"name": "investor", "type": "address", "indexed": True},
        {"name": "requestId", "type": "uint256", "indexed": False},
        {"name": "receiver", "type": "address", "indexed": True},
        {"name": "subscriptionAsset", "type": "address", "indexed": True},
        {"name": "assetsAmount", "type": "uint256", "indexed": False},
        {"name": "sharesAmount", "type": "uint256", "indexed": False},
        {"name": "timestamp", "type": "uint64", "indexed": False},
        {"name": "cancelableFrom", "type": "uint64", "indexed": False},
        {"name": "expiryAt", "type": "uint64", "indexed": False},
    ],
}]

w3 = Web3(Web3.HTTPProvider("https://eth.llamarpc.com"))
shares = w3.eth.contract(address=SHARES, abi=abi)
logs = shares.events.SubscriptionRequest().get_logs(
    from_block=0, argument_filters={"investor": "0xYourAddress"})
for log in logs:
    print("requestId:", log["args"]["requestId"])
```

{% endtab %}
{% endtabs %}

## Synchronous: `getRequest`

To query a request's current state directly, pass the `requestId`:

```solidity
function getRequest(uint256 id) external view returns (UserRequest memory);

struct UserRequest {
    RequestType   requestType;   // 0 = SUBSCRIPTION, 1 = REDEMPTION
    RequestStatus requestStatus; // 0 = PENDING, 1 = PROCESSED, 2 = REJECTED, 3 = CANCELLED
    address asset;
    uint256 assetAmount;         // subscription: deposited assets; redemption: minAssetsOut
    uint256 sharesAmount;        // subscription: minSharesOut; redemption: shares redeemed
    address investor;
    address receiver;
    uint64  timestamp;
    uint64  expiryAt;
}
```

{% tabs %}
{% tab title="viem" %}

```typescript
import { createPublicClient, http, parseAbi } from "viem";
import { mainnet } from "viem/chains";

const SHARES = "0x...";
const abi = parseAbi([
  "function getRequest(uint256 id) view returns ((uint8 requestType, uint8 requestStatus, address asset, uint256 assetAmount, uint256 sharesAmount, address investor, address receiver, uint64 timestamp, uint64 expiryAt))",
]);

const client = createPublicClient({ chain: mainnet, transport: http() });
const req = await client.readContract({ address: SHARES, abi, functionName: "getRequest", args: [42n] });
// req.requestStatus === 0 => still PENDING
```

{% endtab %}

{% tab title="ethers.js" %}

```typescript
import { ethers } from "ethers";

const SHARES = "0x...";
const abi = [
  "function getRequest(uint256 id) view returns (tuple(uint8 requestType, uint8 requestStatus, address asset, uint256 assetAmount, uint256 sharesAmount, address investor, address receiver, uint64 timestamp, uint64 expiryAt))",
];

const provider = new ethers.JsonRpcProvider("https://eth.llamarpc.com");
const shares = new ethers.Contract(SHARES, abi, provider);
const req = await shares.getRequest(42n);
console.log("status:", req.requestStatus); // 0 = PENDING
```

{% endtab %}

{% tab title="Python" %}

```python
from web3 import Web3

SHARES = "0x..."
abi = [{
    "name": "getRequest", "type": "function", "stateMutability": "view",
    "inputs": [{"name": "id", "type": "uint256"}],
    "outputs": [{"type": "tuple", "components": [
        {"name": "requestType", "type": "uint8"},
        {"name": "requestStatus", "type": "uint8"},
        {"name": "asset", "type": "address"},
        {"name": "assetAmount", "type": "uint256"},
        {"name": "sharesAmount", "type": "uint256"},
        {"name": "investor", "type": "address"},
        {"name": "receiver", "type": "address"},
        {"name": "timestamp", "type": "uint64"},
        {"name": "expiryAt", "type": "uint64"},
    ]}],
}]

w3 = Web3(Web3.HTTPProvider("https://eth.llamarpc.com"))
shares = w3.eth.contract(address=SHARES, abi=abi)
req = shares.functions.getRequest(42).call()
print("status:", req[1])  # 0 = PENDING
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.kpk.io/funds/integration/monitor-a-request.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
