@pearcurve/sdk 0.0.0-stage → 0.1.1
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/LICENSE +64 -0
- package/README.md +122 -2
- package/dist/abis.d.ts +21 -0
- package/dist/abis.d.ts.map +1 -0
- package/dist/abis.js +39 -0
- package/dist/abis.js.map +1 -0
- package/dist/borrowerSubmitPreflight.d.ts +14 -0
- package/dist/borrowerSubmitPreflight.d.ts.map +1 -0
- package/dist/borrowerSubmitPreflight.js +28 -0
- package/dist/borrowerSubmitPreflight.js.map +1 -0
- package/dist/bps.d.ts +11 -0
- package/dist/bps.d.ts.map +1 -0
- package/dist/bps.js +25 -0
- package/dist/bps.js.map +1 -0
- package/dist/clients.d.ts +23 -0
- package/dist/clients.d.ts.map +1 -0
- package/dist/clients.js +59 -0
- package/dist/clients.js.map +1 -0
- package/dist/decodeError.d.ts +24 -0
- package/dist/decodeError.d.ts.map +1 -0
- package/dist/decodeError.js +358 -0
- package/dist/decodeError.js.map +1 -0
- package/dist/encoding.d.ts +18 -0
- package/dist/encoding.d.ts.map +1 -0
- package/dist/encoding.js +94 -0
- package/dist/encoding.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/lenderSubmitPreflight.d.ts +20 -0
- package/dist/lenderSubmitPreflight.d.ts.map +1 -0
- package/dist/lenderSubmitPreflight.js +42 -0
- package/dist/lenderSubmitPreflight.js.map +1 -0
- package/dist/loanPositions.d.ts +23 -0
- package/dist/loanPositions.d.ts.map +1 -0
- package/dist/loanPositions.js +37 -0
- package/dist/loanPositions.js.map +1 -0
- package/dist/marketStats.d.ts +70 -0
- package/dist/marketStats.d.ts.map +1 -0
- package/dist/marketStats.js +117 -0
- package/dist/marketStats.js.map +1 -0
- package/dist/networkConfig.d.ts +48 -0
- package/dist/networkConfig.d.ts.map +1 -0
- package/dist/networkConfig.js +48 -0
- package/dist/networkConfig.js.map +1 -0
- package/dist/pause.d.ts +20 -0
- package/dist/pause.d.ts.map +1 -0
- package/dist/pause.js +40 -0
- package/dist/pause.js.map +1 -0
- package/dist/reads.d.ts +187 -0
- package/dist/reads.d.ts.map +1 -0
- package/dist/reads.js +353 -0
- package/dist/reads.js.map +1 -0
- package/dist/strategies.d.ts +14 -0
- package/dist/strategies.d.ts.map +1 -0
- package/dist/strategies.js +49 -0
- package/dist/strategies.js.map +1 -0
- package/dist/txGas.d.ts +19 -0
- package/dist/txGas.d.ts.map +1 -0
- package/dist/txGas.js +37 -0
- package/dist/txGas.js.map +1 -0
- package/dist/types.d.ts +69 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/dist/yieldMigrationPreflight.d.ts +29 -0
- package/dist/yieldMigrationPreflight.d.ts.map +1 -0
- package/dist/yieldMigrationPreflight.js +61 -0
- package/dist/yieldMigrationPreflight.js.map +1 -0
- package/dist/yieldSources.d.ts +33 -0
- package/dist/yieldSources.d.ts.map +1 -0
- package/dist/yieldSources.js +106 -0
- package/dist/yieldSources.js.map +1 -0
- package/package.json +47 -4
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Provider } from 'ethers';
|
|
2
|
+
export type YieldMigrationPreflightParams = {
|
|
3
|
+
viewsAddress: string;
|
|
4
|
+
owner: string;
|
|
5
|
+
fromSource: string;
|
|
6
|
+
asset: string;
|
|
7
|
+
/** Shares to migrate (same units as Main.migrateYieldSource). */
|
|
8
|
+
shares: bigint;
|
|
9
|
+
/** Lender intent ids to retarget; empty for liquidity-only migration. */
|
|
10
|
+
lenderIntentIds: bigint[];
|
|
11
|
+
};
|
|
12
|
+
export type YieldMigrationPreflightResult = {
|
|
13
|
+
maxMigratable: bigint;
|
|
14
|
+
balance: bigint;
|
|
15
|
+
committed: bigint;
|
|
16
|
+
retargetRemaining: bigint;
|
|
17
|
+
assetsPreview: bigint;
|
|
18
|
+
intentIds: bigint[];
|
|
19
|
+
intentRemaining: bigint[];
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Read-only preflight for `Main.migrateYieldSource(..., lenderIntentIds)`.
|
|
23
|
+
*/
|
|
24
|
+
export declare function previewYieldMigration(provider: Provider, p: YieldMigrationPreflightParams): Promise<YieldMigrationPreflightResult>;
|
|
25
|
+
/**
|
|
26
|
+
* Throws if migration would hit `YieldWithdrawWouldInsolventIntents` / `MigrationInsufficientForRetarget`.
|
|
27
|
+
*/
|
|
28
|
+
export declare function assertYieldMigration(provider: Provider, p: YieldMigrationPreflightParams): Promise<YieldMigrationPreflightResult>;
|
|
29
|
+
//# sourceMappingURL=yieldMigrationPreflight.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yieldMigrationPreflight.d.ts","sourceRoot":"","sources":["../src/yieldMigrationPreflight.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAGtC,MAAM,MAAM,6BAA6B,GAAG;IAC1C,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,iEAAiE;IACjE,MAAM,EAAE,MAAM,CAAA;IACd,yEAAyE;IACzE,eAAe,EAAE,MAAM,EAAE,CAAA;CAC1B,CAAA;AAED,MAAM,MAAM,6BAA6B,GAAG;IAC1C,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,iBAAiB,EAAE,MAAM,CAAA;IACzB,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,eAAe,EAAE,MAAM,EAAE,CAAA;CAC1B,CAAA;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,QAAQ,EAClB,CAAC,EAAE,6BAA6B,GAC/B,OAAO,CAAC,6BAA6B,CAAC,CAqCxC;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,QAAQ,EAClB,CAAC,EAAE,6BAA6B,GAC/B,OAAO,CAAC,6BAA6B,CAAC,CA2BxC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Contract, getAddress } from 'ethers';
|
|
2
|
+
import { intentRegistryViewsAbi, yieldSourceAbi } from './abis.js';
|
|
3
|
+
/**
|
|
4
|
+
* Read-only preflight for `Main.migrateYieldSource(..., lenderIntentIds)`.
|
|
5
|
+
*/
|
|
6
|
+
export async function previewYieldMigration(provider, p) {
|
|
7
|
+
const views = new Contract(getAddress(p.viewsAddress), intentRegistryViewsAbi, provider);
|
|
8
|
+
const from = getAddress(p.fromSource);
|
|
9
|
+
const owner = getAddress(p.owner);
|
|
10
|
+
const asset = getAddress(p.asset);
|
|
11
|
+
const [maxMigratable, intentIds, intentRemaining] = await Promise.all([
|
|
12
|
+
views.maxMigratableBalance(owner, from, asset),
|
|
13
|
+
views.getLenderIntentsAtYieldSource(owner, from, asset).then((r) => r[0]),
|
|
14
|
+
views.getLenderIntentsAtYieldSource(owner, from, asset).then((r) => r[1]),
|
|
15
|
+
]);
|
|
16
|
+
const ys = new Contract(from, yieldSourceAbi, provider);
|
|
17
|
+
const balance = (await ys.balanceOf(owner, asset));
|
|
18
|
+
const assetsPreview = (await ys.convertToAssets(p.shares, asset));
|
|
19
|
+
const committed = balance > maxMigratable ? balance - maxMigratable : 0n;
|
|
20
|
+
let retargetRemaining = 0n;
|
|
21
|
+
if (p.lenderIntentIds.length > 0) {
|
|
22
|
+
const idSet = new Set(p.lenderIntentIds.map((id) => id.toString()));
|
|
23
|
+
for (let i = 0; i < intentIds.length; i++) {
|
|
24
|
+
const id = intentIds[i];
|
|
25
|
+
if (idSet.has(id.toString())) {
|
|
26
|
+
retargetRemaining += intentRemaining[i];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
maxMigratable,
|
|
32
|
+
balance,
|
|
33
|
+
committed,
|
|
34
|
+
retargetRemaining,
|
|
35
|
+
assetsPreview,
|
|
36
|
+
intentIds: intentIds.map((x) => BigInt(x)),
|
|
37
|
+
intentRemaining: intentRemaining.map((x) => BigInt(x)),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Throws if migration would hit `YieldWithdrawWouldInsolventIntents` / `MigrationInsufficientForRetarget`.
|
|
42
|
+
*/
|
|
43
|
+
export async function assertYieldMigration(provider, p) {
|
|
44
|
+
const preview = await previewYieldMigration(provider, p);
|
|
45
|
+
const { assetsPreview, retargetRemaining, maxMigratable, committed, balance } = preview;
|
|
46
|
+
if (p.lenderIntentIds.length === 0) {
|
|
47
|
+
if (assetsPreview > maxMigratable) {
|
|
48
|
+
throw new Error(`Migration exceeds free liquidity: ${assetsPreview.toString()} assets but only ${maxMigratable.toString()} migratable (${committed.toString()} reserved by lender intents). Retarget intents or cancel them first.`);
|
|
49
|
+
}
|
|
50
|
+
return preview;
|
|
51
|
+
}
|
|
52
|
+
if (assetsPreview < retargetRemaining) {
|
|
53
|
+
throw new Error(`Migration assets (${assetsPreview.toString()}) must cover selected intents' remaining capacity (${retargetRemaining.toString()}).`);
|
|
54
|
+
}
|
|
55
|
+
const minBalanceAfter = committed > retargetRemaining ? committed - retargetRemaining : 0n;
|
|
56
|
+
if (balance < assetsPreview + minBalanceAfter) {
|
|
57
|
+
throw new Error(`Migration would insolvent remaining intents at source: balance ${balance.toString()}, out ${assetsPreview.toString()}, need ${minBalanceAfter.toString()} left after withdraw.`);
|
|
58
|
+
}
|
|
59
|
+
return preview;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=yieldMigrationPreflight.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yieldMigrationPreflight.js","sourceRoot":"","sources":["../src/yieldMigrationPreflight.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Contract, type ContractRunner } from 'ethers';
|
|
2
|
+
import type { Address } from './types.js';
|
|
3
|
+
/** One registry-listed yield source with on-chain APY (bps) for `asset`. */
|
|
4
|
+
export type SupportedYieldSourceApy = {
|
|
5
|
+
address: Address;
|
|
6
|
+
name: string;
|
|
7
|
+
/** Annual supply APY in basis points (10_000 = 100%); null if `currentApy` reverted. */
|
|
8
|
+
apyBps: bigint | null;
|
|
9
|
+
/** Set when `currentApy` could not be read (e.g. unsupported asset for that venue). */
|
|
10
|
+
error?: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Addresses still marked approved on the registry.
|
|
14
|
+
* @dev `getApprovedSources()` returns the full registration list; removed sources stay in the array with `approvedSources(addr) == false`.
|
|
15
|
+
*/
|
|
16
|
+
export declare function listApprovedYieldSourceAddresses(registry: Contract): Promise<Address[]>;
|
|
17
|
+
/**
|
|
18
|
+
* For each approved yield source, reads `name()` and `currentApy(asset)` via `IYieldSource`.
|
|
19
|
+
* Per-source failures on `currentApy` yield `apyBps: null` and `error` instead of throwing.
|
|
20
|
+
*/
|
|
21
|
+
export declare function fetchSupportedYieldSourceApys(registry: Contract, asset: Address): Promise<SupportedYieldSourceApy[]>;
|
|
22
|
+
/** Same as {@link fetchSupportedYieldSourceApys} but resolves the registry from `Main.yieldSourceRegistry()`. */
|
|
23
|
+
export declare function fetchSupportedYieldSourceApysFromMain(main: Contract, asset: Address): Promise<SupportedYieldSourceApy[]>;
|
|
24
|
+
/**
|
|
25
|
+
* Keep multi-asset sources (e.g. Aave) and Compound comets whose `baseAsset()` matches `asset`.
|
|
26
|
+
* Compound detection uses `baseAsset()` — not `name()` — so filtering works when name reads fail.
|
|
27
|
+
*/
|
|
28
|
+
export declare function filterYieldSourcesForAsset(rows: SupportedYieldSourceApy[], asset: Address, runner: ContractRunner): Promise<SupportedYieldSourceApy[]>;
|
|
29
|
+
/**
|
|
30
|
+
* All approved yield adapters applicable to one loan asset (registry-driven; APY may be null).
|
|
31
|
+
*/
|
|
32
|
+
export declare function fetchYieldSourcesForAsset(main: Contract, asset: Address): Promise<SupportedYieldSourceApy[]>;
|
|
33
|
+
//# sourceMappingURL=yieldSources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yieldSources.d.ts","sourceRoot":"","sources":["../src/yieldSources.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,cAAc,EAAE,MAAM,QAAQ,CAAA;AAGtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAEzC,4EAA4E;AAC5E,MAAM,MAAM,uBAAuB,GAAG;IACpC,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,wFAAwF;IACxF,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,uFAAuF;IACvF,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAQD;;;GAGG;AACH,wBAAsB,gCAAgC,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAa7F;AAED;;;GAGG;AACH,wBAAsB,6BAA6B,CACjD,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAsBpC;AAED,iHAAiH;AACjH,wBAAsB,qCAAqC,CACzD,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAKpC;AAgBD;;;GAGG;AACH,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,uBAAuB,EAAE,EAC/B,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAcpC;AAED;;GAEG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAKpC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { Contract } from 'ethers';
|
|
2
|
+
import { yieldSourceAbi, yieldSourceRegistryAbi } from './abis.js';
|
|
3
|
+
function runnerOrThrow(c) {
|
|
4
|
+
const r = c.runner;
|
|
5
|
+
if (!r)
|
|
6
|
+
throw new Error('Contract has no runner (attach a provider or signer).');
|
|
7
|
+
return r;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Addresses still marked approved on the registry.
|
|
11
|
+
* @dev `getApprovedSources()` returns the full registration list; removed sources stay in the array with `approvedSources(addr) == false`.
|
|
12
|
+
*/
|
|
13
|
+
export async function listApprovedYieldSourceAddresses(registry) {
|
|
14
|
+
const raw = await registry.getApprovedSources();
|
|
15
|
+
const approved = [];
|
|
16
|
+
const seen = new Set();
|
|
17
|
+
for (const addr of raw) {
|
|
18
|
+
const lower = addr.toLowerCase();
|
|
19
|
+
if (seen.has(lower))
|
|
20
|
+
continue;
|
|
21
|
+
if (await registry.approvedSources(addr)) {
|
|
22
|
+
seen.add(lower);
|
|
23
|
+
approved.push(addr);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return approved;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* For each approved yield source, reads `name()` and `currentApy(asset)` via `IYieldSource`.
|
|
30
|
+
* Per-source failures on `currentApy` yield `apyBps: null` and `error` instead of throwing.
|
|
31
|
+
*/
|
|
32
|
+
export async function fetchSupportedYieldSourceApys(registry, asset) {
|
|
33
|
+
const runner = runnerOrThrow(registry);
|
|
34
|
+
const addrs = await listApprovedYieldSourceAddresses(registry);
|
|
35
|
+
const out = [];
|
|
36
|
+
for (const addr of addrs) {
|
|
37
|
+
const source = new Contract(addr, yieldSourceAbi, runner);
|
|
38
|
+
let name = '';
|
|
39
|
+
try {
|
|
40
|
+
name = await source.name();
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// ignore; leave empty
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
const apyBps = await source.currentApy(asset);
|
|
47
|
+
out.push({ address: addr, name, apyBps });
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
const msg = e instanceof Error ? e.message : 'currentApy reverted';
|
|
51
|
+
out.push({ address: addr, name, apyBps: null, error: msg });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return out;
|
|
55
|
+
}
|
|
56
|
+
/** Same as {@link fetchSupportedYieldSourceApys} but resolves the registry from `Main.yieldSourceRegistry()`. */
|
|
57
|
+
export async function fetchSupportedYieldSourceApysFromMain(main, asset) {
|
|
58
|
+
const runner = runnerOrThrow(main);
|
|
59
|
+
const regAddr = await main.yieldSourceRegistry();
|
|
60
|
+
const registry = new Contract(regAddr, yieldSourceRegistryAbi, runner);
|
|
61
|
+
return fetchSupportedYieldSourceApys(registry, asset);
|
|
62
|
+
}
|
|
63
|
+
const COMPOUND_BASE_ASSET_ABI = ['function baseAsset() view returns (address)'];
|
|
64
|
+
function dedupeYieldSourceRows(rows) {
|
|
65
|
+
const seen = new Set();
|
|
66
|
+
const out = [];
|
|
67
|
+
for (const row of rows) {
|
|
68
|
+
const key = row.address.toLowerCase();
|
|
69
|
+
if (seen.has(key))
|
|
70
|
+
continue;
|
|
71
|
+
seen.add(key);
|
|
72
|
+
out.push(row);
|
|
73
|
+
}
|
|
74
|
+
return out;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Keep multi-asset sources (e.g. Aave) and Compound comets whose `baseAsset()` matches `asset`.
|
|
78
|
+
* Compound detection uses `baseAsset()` — not `name()` — so filtering works when name reads fail.
|
|
79
|
+
*/
|
|
80
|
+
export async function filterYieldSourcesForAsset(rows, asset, runner) {
|
|
81
|
+
const assetLower = asset.toLowerCase();
|
|
82
|
+
/** Sequential — parallel baseAsset() bursts trigger Alchemy 429 in dev. */
|
|
83
|
+
const filtered = [];
|
|
84
|
+
for (const row of rows) {
|
|
85
|
+
try {
|
|
86
|
+
const c = new Contract(row.address, COMPOUND_BASE_ASSET_ABI, runner);
|
|
87
|
+
const baseAsset = String(await c.baseAsset()).toLowerCase();
|
|
88
|
+
if (baseAsset === assetLower)
|
|
89
|
+
filtered.push(row);
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
filtered.push(row);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return filtered;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* All approved yield adapters applicable to one loan asset (registry-driven; APY may be null).
|
|
99
|
+
*/
|
|
100
|
+
export async function fetchYieldSourcesForAsset(main, asset) {
|
|
101
|
+
const runner = runnerOrThrow(main);
|
|
102
|
+
const rowsRaw = await fetchSupportedYieldSourceApysFromMain(main, asset);
|
|
103
|
+
const deduped = dedupeYieldSourceRows(rowsRaw);
|
|
104
|
+
return filterYieldSourcesForAsset(deduped, asset, runner);
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=yieldSources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yieldSources.js","sourceRoot":"","sources":["../src/yieldSources.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,49 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pearcurve/sdk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "TypeScript SDK for Pearcurve protocol (ethers, calldata helpers)",
|
|
5
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/pearcurve/pearcurve-sdk.git"
|
|
9
|
+
},
|
|
10
|
+
"type": "module",
|
|
11
|
+
"main": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"publish:sdk": "node ./scripts/publish-sdk.mjs",
|
|
24
|
+
"sync-deployments": "node ./scripts/sync-deployments.mjs",
|
|
25
|
+
"build": "rm -rf dist && tsc",
|
|
26
|
+
"prepack": "npm run build",
|
|
27
|
+
"test": "vitest run",
|
|
28
|
+
"test:watch": "vitest"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@pearcurve/contracts": "^0.1.0"
|
|
32
|
+
},
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"ethers": "^6.16.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/node": "^22.10.0",
|
|
38
|
+
"ethers": "^6.16.0",
|
|
39
|
+
"tsx": "^4.19.0",
|
|
40
|
+
"typescript": "^5.7.2",
|
|
41
|
+
"vitest": "^3.0.0"
|
|
42
|
+
},
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=20.10"
|
|
45
|
+
},
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public"
|
|
48
|
+
}
|
|
49
|
+
}
|