@haven-fi/solauto-sdk 1.0.825 → 1.0.828
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/constants/generalConstants.d.ts +1 -0
- package/dist/constants/generalConstants.d.ts.map +1 -1
- package/dist/constants/generalConstants.js +2 -1
- package/dist/utils/jitoUtils.d.ts.map +1 -1
- package/dist/utils/jitoUtils.js +8 -6
- package/dist/utils/priceUtils.d.ts.map +1 -1
- package/dist/utils/priceUtils.js +17 -14
- package/dist/utils/switchboardUtils.d.ts +2 -1
- package/dist/utils/switchboardUtils.d.ts.map +1 -1
- package/dist/utils/switchboardUtils.js +12 -13
- package/local/txSandbox.ts +18 -2
- package/package.json +3 -3
- package/src/constants/generalConstants.ts +2 -0
- package/src/utils/jitoUtils.ts +10 -6
- package/src/utils/priceUtils.ts +23 -18
- package/src/utils/switchboardUtils.ts +15 -13
|
@@ -4,4 +4,5 @@ export declare const SOLAUTO_FEES_WALLET: PublicKey;
|
|
|
4
4
|
export declare const SOLAUTO_MANAGER: PublicKey;
|
|
5
5
|
export declare const LOCAL_IRONFORGE_API_URL: string;
|
|
6
6
|
export declare const BASIS_POINTS = 10000;
|
|
7
|
+
export declare const CROSSBAR_URL = "https://crossbar.0.xyz/";
|
|
7
8
|
//# sourceMappingURL=generalConstants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generalConstants.d.ts","sourceRoot":"","sources":["../../src/constants/generalConstants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,eAAO,MAAM,YAAY,IAAI,CAAC;AAC9B,eAAO,MAAM,mBAAmB,WAAgE,CAAC;AACjG,eAAO,MAAM,eAAe,WAA+D,CAAC;AAE5F,eAAO,MAAM,uBAAuB,QAAuD,CAAC;AAE5F,eAAO,MAAM,YAAY,QAAQ,CAAC"}
|
|
1
|
+
{"version":3,"file":"generalConstants.d.ts","sourceRoot":"","sources":["../../src/constants/generalConstants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,eAAO,MAAM,YAAY,IAAI,CAAC;AAC9B,eAAO,MAAM,mBAAmB,WAAgE,CAAC;AACjG,eAAO,MAAM,eAAe,WAA+D,CAAC;AAE5F,eAAO,MAAM,uBAAuB,QAAuD,CAAC;AAE5F,eAAO,MAAM,YAAY,QAAQ,CAAC;AAElC,eAAO,MAAM,YAAY,4BAA4B,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.BASIS_POINTS = exports.LOCAL_IRONFORGE_API_URL = exports.SOLAUTO_MANAGER = exports.SOLAUTO_FEES_WALLET = exports.USD_DECIMALS = void 0;
|
|
3
|
+
exports.CROSSBAR_URL = exports.BASIS_POINTS = exports.LOCAL_IRONFORGE_API_URL = exports.SOLAUTO_MANAGER = exports.SOLAUTO_FEES_WALLET = exports.USD_DECIMALS = void 0;
|
|
4
4
|
const web3_js_1 = require("@solana/web3.js");
|
|
5
5
|
const utils_1 = require("../utils");
|
|
6
6
|
exports.USD_DECIMALS = 9;
|
|
@@ -8,3 +8,4 @@ exports.SOLAUTO_FEES_WALLET = new web3_js_1.PublicKey("AprYCPiVeKMCgjQ2ZufwChMzv
|
|
|
8
8
|
exports.SOLAUTO_MANAGER = new web3_js_1.PublicKey("MNGRcX4nc7quPdzBbNKJ4ScK5EE73JnwJVGxuJXhHCY");
|
|
9
9
|
exports.LOCAL_IRONFORGE_API_URL = (0, utils_1.buildIronforgeApiUrl)(process.env.IRONFORGE_API_KEY);
|
|
10
10
|
exports.BASIS_POINTS = 10000;
|
|
11
|
+
exports.CROSSBAR_URL = "https://crossbar.0.xyz/";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jitoUtils.d.ts","sourceRoot":"","sources":["../../src/utils/jitoUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,SAAS,EAIV,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,MAAM,EACN,kBAAkB,EAClB,GAAG,EAEH,kBAAkB,EACnB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAiBlE,wBAAgB,mBAAmB,IAAI,SAAS,CAG/C;AAiGD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,kBAAkB;;;;IAkB/D;
|
|
1
|
+
{"version":3,"file":"jitoUtils.d.ts","sourceRoot":"","sources":["../../src/utils/jitoUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,SAAS,EAIV,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,MAAM,EACN,kBAAkB,EAClB,GAAG,EAEH,kBAAkB,EACnB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAiBlE,wBAAgB,mBAAmB,IAAI,SAAS,CAG/C;AAiGD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,kBAAkB;;;;IAkB/D;AAyHD,wBAAsB,2BAA2B,CAC/C,GAAG,EAAE,GAAG,EACR,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EAAE,EACtB,YAAY,EAAE,kBAAkB,EAAE,EAClC,MAAM,CAAC,EAAE,kBAAkB,EAC3B,kBAAkB,GAAE,kBAA2C,EAC/D,cAAc,CAAC,EAAE,MAAM,IAAI,EAC3B,eAAe,CAAC,EAAE,eAAe,GAChC,OAAO,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,CA6G/B"}
|
package/dist/utils/jitoUtils.js
CHANGED
|
@@ -142,13 +142,14 @@ async function pollBundleStatus(umi, bundleId, interval = 1000, timeout = 40000)
|
|
|
142
142
|
if (statuses?.value?.length > 0) {
|
|
143
143
|
(0, generalUtils_1.consoleLog)("Statuses:", statuses);
|
|
144
144
|
const status = statuses.value[0].confirmation_status;
|
|
145
|
-
if (status === "confirmed") {
|
|
145
|
+
if (status === "confirmed" || status === "finalized") {
|
|
146
146
|
return statuses.value[0].transactions;
|
|
147
147
|
}
|
|
148
148
|
const err = statuses.value[0].err;
|
|
149
|
-
|
|
149
|
+
// Jito reports a successful bundle as err: { Ok: null }
|
|
150
|
+
if (err && !("Ok" in err && err.Ok === null)) {
|
|
150
151
|
(0, generalUtils_1.consoleLog)("Jito bundle err:", JSON.stringify(err, null, 2));
|
|
151
|
-
throw new Error(err);
|
|
152
|
+
throw new Error(JSON.stringify(err));
|
|
152
153
|
}
|
|
153
154
|
}
|
|
154
155
|
}
|
|
@@ -168,11 +169,12 @@ async function sendJitoBundle(umi, transactions) {
|
|
|
168
169
|
throw e;
|
|
169
170
|
}
|
|
170
171
|
}
|
|
171
|
-
if (resp.error?.
|
|
172
|
-
|
|
172
|
+
if (resp.error?.responses?.length) {
|
|
173
|
+
const inner = resp.error.responses[0].response?.error;
|
|
174
|
+
throw new Error(`${resp.error.message}: ${inner ? (inner.message ?? JSON.stringify(inner)) : "unknown"}`);
|
|
173
175
|
}
|
|
174
176
|
else if (resp.error) {
|
|
175
|
-
throw new Error(resp.error);
|
|
177
|
+
throw new Error(resp.error.message ?? JSON.stringify(resp.error));
|
|
176
178
|
}
|
|
177
179
|
const bundleId = resp;
|
|
178
180
|
(0, generalUtils_1.consoleLog)("Bundle ID:", bundleId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"priceUtils.d.ts","sourceRoot":"","sources":["../../src/utils/priceUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,SAAS,IAAI,YAAY,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"priceUtils.d.ts","sourceRoot":"","sources":["../../src/utils/priceUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,SAAS,IAAI,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAiBrE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,UAAU,WAAW;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,SAAS,EAAE,EAClB,SAAS,GAAE,SAA8B,EACzC,SAAS,CAAC,EAAE,SAAS,GACpB,OAAO,CAAC,MAAM,EAAE,CAAC,CA8CnB;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,SAAS,EAAE,GACjB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAuDtC;AAkBD,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,SAAS,EAAE,GACjB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAsDtC;AAED,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,SAAS,EAAE,GACjB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAsBtC;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,SAAS,GAAG,YAAY,GAAG,MAAM,GAAG,SAAS,EACnD,SAAS,GAAE,SAA8B,EACzC,SAAS,CAAC,EAAE,SAAS,GACpB,MAAM,GAAG,SAAS,CAyBpB"}
|
package/dist/utils/priceUtils.js
CHANGED
|
@@ -128,26 +128,29 @@ async function getSwitchboardPrices(mints) {
|
|
|
128
128
|
return {};
|
|
129
129
|
}
|
|
130
130
|
const { CrossbarClient } = SwbCommon;
|
|
131
|
-
const crossbar = new CrossbarClient(
|
|
131
|
+
const crossbar = new CrossbarClient(constants_1.CROSSBAR_URL);
|
|
132
132
|
let prices = {};
|
|
133
133
|
try {
|
|
134
134
|
prices = await (0, generalUtils_1.retryWithExponentialBackoff)(async () => {
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
135
|
+
const mintByFeed = new Map(mints.map((mint) => [
|
|
136
|
+
constants_1.SWITCHBOARD_PRICE_FEED_IDS[mint.toString()].feedId,
|
|
137
|
+
mint.toString(),
|
|
138
|
+
]));
|
|
139
|
+
const resp = await crossbar.simulateSolanaFeeds("mainnet", Array.from(mintByFeed.keys()));
|
|
141
140
|
const finalMap = {};
|
|
142
141
|
for (const item of resp) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
142
|
+
const mint = mintByFeed.get(item.feed);
|
|
143
|
+
// Crossbar currently returns the aggregate as `result`; retain `results[0]` for
|
|
144
|
+
// compatibility with the published SDK response type.
|
|
145
|
+
const result = "result" in item ? item.result : item.results[0];
|
|
146
|
+
const price = Number(result);
|
|
147
|
+
if (!mint || !Number.isFinite(price) || price <= 0) {
|
|
148
|
+
throw new Error("Unable to fetch Switchboard prices");
|
|
150
149
|
}
|
|
150
|
+
finalMap[mint] = { realtimePrice: price };
|
|
151
|
+
}
|
|
152
|
+
if (Object.keys(finalMap).length !== mintByFeed.size) {
|
|
153
|
+
throw new Error("Unable to fetch all Switchboard prices");
|
|
151
154
|
}
|
|
152
155
|
return finalMap;
|
|
153
156
|
}, 2, 350);
|
|
@@ -2,9 +2,10 @@ import { Connection, PublicKey } from "@solana/web3.js";
|
|
|
2
2
|
import { Signer } from "@metaplex-foundation/umi";
|
|
3
3
|
import * as OnDemand from "@switchboard-xyz/on-demand";
|
|
4
4
|
import { TransactionItemInputs } from "../types";
|
|
5
|
+
import { CrossbarClient } from "@switchboard-xyz/common";
|
|
5
6
|
import { SolautoClient, TransactionItem } from "../services";
|
|
6
7
|
export declare function getPullFeed(conn: Connection, mint: PublicKey, wallet?: PublicKey): Promise<{
|
|
7
|
-
|
|
8
|
+
crossbar: CrossbarClient;
|
|
8
9
|
feed: OnDemand.PullFeed;
|
|
9
10
|
}>;
|
|
10
11
|
export declare function buildSwbSubmitResponseTx(conn: Connection, signer: Signer, mint: PublicKey): Promise<TransactionItemInputs | undefined>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"switchboardUtils.d.ts","sourceRoot":"","sources":["../../src/utils/switchboardUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,SAAS,EAGV,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,MAAM,EAAsB,MAAM,0BAA0B,CAAC;AAGtE,OAAO,KAAK,QAAQ,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"switchboardUtils.d.ts","sourceRoot":"","sources":["../../src/utils/switchboardUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,SAAS,EAGV,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,MAAM,EAAsB,MAAM,0BAA0B,CAAC;AAGtE,OAAO,KAAK,QAAQ,MAAM,4BAA4B,CAAC;AAQvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAOjD,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE7D,wBAAsB,WAAW,CAC/B,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,SAAS,EACf,MAAM,CAAC,EAAE,SAAS;;;GAgCnB;AAED,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,SAAS,GACd,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC,CAyE5C;AAED,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,SAAS,EAAE,GACjB,OAAO,CAAC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,EAAE,CAAC,CAuB/D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,WAEzD;AAED,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,aAAa,EACrB,GAAG,EAAE,eAAe,EAAE,iBAkCvB"}
|
|
@@ -56,26 +56,22 @@ async function getPullFeed(conn, mint, wallet) {
|
|
|
56
56
|
};
|
|
57
57
|
const provider = new anchor_1.AnchorProvider(conn, dummyWallet, anchor_1.AnchorProvider.defaultOptions());
|
|
58
58
|
(0, generalUtils_1.consoleLog)("Pulling SWB program...");
|
|
59
|
-
const { PullFeed,
|
|
59
|
+
const { PullFeed, ON_DEMAND_MAINNET_PID } = OnDemand;
|
|
60
60
|
const sbProgram = await anchor_1.Program.at(ON_DEMAND_MAINNET_PID, provider);
|
|
61
|
-
const crossbar = new common_1.CrossbarClient(
|
|
62
|
-
const queue = await Queue.loadDefault(sbProgram);
|
|
63
|
-
const gateway = await queue.fetchGatewayFromCrossbar(crossbar);
|
|
61
|
+
const crossbar = new common_1.CrossbarClient(constants_1.CROSSBAR_URL);
|
|
64
62
|
(0, generalUtils_1.consoleLog)("Pulled SWB program!");
|
|
65
63
|
(0, generalUtils_1.consoleLog)("Feed id:", constants_1.SWITCHBOARD_PRICE_FEED_IDS[mint.toString()].feedId);
|
|
66
64
|
return {
|
|
67
|
-
|
|
65
|
+
crossbar,
|
|
68
66
|
feed: new PullFeed(sbProgram, new web3_js_1.PublicKey(constants_1.SWITCHBOARD_PRICE_FEED_IDS[mint.toString()].feedId)),
|
|
69
67
|
};
|
|
70
68
|
}
|
|
71
69
|
async function buildSwbSubmitResponseTx(conn, signer, mint) {
|
|
72
|
-
const { feed,
|
|
70
|
+
const { feed, crossbar } = await getPullFeed(conn, mint, (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(signer.publicKey));
|
|
73
71
|
(0, generalUtils_1.consoleLog)("Fetching crank IX...");
|
|
74
|
-
const [pullIxs, responses] = await (0, generalUtils_1.retryWithExponentialBackoff)(async () => {
|
|
72
|
+
const [pullIxs, responses, , luts] = await (0, generalUtils_1.retryWithExponentialBackoff)(async () => {
|
|
75
73
|
const res = await feed.fetchUpdateIx({
|
|
76
|
-
|
|
77
|
-
chain: "solana",
|
|
78
|
-
network: "mainnet-beta",
|
|
74
|
+
crossbarClient: crossbar,
|
|
79
75
|
});
|
|
80
76
|
if (!res[1] || !res[1][0].value) {
|
|
81
77
|
throw new Error("Unable to fetch Switchboard pull IX");
|
|
@@ -113,9 +109,12 @@ async function buildSwbSubmitResponseTx(conn, signer, mint) {
|
|
|
113
109
|
(0, generalUtils_1.consoleLog)("Returning SWB transaction data...");
|
|
114
110
|
return {
|
|
115
111
|
tx: (0, umi_1.transactionBuilder)(pullIxs.map((x) => (0, solanaUtils_1.getWrappedInstruction)(signer, x))),
|
|
116
|
-
lookupTableAddresses:
|
|
117
|
-
.
|
|
118
|
-
|
|
112
|
+
lookupTableAddresses: Array.from(new Set([
|
|
113
|
+
...luts.map((x) => x.key.toString()),
|
|
114
|
+
...responses
|
|
115
|
+
.filter((x) => Boolean(x.oracle.lut?.key))
|
|
116
|
+
.map((x) => x.oracle.lut.key.toString()),
|
|
117
|
+
])),
|
|
119
118
|
orderPrio: -2,
|
|
120
119
|
};
|
|
121
120
|
}
|
package/local/txSandbox.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Keypair, PublicKey } from "@solana/web3.js";
|
|
2
|
+
import { NATIVE_MINT } from "@solana/spl-token";
|
|
2
3
|
import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi";
|
|
3
4
|
import { fromWeb3JsKeypair } from "@metaplex-foundation/umi-web3js-adapters";
|
|
4
5
|
import {
|
|
@@ -118,6 +119,20 @@ async function refreshAll() {
|
|
|
118
119
|
}
|
|
119
120
|
}
|
|
120
121
|
|
|
122
|
+
// Crank a Switchboard pull feed for a single mint, as one standalone tx (no bundle).
|
|
123
|
+
// Usage: npx ts-node local/txSandbox.ts [mint]
|
|
124
|
+
// mint defaults to SOL; accepts a raw mint address or a shorthand below.
|
|
125
|
+
const MINT_SHORTHANDS: Record<string, string> = {
|
|
126
|
+
sol: NATIVE_MINT.toString(),
|
|
127
|
+
jitosol: JITO_SOL,
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
function resolveMint(arg?: string): PublicKey {
|
|
131
|
+
if (!arg) return NATIVE_MINT;
|
|
132
|
+
const shorthand = MINT_SHORTHANDS[arg.toLowerCase()];
|
|
133
|
+
return new PublicKey(shorthand ?? arg);
|
|
134
|
+
}
|
|
135
|
+
|
|
121
136
|
async function testSwbOracleUpdate() {
|
|
122
137
|
(globalThis as any).SHOW_LOGS = true;
|
|
123
138
|
|
|
@@ -128,8 +143,8 @@ async function testSwbOracleUpdate() {
|
|
|
128
143
|
);
|
|
129
144
|
umiLocal = umiLocal.use(signerIdentity(signer));
|
|
130
145
|
|
|
131
|
-
const mint =
|
|
132
|
-
console.log("Building SWB oracle update tx for
|
|
146
|
+
const mint = resolveMint(process.argv[2]);
|
|
147
|
+
console.log("Building SWB oracle update tx for mint:", mint.toString());
|
|
133
148
|
|
|
134
149
|
const result = await buildSwbSubmitResponseTx(conn, signer, mint);
|
|
135
150
|
if (!result) {
|
|
@@ -139,6 +154,7 @@ async function testSwbOracleUpdate() {
|
|
|
139
154
|
|
|
140
155
|
console.log("Instructions count:", result.tx.getInstructions().length);
|
|
141
156
|
console.log("Lookup tables:", result.lookupTableAddresses);
|
|
157
|
+
console.log("Transaction size:", result.tx.getTransactionSize(umiLocal));
|
|
142
158
|
|
|
143
159
|
console.log("Sending transaction...");
|
|
144
160
|
const sig = await sendSingleOptimizedTransaction(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haven-fi/solauto-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.828",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"description": "Typescript SDK for the Solauto program on the Solana blockchain",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"@metaplex-foundation/umi-web3js-adapters": "^0.9.1",
|
|
21
21
|
"@solana/spl-token": "^0.4.0",
|
|
22
22
|
"@solana/web3.js": "=1.98.2",
|
|
23
|
-
"@switchboard-xyz/common": "=
|
|
24
|
-
"@switchboard-xyz/on-demand": "=
|
|
23
|
+
"@switchboard-xyz/common": "=5.8.5",
|
|
24
|
+
"@switchboard-xyz/on-demand": "=3.10.6",
|
|
25
25
|
"axios": "^1.7.8",
|
|
26
26
|
"big.js": "^6.2.2",
|
|
27
27
|
"bs58": "^5.0.0",
|
|
@@ -8,3 +8,5 @@ export const SOLAUTO_MANAGER = new PublicKey("MNGRcX4nc7quPdzBbNKJ4ScK5EE73JnwJV
|
|
|
8
8
|
export const LOCAL_IRONFORGE_API_URL = buildIronforgeApiUrl(process.env.IRONFORGE_API_KEY!);
|
|
9
9
|
|
|
10
10
|
export const BASIS_POINTS = 10000;
|
|
11
|
+
|
|
12
|
+
export const CROSSBAR_URL = "https://crossbar.0.xyz/";
|
package/src/utils/jitoUtils.ts
CHANGED
|
@@ -224,13 +224,14 @@ async function pollBundleStatus(
|
|
|
224
224
|
if (statuses?.value?.length > 0) {
|
|
225
225
|
consoleLog("Statuses:", statuses);
|
|
226
226
|
const status = statuses.value[0].confirmation_status;
|
|
227
|
-
if (status === "confirmed") {
|
|
227
|
+
if (status === "confirmed" || status === "finalized") {
|
|
228
228
|
return statuses.value[0].transactions as string[];
|
|
229
229
|
}
|
|
230
230
|
const err = statuses.value[0].err;
|
|
231
|
-
|
|
231
|
+
// Jito reports a successful bundle as err: { Ok: null }
|
|
232
|
+
if (err && !("Ok" in err && err.Ok === null)) {
|
|
232
233
|
consoleLog("Jito bundle err:", JSON.stringify(err, null, 2));
|
|
233
|
-
throw new Error(err);
|
|
234
|
+
throw new Error(JSON.stringify(err));
|
|
234
235
|
}
|
|
235
236
|
}
|
|
236
237
|
}
|
|
@@ -255,10 +256,13 @@ async function sendJitoBundle(
|
|
|
255
256
|
}
|
|
256
257
|
}
|
|
257
258
|
|
|
258
|
-
if (resp.error?.
|
|
259
|
-
|
|
259
|
+
if (resp.error?.responses?.length) {
|
|
260
|
+
const inner = resp.error.responses[0].response?.error;
|
|
261
|
+
throw new Error(
|
|
262
|
+
`${resp.error.message}: ${inner ? (inner.message ?? JSON.stringify(inner)) : "unknown"}`
|
|
263
|
+
);
|
|
260
264
|
} else if (resp.error) {
|
|
261
|
-
throw new Error(resp.error);
|
|
265
|
+
throw new Error(resp.error.message ?? JSON.stringify(resp.error));
|
|
262
266
|
}
|
|
263
267
|
|
|
264
268
|
const bundleId = resp as string;
|
package/src/utils/priceUtils.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { PublicKey } from "@solana/web3.js";
|
|
|
2
2
|
import { PublicKey as UmiPublicKey } from "@metaplex-foundation/umi";
|
|
3
3
|
import * as SwbCommon from "@switchboard-xyz/common";
|
|
4
4
|
import {
|
|
5
|
+
CROSSBAR_URL,
|
|
5
6
|
PYTH_PRICE_FEED_IDS,
|
|
6
7
|
PRICES,
|
|
7
8
|
SWITCHBOARD_PRICE_FEED_IDS,
|
|
@@ -160,34 +161,38 @@ export async function getSwitchboardPrices(
|
|
|
160
161
|
}
|
|
161
162
|
|
|
162
163
|
const { CrossbarClient } = SwbCommon;
|
|
163
|
-
const crossbar = new CrossbarClient(
|
|
164
|
+
const crossbar = new CrossbarClient(CROSSBAR_URL);
|
|
164
165
|
|
|
165
166
|
let prices: Record<string, PriceResult> = {};
|
|
166
167
|
try {
|
|
167
168
|
prices = await retryWithExponentialBackoff(
|
|
168
169
|
async () => {
|
|
169
|
-
const
|
|
170
|
-
mints.map((
|
|
170
|
+
const mintByFeed = new Map(
|
|
171
|
+
mints.map((mint) => [
|
|
172
|
+
SWITCHBOARD_PRICE_FEED_IDS[mint.toString()].feedId,
|
|
173
|
+
mint.toString(),
|
|
174
|
+
])
|
|
175
|
+
);
|
|
176
|
+
const resp = await crossbar.simulateSolanaFeeds(
|
|
177
|
+
"mainnet",
|
|
178
|
+
Array.from(mintByFeed.keys())
|
|
171
179
|
);
|
|
172
|
-
|
|
173
|
-
const data = resp.flatMap((x) => x.results[0]);
|
|
174
|
-
if (
|
|
175
|
-
data.filter((x) => !x || isNaN(Number(x)) || Number(x) <= 0).length >
|
|
176
|
-
0
|
|
177
|
-
) {
|
|
178
|
-
throw new Error("Unable to fetch Switchboard prices");
|
|
179
|
-
}
|
|
180
180
|
|
|
181
181
|
const finalMap: Record<string, PriceResult> = {};
|
|
182
182
|
for (const item of resp) {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
183
|
+
const mint = mintByFeed.get(item.feed);
|
|
184
|
+
// Crossbar currently returns the aggregate as `result`; retain `results[0]` for
|
|
185
|
+
// compatibility with the published SDK response type.
|
|
186
|
+
const result = "result" in item ? item.result : item.results[0];
|
|
187
|
+
const price = Number(result);
|
|
188
|
+
if (!mint || !Number.isFinite(price) || price <= 0) {
|
|
189
|
+
throw new Error("Unable to fetch Switchboard prices");
|
|
190
190
|
}
|
|
191
|
+
finalMap[mint] = { realtimePrice: price };
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (Object.keys(finalMap).length !== mintByFeed.size) {
|
|
195
|
+
throw new Error("Unable to fetch all Switchboard prices");
|
|
191
196
|
}
|
|
192
197
|
return finalMap;
|
|
193
198
|
},
|
|
@@ -10,6 +10,7 @@ import { AnchorProvider, Idl, Program } from "@coral-xyz/anchor";
|
|
|
10
10
|
import * as OnDemand from "@switchboard-xyz/on-demand";
|
|
11
11
|
import Big from "big.js";
|
|
12
12
|
import {
|
|
13
|
+
CROSSBAR_URL,
|
|
13
14
|
PRICES,
|
|
14
15
|
SWITCHBOARD_PRICE_FEED_IDS,
|
|
15
16
|
UPDATE_ORACLE_TX_NAME,
|
|
@@ -45,17 +46,15 @@ export async function getPullFeed(
|
|
|
45
46
|
);
|
|
46
47
|
|
|
47
48
|
consoleLog("Pulling SWB program...");
|
|
48
|
-
const { PullFeed,
|
|
49
|
+
const { PullFeed, ON_DEMAND_MAINNET_PID } = OnDemand;
|
|
49
50
|
const sbProgram = await Program.at(ON_DEMAND_MAINNET_PID, provider);
|
|
50
51
|
|
|
51
|
-
const crossbar = new CrossbarClient(
|
|
52
|
-
const queue = await Queue.loadDefault(sbProgram);
|
|
53
|
-
const gateway = await queue.fetchGatewayFromCrossbar(crossbar as any);
|
|
52
|
+
const crossbar = new CrossbarClient(CROSSBAR_URL);
|
|
54
53
|
|
|
55
54
|
consoleLog("Pulled SWB program!");
|
|
56
55
|
consoleLog("Feed id:", SWITCHBOARD_PRICE_FEED_IDS[mint.toString()].feedId);
|
|
57
56
|
return {
|
|
58
|
-
|
|
57
|
+
crossbar,
|
|
59
58
|
feed: new PullFeed(
|
|
60
59
|
sbProgram,
|
|
61
60
|
new PublicKey(SWITCHBOARD_PRICE_FEED_IDS[mint.toString()].feedId)
|
|
@@ -68,19 +67,17 @@ export async function buildSwbSubmitResponseTx(
|
|
|
68
67
|
signer: Signer,
|
|
69
68
|
mint: PublicKey
|
|
70
69
|
): Promise<TransactionItemInputs | undefined> {
|
|
71
|
-
const { feed,
|
|
70
|
+
const { feed, crossbar } = await getPullFeed(
|
|
72
71
|
conn,
|
|
73
72
|
mint,
|
|
74
73
|
toWeb3JsPublicKey(signer.publicKey)
|
|
75
74
|
);
|
|
76
75
|
|
|
77
76
|
consoleLog("Fetching crank IX...");
|
|
78
|
-
const [pullIxs, responses] = await retryWithExponentialBackoff(
|
|
77
|
+
const [pullIxs, responses, , luts] = await retryWithExponentialBackoff(
|
|
79
78
|
async () => {
|
|
80
79
|
const res = await feed.fetchUpdateIx({
|
|
81
|
-
|
|
82
|
-
chain: "solana",
|
|
83
|
-
network: "mainnet-beta",
|
|
80
|
+
crossbarClient: crossbar,
|
|
84
81
|
});
|
|
85
82
|
if (!res[1] || !res[1][0].value) {
|
|
86
83
|
throw new Error("Unable to fetch Switchboard pull IX");
|
|
@@ -132,9 +129,14 @@ export async function buildSwbSubmitResponseTx(
|
|
|
132
129
|
tx: transactionBuilder(
|
|
133
130
|
pullIxs.map((x) => getWrappedInstruction(signer, x))
|
|
134
131
|
),
|
|
135
|
-
lookupTableAddresses:
|
|
136
|
-
|
|
137
|
-
|
|
132
|
+
lookupTableAddresses: Array.from(
|
|
133
|
+
new Set([
|
|
134
|
+
...luts.map((x) => x.key.toString()),
|
|
135
|
+
...responses
|
|
136
|
+
.filter((x) => Boolean(x.oracle.lut?.key))
|
|
137
|
+
.map((x) => x.oracle.lut!.key.toString()),
|
|
138
|
+
])
|
|
139
|
+
),
|
|
138
140
|
orderPrio: -2,
|
|
139
141
|
};
|
|
140
142
|
}
|