@splitmarkets/sdk 0.2.0 → 0.2.2
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/dist/{chunk-MZEPXYHI.js → chunk-FDWH3X5N.js} +27 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +1 -1
- package/dist/widget.js +21 -16
- package/package.json +27 -6
|
@@ -319,6 +319,7 @@ function defaultFeeHeadroom(amount) {
|
|
|
319
319
|
}
|
|
320
320
|
async function buyGasless(args) {
|
|
321
321
|
const { chain, side, seriesId } = args;
|
|
322
|
+
await ensureWalletChain(args.walletClient, chain);
|
|
322
323
|
const pool = poolAddress(chain, side);
|
|
323
324
|
const usdc = CHAINS[chain].usdc;
|
|
324
325
|
const client = getPublic(chain, args.rpcUrl);
|
|
@@ -384,6 +385,7 @@ async function buyGasless(args) {
|
|
|
384
385
|
}
|
|
385
386
|
async function closeGasless(args) {
|
|
386
387
|
const { chain, side, seriesId } = args;
|
|
388
|
+
await ensureWalletChain(args.walletClient, chain);
|
|
387
389
|
const pool = poolAddress(chain, side);
|
|
388
390
|
const client = getPublic(chain, args.rpcUrl);
|
|
389
391
|
const trading = args.trading ?? await deriveTradingAccount(args.walletClient, args.account, chain, args.rpcUrl);
|
|
@@ -548,6 +550,28 @@ function getPublic(chain, rpcUrl) {
|
|
|
548
550
|
return p;
|
|
549
551
|
}
|
|
550
552
|
var chainObj = (chain) => chain === "base" ? base : arbitrum;
|
|
553
|
+
async function ensureWalletChain(walletClient, chain) {
|
|
554
|
+
if (walletClient.account?.type === "local") return;
|
|
555
|
+
const want = CHAINS[chain].id;
|
|
556
|
+
let current;
|
|
557
|
+
try {
|
|
558
|
+
current = await walletClient.getChainId();
|
|
559
|
+
} catch {
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
if (current === want) return;
|
|
563
|
+
try {
|
|
564
|
+
await walletClient.switchChain({ id: want });
|
|
565
|
+
} catch (e) {
|
|
566
|
+
const code = e?.code;
|
|
567
|
+
if (code === 4902 || /unrecognized|not been added/i.test(String(e?.message))) {
|
|
568
|
+
await walletClient.addChain({ chain: chainObj(chain) });
|
|
569
|
+
await walletClient.switchChain({ id: want });
|
|
570
|
+
} else {
|
|
571
|
+
throw e;
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
}
|
|
551
575
|
var toNWei2 = (qN) => BigInt(Math.round(qN * 1e18));
|
|
552
576
|
var quoteCost2 = (qNWei, perN) => (qNWei * perN + ONE2 - 1n) / ONE2;
|
|
553
577
|
var sellProceeds2 = (qNWei, perN) => qNWei * perN / ONE2;
|
|
@@ -611,6 +635,7 @@ function quoteTuple(q) {
|
|
|
611
635
|
}
|
|
612
636
|
async function buy(args) {
|
|
613
637
|
const { chain, side, seriesId, account, walletClient } = args;
|
|
638
|
+
await ensureWalletChain(walletClient, chain);
|
|
614
639
|
const pool = poolAddress(chain, side);
|
|
615
640
|
const c = cfg(chain);
|
|
616
641
|
const pub = getPublic(chain, args.rpcUrl);
|
|
@@ -653,6 +678,7 @@ async function buy(args) {
|
|
|
653
678
|
}
|
|
654
679
|
async function close(args) {
|
|
655
680
|
const { chain, side, seriesId, account, walletClient } = args;
|
|
681
|
+
await ensureWalletChain(walletClient, chain);
|
|
656
682
|
const pool = poolAddress(chain, side);
|
|
657
683
|
const pub = getPublic(chain, args.rpcUrl);
|
|
658
684
|
const quote = args.quote ?? await getQuote(chain, side, seriesId);
|
|
@@ -755,4 +781,4 @@ async function ensureAllowance(pub, walletClient, chain, token, owner, spender,
|
|
|
755
781
|
await pub.waitForTransactionReceipt({ hash });
|
|
756
782
|
}
|
|
757
783
|
|
|
758
|
-
export { ARB_CHAIN_ID, BASE_CHAIN_ID, CHAINS, ERC20_ABI, FACILITATOR_URL_ARB, FACILITATOR_URL_BASE, NEXUS_BOOTSTRAP, NEXUS_FACTORY, QUOTE_API, SPLIT_POOL_ABI, SPLIT_VAULT_ABI, buy, buyGasless, close, closeGasless, deriveSmartWallet, deriveTradingAccount, facilitatorUrlForChain, getMarkets, getPosition, getPositionGasless, getPublic, getQuote, poolAddress, quoteTuple };
|
|
784
|
+
export { ARB_CHAIN_ID, BASE_CHAIN_ID, CHAINS, ERC20_ABI, FACILITATOR_URL_ARB, FACILITATOR_URL_BASE, NEXUS_BOOTSTRAP, NEXUS_FACTORY, QUOTE_API, SPLIT_POOL_ABI, SPLIT_VAULT_ABI, buy, buyGasless, close, closeGasless, deriveSmartWallet, deriveTradingAccount, ensureWalletChain, facilitatorUrlForChain, getMarkets, getPosition, getPositionGasless, getPublic, getQuote, poolAddress, quoteTuple };
|
package/dist/index.d.ts
CHANGED
|
@@ -446,6 +446,13 @@ interface TradeResult {
|
|
|
446
446
|
}
|
|
447
447
|
/** A cached viem public client for a chain. Pass `rpcUrl` to use your own RPC. */
|
|
448
448
|
declare function getPublic(chain: ChainName, rpcUrl?: string): PublicClient;
|
|
449
|
+
/**
|
|
450
|
+
* Switch the connected wallet to a chain before signing/sending on it. An external wallet
|
|
451
|
+
* (MetaMask etc.) rejects a tx/typed-data whose chain differs from its active chain, so
|
|
452
|
+
* every trade fn calls this first. Idempotent (no prompt if already there); adds the chain
|
|
453
|
+
* if unknown (4902). Skipped for local signers, which sign any chain.
|
|
454
|
+
*/
|
|
455
|
+
declare function ensureWalletChain(walletClient: WalletClient, chain: ChainName): Promise<void>;
|
|
449
456
|
/**
|
|
450
457
|
* Read the live grid: current epoch -> every series (seriesAt) -> strike + a quote.
|
|
451
458
|
* Leverage = spot / premium (the ask from the quote API). Returns [] if the pool
|
|
@@ -524,4 +531,4 @@ interface PositionArgs {
|
|
|
524
531
|
*/
|
|
525
532
|
declare function getPosition(args: PositionArgs): Promise<Position>;
|
|
526
533
|
|
|
527
|
-
export { ARB_CHAIN_ID, BASE_CHAIN_ID, type BuyArgs, type BuyGaslessArgs, CHAINS, type ChainConfig, type ChainId, type ChainName, type CloseArgs, type CloseGaslessArgs, ERC20_ABI, type ExecuteCall, FACILITATOR_URL_ARB, FACILITATOR_URL_BASE, type GaslessPosition, type GaslessResult, type Greeks, type Market, NEXUS_BOOTSTRAP, NEXUS_FACTORY, type Position, type PositionArgs, type PositionGaslessArgs, QUOTE_API, SPLIT_POOL_ABI, SPLIT_VAULT_ABI, type Side, type SplitQuote, type TradeResult, type TradingAccount, type UserOp, buy, buyGasless, close, closeGasless, deriveSmartWallet, deriveTradingAccount, facilitatorUrlForChain, getMarkets, getPosition, getPositionGasless, getPublic, getQuote, poolAddress, quoteTuple };
|
|
534
|
+
export { ARB_CHAIN_ID, BASE_CHAIN_ID, type BuyArgs, type BuyGaslessArgs, CHAINS, type ChainConfig, type ChainId, type ChainName, type CloseArgs, type CloseGaslessArgs, ERC20_ABI, type ExecuteCall, FACILITATOR_URL_ARB, FACILITATOR_URL_BASE, type GaslessPosition, type GaslessResult, type Greeks, type Market, NEXUS_BOOTSTRAP, NEXUS_FACTORY, type Position, type PositionArgs, type PositionGaslessArgs, QUOTE_API, SPLIT_POOL_ABI, SPLIT_VAULT_ABI, type Side, type SplitQuote, type TradeResult, type TradingAccount, type UserOp, buy, buyGasless, close, closeGasless, deriveSmartWallet, deriveTradingAccount, ensureWalletChain, facilitatorUrlForChain, getMarkets, getPosition, getPositionGasless, getPublic, getQuote, poolAddress, quoteTuple };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { ARB_CHAIN_ID, BASE_CHAIN_ID, CHAINS, ERC20_ABI, FACILITATOR_URL_ARB, FACILITATOR_URL_BASE, NEXUS_BOOTSTRAP, NEXUS_FACTORY, QUOTE_API, SPLIT_POOL_ABI, SPLIT_VAULT_ABI, buy, buyGasless, close, closeGasless, deriveSmartWallet, deriveTradingAccount, facilitatorUrlForChain, getMarkets, getPosition, getPositionGasless, getPublic, getQuote, poolAddress, quoteTuple } from './chunk-
|
|
1
|
+
export { ARB_CHAIN_ID, BASE_CHAIN_ID, CHAINS, ERC20_ABI, FACILITATOR_URL_ARB, FACILITATOR_URL_BASE, NEXUS_BOOTSTRAP, NEXUS_FACTORY, QUOTE_API, SPLIT_POOL_ABI, SPLIT_VAULT_ABI, buy, buyGasless, close, closeGasless, deriveSmartWallet, deriveTradingAccount, ensureWalletChain, facilitatorUrlForChain, getMarkets, getPosition, getPositionGasless, getPublic, getQuote, poolAddress, quoteTuple } from './chunk-FDWH3X5N.js';
|
package/dist/widget.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getMarkets, getPositionGasless, getPosition, deriveTradingAccount, buyGasless, buy, closeGasless, close } from './chunk-
|
|
1
|
+
import { getMarkets, getPositionGasless, getPosition, deriveTradingAccount, buyGasless, buy, closeGasless, close } from './chunk-FDWH3X5N.js';
|
|
2
2
|
import { useState, useId, useMemo, useEffect, useCallback } from 'react';
|
|
3
3
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
4
|
|
|
@@ -36,7 +36,7 @@ function SplitTradeWidget({
|
|
|
36
36
|
const [side, setSide] = useState("long");
|
|
37
37
|
const [markets, setMarkets] = useState([]);
|
|
38
38
|
const [picked, setPicked] = useState(null);
|
|
39
|
-
const [amount, setAmount] = useState("
|
|
39
|
+
const [amount, setAmount] = useState("5");
|
|
40
40
|
const [position, setPosition] = useState(null);
|
|
41
41
|
const [status, setStatus] = useState("");
|
|
42
42
|
const [busy, setBusy] = useState(false);
|
|
@@ -105,11 +105,17 @@ function SplitTradeWidget({
|
|
|
105
105
|
setStatus("Connect a wallet first.");
|
|
106
106
|
return;
|
|
107
107
|
}
|
|
108
|
-
const
|
|
109
|
-
if (!(
|
|
110
|
-
setStatus("Enter
|
|
108
|
+
const usd = Number(amount);
|
|
109
|
+
if (!(usd > 0)) {
|
|
110
|
+
setStatus("Enter a dollar amount > 0.");
|
|
111
111
|
return;
|
|
112
112
|
}
|
|
113
|
+
const m = markets.find((x) => x.seriesId === picked);
|
|
114
|
+
if (!m || !(m.premium > 0)) {
|
|
115
|
+
setStatus("Market not ready \u2014 try again.");
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const qN = usd / m.premium;
|
|
113
119
|
setBusy(true);
|
|
114
120
|
try {
|
|
115
121
|
if (gasless) {
|
|
@@ -117,11 +123,11 @@ function SplitTradeWidget({
|
|
|
117
123
|
const t = trading ?? await deriveTradingAccount(walletClient, account, chain);
|
|
118
124
|
if (!trading) setTrading(t);
|
|
119
125
|
const r = await buyGasless({ chain, side, seriesId: picked, qN, walletClient, account, trading: t });
|
|
120
|
-
setStatus(`Bought ${
|
|
126
|
+
setStatus(`Bought $${usd} of ${side}. tx ${r.txHash.slice(0, 10)}\u2026`);
|
|
121
127
|
} else {
|
|
122
128
|
setStatus("Confirm in your wallet (approve, then buy)\u2026");
|
|
123
129
|
const r = await buy({ chain, side, seriesId: picked, qN, walletClient, account });
|
|
124
|
-
setStatus(`Bought ${
|
|
130
|
+
setStatus(`Bought $${usd} of ${side}. tx ${r.txHash.slice(0, 10)}\u2026`);
|
|
125
131
|
}
|
|
126
132
|
await refreshPosition();
|
|
127
133
|
} catch (e) {
|
|
@@ -181,31 +187,30 @@ function SplitTradeWidget({
|
|
|
181
187
|
children: [
|
|
182
188
|
/* @__PURE__ */ jsx("div", { className: "swt-lev", children: m.leverage > 0 ? `${m.leverage.toFixed(0)}x` : "\u2014" }),
|
|
183
189
|
/* @__PURE__ */ jsxs("div", { className: "swt-muted", children: [
|
|
184
|
-
"
|
|
185
|
-
|
|
190
|
+
"ETH ",
|
|
191
|
+
side === "long" ? ">" : "<",
|
|
192
|
+
" $",
|
|
193
|
+
(side === "long" ? m.strike + m.premium : m.strike - m.premium).toLocaleString(void 0, { maximumFractionDigits: 0 })
|
|
186
194
|
] }),
|
|
187
|
-
/* @__PURE__ */
|
|
188
|
-
"$",
|
|
189
|
-
m.premium.toFixed(2),
|
|
190
|
-
"/contract"
|
|
191
|
-
] })
|
|
195
|
+
/* @__PURE__ */ jsx("div", { className: "swt-muted-sm", children: "by expiry" })
|
|
192
196
|
]
|
|
193
197
|
},
|
|
194
198
|
m.seriesId
|
|
195
199
|
))
|
|
196
200
|
] }),
|
|
197
201
|
/* @__PURE__ */ jsxs("div", { className: "swt-row", children: [
|
|
202
|
+
/* @__PURE__ */ jsx("span", { className: "swt-muted", children: "$" }),
|
|
198
203
|
/* @__PURE__ */ jsx(
|
|
199
204
|
"input",
|
|
200
205
|
{
|
|
201
206
|
value: amount,
|
|
202
207
|
onChange: (e) => setAmount(e.target.value),
|
|
203
208
|
inputMode: "decimal",
|
|
204
|
-
placeholder: "
|
|
209
|
+
placeholder: "5",
|
|
205
210
|
className: "swt-input"
|
|
206
211
|
}
|
|
207
212
|
),
|
|
208
|
-
/* @__PURE__ */ jsx("span", { className: "swt-muted", children: "
|
|
213
|
+
/* @__PURE__ */ jsx("span", { className: "swt-muted", children: "USDC" }),
|
|
209
214
|
/* @__PURE__ */ jsx(
|
|
210
215
|
"button",
|
|
211
216
|
{
|
package/package.json
CHANGED
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@splitmarkets/sdk",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Oracle-free, non-liquidatable ETH options — viem client + optional React widget for Split (split.markets). Integrate leverage your users can't get liquidated out of.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
|
-
"files": [
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"README.md",
|
|
10
|
+
"SKILL.md"
|
|
11
|
+
],
|
|
8
12
|
"main": "./dist/index.js",
|
|
9
13
|
"module": "./dist/index.js",
|
|
10
14
|
"types": "./dist/index.d.ts",
|
|
11
15
|
"exports": {
|
|
12
|
-
".": {
|
|
13
|
-
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"import": "./dist/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./widget": {
|
|
21
|
+
"types": "./dist/widget.d.ts",
|
|
22
|
+
"import": "./dist/widget.js"
|
|
23
|
+
}
|
|
14
24
|
},
|
|
15
25
|
"scripts": {
|
|
16
26
|
"build": "tsup",
|
|
@@ -18,14 +28,25 @@
|
|
|
18
28
|
"test:integration": "vitest run test/integration.test.ts",
|
|
19
29
|
"prepublishOnly": "npm run build && npm test"
|
|
20
30
|
},
|
|
21
|
-
"keywords": [
|
|
31
|
+
"keywords": [
|
|
32
|
+
"ethereum",
|
|
33
|
+
"base",
|
|
34
|
+
"arbitrum",
|
|
35
|
+
"options",
|
|
36
|
+
"defi",
|
|
37
|
+
"viem",
|
|
38
|
+
"split",
|
|
39
|
+
"no-liquidation"
|
|
40
|
+
],
|
|
22
41
|
"homepage": "https://split.markets",
|
|
23
42
|
"peerDependencies": {
|
|
24
43
|
"viem": "^2",
|
|
25
44
|
"react": ">=18"
|
|
26
45
|
},
|
|
27
46
|
"peerDependenciesMeta": {
|
|
28
|
-
"react": {
|
|
47
|
+
"react": {
|
|
48
|
+
"optional": true
|
|
49
|
+
}
|
|
29
50
|
},
|
|
30
51
|
"devDependencies": {
|
|
31
52
|
"@types/react": "^19",
|