> 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/subscription-request.md).

# Subscription request

Approve the asset and create a subscription request on the shares contract.

Subscribing is a two-step flow, just like a standard deposit:

1. **Approve** the shares contract to spend your subscription asset, a standard ERC-20 `approve` call.
2. **Create the request** with `requestSubscription` on the shares contract:

```solidity
function requestSubscription(
    uint256 assetsIn,         // amount of the asset to deposit
    uint256 minSharesOut,     // slippage protection (see Calculate share price)
    address subscriptionAsset,// must be approved for deposits
    address receiver          // who receives the minted shares
) external returns (uint256 requestId);
```

{% hint style="warning" %}
`minSharesOut` is **slippage protection**. The actual shares are computed by the operator from the share price at settlement time; that result must be `≥ minSharesOut` or the request fails the slippage check. Derive it from the fund's current share price, see [Calculate share price](/funds/kpk-fund-integration/calculate-share-price.md), then convert with `assetsToShares` and apply a tolerance. The 0.5% used below is only an example; set it to how much slippage you are willing to accept.
{% endhint %}

## Example

Subscribing **1,000 USDC** (6 decimals) into a fund. We read the fund's current share price (see [Calculate share price](/funds/kpk-fund-integration/calculate-share-price.md)), convert it to expected shares with `assetsToShares`, and apply a 0.5% example tolerance to get `minSharesOut`.

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

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

const SHARES = "0x...";  // fund shares contract — see the fund's Policies and addresses
const USDC   = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";

const sharesAbi = parseAbi([
  "function assetsToShares(uint256 assetAmount, uint256 sharesPrice, address subscriptionAsset) view returns (uint256)",
  "function requestSubscription(uint256 assetsIn, uint256 minSharesOut, address subscriptionAsset, address receiver) returns (uint256)",
]);
const erc20Abi = parseAbi(["function approve(address spender, uint256 amount) returns (bool)"]);

const account = privateKeyToAccount("0x...");
const pub = createPublicClient({ chain: mainnet, transport: http() });
const wallet = createWalletClient({ account, chain: mainnet, transport: http() });

const assetsIn = parseUnits("1000", 6); // 1,000 USDC

// 1. Current share price in 8-decimal USD — compute it onchain per Calculate share price.
const sharePrice = await getSharePrice(pub); // bigint, 8 decimals — see Calculate share price

// 2. Convert to expected shares at that price, then apply your tolerance.
const expectedShares = await pub.readContract({
  address: SHARES, abi: sharesAbi, functionName: "assetsToShares",
  args: [assetsIn, sharePrice, USDC],
});
const minSharesOut = (expectedShares * 9950n) / 10000n; // 0.5% is only an example — set your own tolerance

// 3. Approve, then request.
await wallet.writeContract({ address: USDC, abi: erc20Abi, functionName: "approve", args: [SHARES, assetsIn] });
const hash = await wallet.writeContract({
  address: SHARES, abi: sharesAbi, functionName: "requestSubscription",
  args: [assetsIn, minSharesOut, USDC, account.address],
});
```

{% endtab %}

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

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

const SHARES = "0x...";  // fund shares contract — see the fund's Policies and addresses
const USDC   = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";

const sharesAbi = [
  "function assetsToShares(uint256 assetAmount, uint256 sharesPrice, address subscriptionAsset) view returns (uint256)",
  "function requestSubscription(uint256 assetsIn, uint256 minSharesOut, address subscriptionAsset, address receiver) returns (uint256)",
];
const erc20Abi = ["function approve(address spender, uint256 amount) returns (bool)"];

const provider = new ethers.JsonRpcProvider("https://eth.llamarpc.com");
const signer = new ethers.Wallet("0x...", provider);
const shares = new ethers.Contract(SHARES, sharesAbi, signer);
const usdc = new ethers.Contract(USDC, erc20Abi, signer);

const assetsIn = ethers.parseUnits("1000", 6); // 1,000 USDC

const sharePrice = await getSharePrice(provider); // 8-dec USD — see Calculate share price
const expectedShares = await shares.assetsToShares(assetsIn, sharePrice, USDC);
const minSharesOut = (expectedShares * 9950n) / 10000n; // 0.5% is only an example — set your own tolerance

await (await usdc.approve(SHARES, assetsIn)).wait();
const tx = await shares.requestSubscription(assetsIn, minSharesOut, USDC, await signer.getAddress());
await tx.wait();
```

{% endtab %}

{% tab title="Python" %}

```python
from web3 import Web3

SHARES = "0x..."  # fund shares contract — see the fund's Policies and addresses
USDC   = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"

shares_abi = [
    {"name": "assetsToShares", "type": "function", "stateMutability": "view",
     "inputs": [{"name": "assetAmount", "type": "uint256"}, {"name": "sharesPrice", "type": "uint256"},
                {"name": "subscriptionAsset", "type": "address"}],
     "outputs": [{"type": "uint256"}]},
    {"name": "requestSubscription", "type": "function", "stateMutability": "nonpayable",
     "inputs": [{"name": "assetsIn", "type": "uint256"}, {"name": "minSharesOut", "type": "uint256"},
                {"name": "subscriptionAsset", "type": "address"}, {"name": "receiver", "type": "address"}],
     "outputs": [{"type": "uint256"}]},
]
erc20_abi = [{"name": "approve", "type": "function", "stateMutability": "nonpayable",
              "inputs": [{"name": "spender", "type": "address"}, {"name": "amount", "type": "uint256"}],
              "outputs": [{"type": "bool"}]}]

w3 = Web3(Web3.HTTPProvider("https://eth.llamarpc.com"))
acct = w3.eth.account.from_key("0x...")
shares = w3.eth.contract(address=SHARES, abi=shares_abi)
usdc = w3.eth.contract(address=USDC, abi=erc20_abi)

assets_in = 1000 * 10**6  # 1,000 USDC

share_price = get_share_price(w3)  # 8-decimal USD — see Calculate share price
expected = shares.functions.assetsToShares(assets_in, share_price, USDC).call()
min_shares_out = expected * 9950 // 10000  # 0.5% is only an example — set your own tolerance

# Build, sign, and send approve + requestSubscription (nonce/gas handling omitted for brevity).
approve = usdc.functions.approve(SHARES, assets_in).build_transaction({"from": acct.address})
# ... sign & send approve ...
req = shares.functions.requestSubscription(
    assets_in, min_shares_out, USDC, acct.address
).build_transaction({"from": acct.address})
# ... sign & send req ...
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}

## Events

Creating a subscription request emits a `SubscriptionRequest` event containing the `requestId`, `cancelableFrom`, and `expiryAt`. Track it as described in [Monitor a request](/funds/kpk-fund-integration/monitor-a-request.md).
{% endhint %}

<figure><picture><source srcset="/files/fMRNxtuXyn7U776YiNmf" media="(prefers-color-scheme: dark)"><img src="https://1699303810-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUsQM4bzcmOPSgkWddkeN%2Fuploads%2Fpf8Dr49WWEofgFOikcq8%2Fkpk_funds_subs_request.png?alt=media&amp;token=9ba294ae-8332-45c7-9589-7e1e856cd036" alt=""></picture><figcaption><p>Subscription flow example, with USDC as subscription token.</p></figcaption></figure>


---

# 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/subscription-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.
