@nickthelegend69/fund402 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -5
- package/dist/casper.d.ts +24 -0
- package/dist/casper.js +60 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -151,17 +151,30 @@ for Tier-3).
|
|
|
151
151
|
`verifyPoolSettlement` is resilient to indexer lag — it polls a bounded window while
|
|
152
152
|
the deploy is still propagating, and fails fast on an executed on-chain failure.
|
|
153
153
|
|
|
154
|
+
## Yield-bearing pool
|
|
155
|
+
|
|
156
|
+
The vault charges a **5% JIT credit fee** on every borrow. On repayment the agent pays
|
|
157
|
+
back principal **+ fee**, and the fee accrues to the pool's value — so **LPs earn yield**:
|
|
158
|
+
deposits are minted as shares, and a share redeems for more than it cost as fees pile up.
|
|
159
|
+
Agents can settle their newest loan with **`repayLatestOnChain`** (no loan id needed),
|
|
160
|
+
which makes auto-repay-from-earnings trivial.
|
|
161
|
+
|
|
162
|
+
**Proven live (casper-test):** an LP deposited `2_000_000`, an agent borrowed `1_000_000`
|
|
163
|
+
and repaid via `repay_latest`, the pool grew to `2_050_000`, and the LP **withdrew
|
|
164
|
+
`2_050_000` for its `2_000_000` deposit — `+50_000` realized yield.**
|
|
165
|
+
[repay `80e90a43…`](https://testnet.cspr.live/deploy/80e90a43120b40524038a405088f3f83c4ce45674a9ff3e28c577a20552cba9e) ·
|
|
166
|
+
[LP withdraw `44318b5b…`](https://testnet.cspr.live/deploy/44318b5b303dab8dbbb3c3b26ac0f148bf7b44701996fbd446f17f9f7622023c)
|
|
167
|
+
|
|
154
168
|
## Live deployment (casper-test)
|
|
155
169
|
|
|
156
170
|
| | |
|
|
157
171
|
|---|---|
|
|
158
|
-
| Vault (lending pool) package | `
|
|
172
|
+
| Vault (yield-bearing lending pool) package | `ca4086d3a7b1abf000d0a79e23a237bb484a14807e9438f2c56f3461073e1b2f` |
|
|
159
173
|
| CEP-18 asset (Fund402 USDC / F402) | `389cedc529cc553e2639884c9dcc5e6dcbeb3920f7f5ca5a39bf7f7b866bccd0` |
|
|
160
174
|
| Network | `casper:casper-test` |
|
|
161
175
|
| Facilitator | `https://x402-facilitator.cspr.cloud` |
|
|
162
176
|
|
|
163
|
-
|
|
164
|
-
own deployment for production.
|
|
177
|
+
Point `vaultContract` / `asset` at your own deployment for production.
|
|
165
178
|
|
|
166
179
|
## Verified live ✅
|
|
167
180
|
|
|
@@ -194,8 +207,9 @@ Run them yourself: `npm run test:e2e` (Tier-3) and `npm run test:e2e:collateral`
|
|
|
194
207
|
· `decodeChallenge` · `selectCasperOption` · `testnetClient` / `mainnetClient`.
|
|
195
208
|
|
|
196
209
|
**On-chain primitives:** `borrowAndPayOnChain` · `repayLoanOnChain` ·
|
|
197
|
-
`
|
|
198
|
-
`
|
|
210
|
+
`repayLatestOnChain` (repay your newest loan — no loan id) · `ensureCollateralAllowance`
|
|
211
|
+
· `buildExactPayload` · `waitForDeploy` · `agentTaggedAddress` ·
|
|
212
|
+
`transferAuthorizationDigest`.
|
|
199
213
|
|
|
200
214
|
## ⚠️ Security
|
|
201
215
|
|
package/dist/casper.d.ts
CHANGED
|
@@ -32,6 +32,15 @@ export declare function borrowAndPayOnChain(cfg: CasperWiringConfig, args: {
|
|
|
32
32
|
export declare function repayLoanOnChain(cfg: CasperWiringConfig, loanId: number): Promise<{
|
|
33
33
|
deployHash: string;
|
|
34
34
|
}>;
|
|
35
|
+
/**
|
|
36
|
+
* Repay the agent's **most recent** open loan without needing its id (vault
|
|
37
|
+
* `repay_latest`). Pulls back principal + the JIT fee — the fee accrues to the pool
|
|
38
|
+
* as LP yield. The agent must first `approve` the vault for principal + fee
|
|
39
|
+
* (see ensureCollateralAllowance) and hold that much of the asset.
|
|
40
|
+
*/
|
|
41
|
+
export declare function repayLatestOnChain(cfg: CasperWiringConfig): Promise<{
|
|
42
|
+
deployHash: string;
|
|
43
|
+
}>;
|
|
35
44
|
/**
|
|
36
45
|
* Approve the vault to pull `amount` of the CEP-18 asset from the agent (needed
|
|
37
46
|
* before a collateralized borrow_and_pay can escrow, and before repay_loan can
|
|
@@ -54,6 +63,21 @@ export declare function waitForDeploy(cfg: Pick<CasperWiringConfig, "nodeUrl">,
|
|
|
54
63
|
tries?: number;
|
|
55
64
|
intervalMs?: number;
|
|
56
65
|
}): Promise<boolean>;
|
|
66
|
+
/**
|
|
67
|
+
* LP deposits CEP-18 liquidity into the pool (minted as shares). The LP must first
|
|
68
|
+
* `approve` the vault for `amount` on the asset (see ensureCollateralAllowance). As
|
|
69
|
+
* borrow fees accrue, each share redeems for more — that's the LP's yield.
|
|
70
|
+
*/
|
|
71
|
+
export declare function depositLiquidityOnChain(cfg: CasperWiringConfig, amount: bigint): Promise<{
|
|
72
|
+
deployHash: string;
|
|
73
|
+
}>;
|
|
74
|
+
/**
|
|
75
|
+
* LP burns `shares` and withdraws the CEP-18 they redeem for — including accrued
|
|
76
|
+
* yield (limited to the pool's free cash).
|
|
77
|
+
*/
|
|
78
|
+
export declare function withdrawLiquidityOnChain(cfg: CasperWiringConfig, shares: bigint): Promise<{
|
|
79
|
+
deployHash: string;
|
|
80
|
+
}>;
|
|
57
81
|
/** Casper account-hash ("00" + 32-byte hash) for the agent's public key. */
|
|
58
82
|
export declare function agentTaggedAddress(agentPublicKey: string): string;
|
|
59
83
|
/**
|
package/dist/casper.js
CHANGED
|
@@ -11,8 +11,11 @@ exports.rpc = rpc;
|
|
|
11
11
|
exports.loadPrivateKey = loadPrivateKey;
|
|
12
12
|
exports.borrowAndPayOnChain = borrowAndPayOnChain;
|
|
13
13
|
exports.repayLoanOnChain = repayLoanOnChain;
|
|
14
|
+
exports.repayLatestOnChain = repayLatestOnChain;
|
|
14
15
|
exports.ensureCollateralAllowance = ensureCollateralAllowance;
|
|
15
16
|
exports.waitForDeploy = waitForDeploy;
|
|
17
|
+
exports.depositLiquidityOnChain = depositLiquidityOnChain;
|
|
18
|
+
exports.withdrawLiquidityOnChain = withdrawLiquidityOnChain;
|
|
16
19
|
exports.agentTaggedAddress = agentTaggedAddress;
|
|
17
20
|
exports.buildExactPayload = buildExactPayload;
|
|
18
21
|
const casper_js_sdk_1 = require("casper-js-sdk");
|
|
@@ -100,6 +103,28 @@ async function repayLoanOnChain(cfg, loanId) {
|
|
|
100
103
|
const result = await client.putDeploy(deploy);
|
|
101
104
|
return { deployHash: result.deployHash.toHex() };
|
|
102
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* Repay the agent's **most recent** open loan without needing its id (vault
|
|
108
|
+
* `repay_latest`). Pulls back principal + the JIT fee — the fee accrues to the pool
|
|
109
|
+
* as LP yield. The agent must first `approve` the vault for principal + fee
|
|
110
|
+
* (see ensureCollateralAllowance) and hold that much of the asset.
|
|
111
|
+
*/
|
|
112
|
+
async function repayLatestOnChain(cfg) {
|
|
113
|
+
const client = rpc(cfg.nodeUrl);
|
|
114
|
+
const algo = cfg.keyAlgorithm ?? casper_js_sdk_1.KeyAlgorithm.ED25519;
|
|
115
|
+
const signer = await loadPrivateKey(cfg.agentSecretKey, algo);
|
|
116
|
+
const sender = casper_js_sdk_1.PublicKey.fromHex(cfg.agentPublicKey);
|
|
117
|
+
const header = casper_js_sdk_1.DeployHeader.default();
|
|
118
|
+
header.account = sender;
|
|
119
|
+
header.chainName = cfg.chainName;
|
|
120
|
+
header.ttl = new casper_js_sdk_1.Duration(casper_js_sdk_1.DEFAULT_DEPLOY_TTL);
|
|
121
|
+
const session = callPkg(cfg.vaultContractHash, "repay_latest", casper_js_sdk_1.Args.fromMap({}));
|
|
122
|
+
const payment = casper_js_sdk_1.ExecutableDeployItem.standardPayment("3000000000");
|
|
123
|
+
const deploy = casper_js_sdk_1.Deploy.makeDeploy(header, payment, session);
|
|
124
|
+
deploy.sign(signer);
|
|
125
|
+
const result = await client.putDeploy(deploy);
|
|
126
|
+
return { deployHash: result.deployHash.toHex() };
|
|
127
|
+
}
|
|
103
128
|
/**
|
|
104
129
|
* Approve the vault to pull `amount` of the CEP-18 asset from the agent (needed
|
|
105
130
|
* before a collateralized borrow_and_pay can escrow, and before repay_loan can
|
|
@@ -150,6 +175,41 @@ async function waitForDeploy(cfg, deployHash, { tries = 60, intervalMs = 3000 }
|
|
|
150
175
|
}
|
|
151
176
|
return false;
|
|
152
177
|
}
|
|
178
|
+
/**
|
|
179
|
+
* LP deposits CEP-18 liquidity into the pool (minted as shares). The LP must first
|
|
180
|
+
* `approve` the vault for `amount` on the asset (see ensureCollateralAllowance). As
|
|
181
|
+
* borrow fees accrue, each share redeems for more — that's the LP's yield.
|
|
182
|
+
*/
|
|
183
|
+
async function depositLiquidityOnChain(cfg, amount) {
|
|
184
|
+
const client = rpc(cfg.nodeUrl);
|
|
185
|
+
const signer = await loadPrivateKey(cfg.agentSecretKey, cfg.keyAlgorithm ?? casper_js_sdk_1.KeyAlgorithm.ED25519);
|
|
186
|
+
const header = casper_js_sdk_1.DeployHeader.default();
|
|
187
|
+
header.account = casper_js_sdk_1.PublicKey.fromHex(cfg.agentPublicKey);
|
|
188
|
+
header.chainName = cfg.chainName;
|
|
189
|
+
header.ttl = new casper_js_sdk_1.Duration(casper_js_sdk_1.DEFAULT_DEPLOY_TTL);
|
|
190
|
+
const session = callPkg(cfg.vaultContractHash, "deposit_liquidity", casper_js_sdk_1.Args.fromMap({ amount: casper_js_sdk_1.CLValue.newCLUInt256(amount.toString()) }));
|
|
191
|
+
const deploy = casper_js_sdk_1.Deploy.makeDeploy(header, casper_js_sdk_1.ExecutableDeployItem.standardPayment("4000000000"), session);
|
|
192
|
+
deploy.sign(signer);
|
|
193
|
+
const result = await client.putDeploy(deploy);
|
|
194
|
+
return { deployHash: result.deployHash.toHex() };
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* LP burns `shares` and withdraws the CEP-18 they redeem for — including accrued
|
|
198
|
+
* yield (limited to the pool's free cash).
|
|
199
|
+
*/
|
|
200
|
+
async function withdrawLiquidityOnChain(cfg, shares) {
|
|
201
|
+
const client = rpc(cfg.nodeUrl);
|
|
202
|
+
const signer = await loadPrivateKey(cfg.agentSecretKey, cfg.keyAlgorithm ?? casper_js_sdk_1.KeyAlgorithm.ED25519);
|
|
203
|
+
const header = casper_js_sdk_1.DeployHeader.default();
|
|
204
|
+
header.account = casper_js_sdk_1.PublicKey.fromHex(cfg.agentPublicKey);
|
|
205
|
+
header.chainName = cfg.chainName;
|
|
206
|
+
header.ttl = new casper_js_sdk_1.Duration(casper_js_sdk_1.DEFAULT_DEPLOY_TTL);
|
|
207
|
+
const session = callPkg(cfg.vaultContractHash, "withdraw_liquidity", casper_js_sdk_1.Args.fromMap({ shares: casper_js_sdk_1.CLValue.newCLUInt256(shares.toString()) }));
|
|
208
|
+
const deploy = casper_js_sdk_1.Deploy.makeDeploy(header, casper_js_sdk_1.ExecutableDeployItem.standardPayment("4000000000"), session);
|
|
209
|
+
deploy.sign(signer);
|
|
210
|
+
const result = await client.putDeploy(deploy);
|
|
211
|
+
return { deployHash: result.deployHash.toHex() };
|
|
212
|
+
}
|
|
153
213
|
/** Casper account-hash ("00" + 32-byte hash) for the agent's public key. */
|
|
154
214
|
function agentTaggedAddress(agentPublicKey) {
|
|
155
215
|
const pk = casper_js_sdk_1.PublicKey.fromHex(agentPublicKey);
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export * from "./types";
|
|
2
2
|
export { paywall, buildPaymentRequirements, challengeBody, decodePaymentSignature, verifyPoolSettlement, verifyWithFacilitator, explorerTx, type PaywallConfig, type Fund402Paywall, type VerifyResult, type GuardResult, type RequestLike, type HttpResponseLike, } from "./server";
|
|
3
3
|
export { fund402Fetch, withPaymentInterceptor, payViaPool, decodeChallenge, selectCasperOption, testnetClient, mainnetClient, type Fund402ClientConfig, type Fund402Event, } from "./client";
|
|
4
|
-
export { borrowAndPayOnChain, repayLoanOnChain, ensureCollateralAllowance, buildExactPayload, waitForDeploy, agentTaggedAddress, loadPrivateKey, rpc, type CasperWiringConfig, } from "./casper";
|
|
4
|
+
export { borrowAndPayOnChain, repayLoanOnChain, repayLatestOnChain, depositLiquidityOnChain, withdrawLiquidityOnChain, ensureCollateralAllowance, buildExactPayload, waitForDeploy, agentTaggedAddress, loadPrivateKey, rpc, type CasperWiringConfig, } from "./casper";
|
|
5
5
|
export { transferAuthorizationDigest, randomNonce, bytesToHex } from "./eip712";
|
|
6
6
|
export { expressPaywall } from "./adapters/express";
|
|
7
7
|
export { honoPaywall } from "./adapters/hono";
|
package/dist/index.js
CHANGED
|
@@ -25,7 +25,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
25
25
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
26
26
|
};
|
|
27
27
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
-
exports.withPaywall = exports.honoPaywall = exports.expressPaywall = exports.bytesToHex = exports.randomNonce = exports.transferAuthorizationDigest = exports.rpc = exports.loadPrivateKey = exports.agentTaggedAddress = exports.waitForDeploy = exports.buildExactPayload = exports.ensureCollateralAllowance = exports.repayLoanOnChain = exports.borrowAndPayOnChain = exports.mainnetClient = exports.testnetClient = exports.selectCasperOption = exports.decodeChallenge = exports.payViaPool = exports.withPaymentInterceptor = exports.fund402Fetch = exports.explorerTx = exports.verifyWithFacilitator = exports.verifyPoolSettlement = exports.decodePaymentSignature = exports.challengeBody = exports.buildPaymentRequirements = exports.paywall = void 0;
|
|
28
|
+
exports.withPaywall = exports.honoPaywall = exports.expressPaywall = exports.bytesToHex = exports.randomNonce = exports.transferAuthorizationDigest = exports.rpc = exports.loadPrivateKey = exports.agentTaggedAddress = exports.waitForDeploy = exports.buildExactPayload = exports.ensureCollateralAllowance = exports.withdrawLiquidityOnChain = exports.depositLiquidityOnChain = exports.repayLatestOnChain = exports.repayLoanOnChain = exports.borrowAndPayOnChain = exports.mainnetClient = exports.testnetClient = exports.selectCasperOption = exports.decodeChallenge = exports.payViaPool = exports.withPaymentInterceptor = exports.fund402Fetch = exports.explorerTx = exports.verifyWithFacilitator = exports.verifyPoolSettlement = exports.decodePaymentSignature = exports.challengeBody = exports.buildPaymentRequirements = exports.paywall = void 0;
|
|
29
29
|
__exportStar(require("./types"), exports);
|
|
30
30
|
// Server
|
|
31
31
|
var server_1 = require("./server");
|
|
@@ -49,6 +49,9 @@ Object.defineProperty(exports, "mainnetClient", { enumerable: true, get: functio
|
|
|
49
49
|
var casper_1 = require("./casper");
|
|
50
50
|
Object.defineProperty(exports, "borrowAndPayOnChain", { enumerable: true, get: function () { return casper_1.borrowAndPayOnChain; } });
|
|
51
51
|
Object.defineProperty(exports, "repayLoanOnChain", { enumerable: true, get: function () { return casper_1.repayLoanOnChain; } });
|
|
52
|
+
Object.defineProperty(exports, "repayLatestOnChain", { enumerable: true, get: function () { return casper_1.repayLatestOnChain; } });
|
|
53
|
+
Object.defineProperty(exports, "depositLiquidityOnChain", { enumerable: true, get: function () { return casper_1.depositLiquidityOnChain; } });
|
|
54
|
+
Object.defineProperty(exports, "withdrawLiquidityOnChain", { enumerable: true, get: function () { return casper_1.withdrawLiquidityOnChain; } });
|
|
52
55
|
Object.defineProperty(exports, "ensureCollateralAllowance", { enumerable: true, get: function () { return casper_1.ensureCollateralAllowance; } });
|
|
53
56
|
Object.defineProperty(exports, "buildExactPayload", { enumerable: true, get: function () { return casper_1.buildExactPayload; } });
|
|
54
57
|
Object.defineProperty(exports, "waitForDeploy", { enumerable: true, get: function () { return casper_1.waitForDeploy; } });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nickthelegend69/fund402",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Create x402-gated HTTP endpoints settled by the Fund402 lending pool on Casper — and the agent client that pays them with just-in-time credit. Drop-in middleware for Express, Hono and Next.js.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"x402",
|