> 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/kpk-fund-integration/monitor-a-request.md).

# Monitor a request

Track a request's lifecycle through events or a synchronous getRequest call.

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="https://1699303810-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUsQM4bzcmOPSgkWddkeN%2Fuploads%2FACe50o0vuJFod4dNBhKo%2Fkpk_funds_monitor_request.png?alt=media&amp;token=a528d64e-84e0-4abf-96c1-d94ea4e13d74" 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

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

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
