@solard/sdk 0.2.27 → 0.2.31
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 +21 -6
- package/package.json +2 -2
- package/src/client.trade-fees.test.ts +60 -0
- package/src/client.ts +263 -280
- package/src/default.ts +51 -51
- package/src/export-surface.test.ts +204 -188
- package/src/index.ts +142 -100
- package/src/live.test.ts +108 -15
- package/src/live.ts +468 -307
- package/src/operator-api.architecture.test.ts +45 -44
package/README.md
CHANGED
|
@@ -3,11 +3,26 @@
|
|
|
3
3
|
Public Solard SDK. It intentionally contains no duplicate business logic; it re-exports the supported `@solard/core` API.
|
|
4
4
|
|
|
5
5
|
```ts
|
|
6
|
-
import {
|
|
6
|
+
import { createSolard } from "@solard/sdk";
|
|
7
7
|
|
|
8
|
-
const slrd =
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
const slrd = createSolard();
|
|
9
|
+
await slrd.addToken(mint, undefined, { venueHint: "pumpswap", pool: poolAddress });
|
|
10
|
+
const buy = await slrd.buy(
|
|
11
|
+
{ wallet: "trader-1", token: mint, amount: { sol: 0.001 }, slippageBps: 500 },
|
|
12
|
+
{ intentKey: "example:buy:1", priorityFee: { cuLimit: 600_000, microLamports: 200_000 } },
|
|
13
|
+
);
|
|
14
|
+
if (buy.status === "confirmed") {
|
|
15
|
+
console.log(buy.solPrincipalDeltaLamports, buy.networkFeeLamports, buy.targetTokenDeltaRaw);
|
|
16
|
+
}
|
|
17
|
+
// Sell through the same atomic quote-token -> SOL route.
|
|
18
|
+
// await slrd.sell({ wallet: "trader-1", token: mint, amount: "all", slippageBps: 500 });
|
|
13
19
|
```
|
|
20
|
+
|
|
21
|
+
The trader preset supports Pump/PumpSwap, Meteora DBC and DAMM v2. Custom quote
|
|
22
|
+
routes require a supported SOL market for the quote token and suitable lookup
|
|
23
|
+
tables when needed. Composer routes fall back to Jupiter instructions. Unavailable
|
|
24
|
+
converted prices are null. `unresolved` means reconcile with `resumeTrade(intentKey)`
|
|
25
|
+
before another trade. Buy accepts `minOutputRaw`; sell accepts `minOutputLamports`.
|
|
26
|
+
Both use confirmed/failed/unresolved results with phase, code, attempts and accounting.
|
|
27
|
+
`quote`, `curveLiquidity`, `maxSendableSol`, `transferToken` and `exitWallet` share the
|
|
28
|
+
core implementation. Raydium AMM/CPMM execution does not supply live pool prices.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solard/sdk",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.31",
|
|
4
4
|
"description": "Public Solard SDK for wallets, trading, history, live market subscriptions and token metadata.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"license": "MIT",
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@solana/web3.js": "^1.98.4",
|
|
30
|
-
"@solard/core": "0.2.
|
|
30
|
+
"@solard/core": "0.2.31"
|
|
31
31
|
},
|
|
32
32
|
"scripts": {
|
|
33
33
|
"typecheck": "tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.browser.json",
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { expect, spyOn, test } from "bun:test";
|
|
2
|
+
import { mkdtempSync, rmSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { Keypair } from "@solana/web3.js";
|
|
6
|
+
import { Solard } from "../../core/src/core/solard.ts";
|
|
7
|
+
import { TransactionComposer } from "../../core/src/tx/composer.ts";
|
|
8
|
+
import type { PlannedTransaction, TransactionDraft } from "../../core/src/tx/types.ts";
|
|
9
|
+
import { createSolard } from "./client.ts";
|
|
10
|
+
|
|
11
|
+
test("SDK buy rebuild and sell preserve custom fees in immediate submitted results", async () => {
|
|
12
|
+
const directory = mkdtempSync(join(tmpdir(), "solard-sdk-fees-"));
|
|
13
|
+
const drafts: Array<TransactionDraft> = [];
|
|
14
|
+
// A sentinel plan is never compiled, signed, or broadcast in this test.
|
|
15
|
+
const payer = Keypair.generate();
|
|
16
|
+
const plan = { payer: payer.publicKey } as PlannedTransaction;
|
|
17
|
+
const build = spyOn(TransactionComposer.prototype, "build").mockImplementation(async function (this: TransactionComposer) {
|
|
18
|
+
drafts.push(this.snapshot());
|
|
19
|
+
return { ...plan, draft: this.snapshot() };
|
|
20
|
+
});
|
|
21
|
+
const signer = spyOn(Solard.prototype, "signer").mockImplementation(() => payer);
|
|
22
|
+
const compile = spyOn(Solard.prototype, "compile").mockImplementation(async (_payer, draft) => ({ ...plan, draft }));
|
|
23
|
+
let submissions = 0;
|
|
24
|
+
const submit = spyOn(Solard.prototype, "submitPlan").mockImplementation(async () => {
|
|
25
|
+
submissions += 1;
|
|
26
|
+
if (submissions === 1) {
|
|
27
|
+
throw new Error("Simulation failed: BuySlippageBelowMinBaseAmountOut");
|
|
28
|
+
}
|
|
29
|
+
return { signature: "test-signature", sender: "rpc", executionId: 42, plan };
|
|
30
|
+
});
|
|
31
|
+
const settle = spyOn(Solard.prototype, "settleSubmission").mockImplementation(async () => {
|
|
32
|
+
throw new Error("Immediate submission must not wait for confirmation");
|
|
33
|
+
});
|
|
34
|
+
const sdk = createSolard({ dbPath: join(directory, "test.sqlite") });
|
|
35
|
+
try {
|
|
36
|
+
const options = {
|
|
37
|
+
priorityFee: { cuLimit: 300_000, microLamports: 0 },
|
|
38
|
+
waitForConfirmation: false,
|
|
39
|
+
};
|
|
40
|
+
const buy = await sdk.buy({ token: "token", wallet: "wallet", amount: 0.1 }, options);
|
|
41
|
+
const sell = await sdk.sell({ token: "token", wallet: "wallet" }, options);
|
|
42
|
+
expect(drafts).toHaveLength(3);
|
|
43
|
+
for (const draft of drafts) {
|
|
44
|
+
expect(draft.cuLimit).toBe(300_000);
|
|
45
|
+
expect(draft.cuPriceMicroLamports).toBe(0);
|
|
46
|
+
}
|
|
47
|
+
expect(buy.status).toBe("unresolved");
|
|
48
|
+
expect(sell.status).toBe("unresolved");
|
|
49
|
+
expect(buy.executionId).toBe(42);
|
|
50
|
+
expect(settle).not.toHaveBeenCalled();
|
|
51
|
+
} finally {
|
|
52
|
+
sdk.close();
|
|
53
|
+
build.mockRestore();
|
|
54
|
+
signer.mockRestore();
|
|
55
|
+
compile.mockRestore();
|
|
56
|
+
submit.mockRestore();
|
|
57
|
+
settle.mockRestore();
|
|
58
|
+
rmSync(directory, { recursive: true, force: true });
|
|
59
|
+
}
|
|
60
|
+
});
|