stellar-agent-kit 1.0.0 → 1.0.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 +75 -0
- package/dist/index.cjs +352 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +164 -27
- package/dist/index.d.ts +164 -27
- package/dist/index.js +355 -37
- package/dist/index.js.map +1 -1
- package/package.json +58 -57
package/README.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# stellar-agent-kit
|
|
2
|
+
|
|
3
|
+
Unified TypeScript SDK for Stellar: payments, DEX (SoroSwap), lending (Blend), and oracles. AgentKit-style API: one class, `initialize()`, then protocol methods.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install stellar-agent-kit
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { StellarAgentKit, MAINNET_ASSETS } from "stellar-agent-kit";
|
|
15
|
+
|
|
16
|
+
const agent = new StellarAgentKit(process.env.SECRET_KEY!, "mainnet");
|
|
17
|
+
await agent.initialize();
|
|
18
|
+
|
|
19
|
+
// Balances
|
|
20
|
+
const balances = await agent.getBalances();
|
|
21
|
+
|
|
22
|
+
// Send XLM
|
|
23
|
+
await agent.sendPayment("G...", "10");
|
|
24
|
+
|
|
25
|
+
// DEX quote + swap
|
|
26
|
+
const quote = await agent.dexGetQuote(
|
|
27
|
+
{ contractId: MAINNET_ASSETS.XLM.contractId },
|
|
28
|
+
{ contractId: MAINNET_ASSETS.USDC.contractId },
|
|
29
|
+
"10000000" // 1 XLM (7 decimals)
|
|
30
|
+
);
|
|
31
|
+
await agent.dexSwap(quote);
|
|
32
|
+
|
|
33
|
+
// Path payment (strict receive)
|
|
34
|
+
await agent.pathPayment(
|
|
35
|
+
{ assetCode: "XLM" },
|
|
36
|
+
"10",
|
|
37
|
+
"G...",
|
|
38
|
+
{ assetCode: "USDC", issuer: "G..." },
|
|
39
|
+
"5",
|
|
40
|
+
[]
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
// Create account
|
|
44
|
+
await agent.createAccount("G...", "1");
|
|
45
|
+
|
|
46
|
+
// Price (Reflector oracle)
|
|
47
|
+
const price = await agent.getPrice({ symbol: "XLM" });
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## API overview
|
|
51
|
+
|
|
52
|
+
| Method | Description |
|
|
53
|
+
|--------|-------------|
|
|
54
|
+
| `initialize()` | Must be called once after construction. Sets up Horizon, DEX, oracle. |
|
|
55
|
+
| `getBalances(accountId?)` | Native + trustline balances for an account (default: this key). |
|
|
56
|
+
| `sendPayment(to, amount, assetCode?, assetIssuer?)` | Send a payment (XLM or custom asset). |
|
|
57
|
+
| `createAccount(destination, startingBalance)` | Create a new account (funded from this key). |
|
|
58
|
+
| `pathPayment(sendAsset, sendMax, destination, destAsset, destAmount, path?)` | Path payment strict receive. |
|
|
59
|
+
| `dexGetQuote(from, to, amount)` | Get swap quote (SoroSwap aggregator). |
|
|
60
|
+
| `dexSwap(quote)` | Execute a swap from a quote. |
|
|
61
|
+
| `dexSwapExactIn(from, to, amount)` | Get quote and execute in one call. |
|
|
62
|
+
| `getPrice(asset)` | Latest price from Reflector oracle. |
|
|
63
|
+
| `lendingSupply(args)` | Supply to a Blend pool. |
|
|
64
|
+
| `lendingBorrow(args)` | Borrow from a Blend pool. |
|
|
65
|
+
|
|
66
|
+
## Network
|
|
67
|
+
|
|
68
|
+
Currently **mainnet only**. Set `SECRET_KEY` and optionally `SOROSWAP_API_KEY` (for DEX quotes) in your environment.
|
|
69
|
+
|
|
70
|
+
## Exports
|
|
71
|
+
|
|
72
|
+
- `StellarAgentKit`, `StellarNetwork`
|
|
73
|
+
- `getNetworkConfig`, `networks`, `MAINNET_ASSETS`, `SOROSWAP_AGGREGATOR`
|
|
74
|
+
- `createDexClient`, `createReflectorOracle`, `lendingSupply`, `lendingBorrow`
|
|
75
|
+
- Types: `DexAsset`, `QuoteResult`, `SwapResult`, `OracleAsset`, `PriceData`, `LendingSupplyArgs`, etc.
|
package/dist/index.cjs
CHANGED
|
@@ -20,18 +20,26 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
ALLBRIDGE_CORE_STELLAR_DOCS: () => ALLBRIDGE_CORE_STELLAR_DOCS,
|
|
24
|
+
BAND_ORACLE: () => BAND_ORACLE,
|
|
25
|
+
BLEND_POOLS: () => BLEND_POOLS,
|
|
26
|
+
BLEND_POOLS_MAINNET: () => BLEND_POOLS_MAINNET,
|
|
27
|
+
FXDAO_MAINNET: () => FXDAO_MAINNET,
|
|
23
28
|
MAINNET_ASSETS: () => MAINNET_ASSETS,
|
|
29
|
+
REFLECTOR_ORACLE: () => REFLECTOR_ORACLE,
|
|
24
30
|
SOROSWAP_AGGREGATOR: () => SOROSWAP_AGGREGATOR,
|
|
25
31
|
StellarAgentKit: () => StellarAgentKit,
|
|
26
|
-
TESTNET_ASSETS: () => TESTNET_ASSETS,
|
|
27
32
|
createDexClient: () => createDexClient,
|
|
33
|
+
createReflectorOracle: () => createReflectorOracle,
|
|
28
34
|
getNetworkConfig: () => getNetworkConfig,
|
|
35
|
+
lendingBorrow: () => lendingBorrow,
|
|
36
|
+
lendingSupply: () => lendingSupply,
|
|
29
37
|
networks: () => networks
|
|
30
38
|
});
|
|
31
39
|
module.exports = __toCommonJS(index_exports);
|
|
32
40
|
|
|
33
41
|
// src/agent.ts
|
|
34
|
-
var
|
|
42
|
+
var import_stellar_sdk5 = require("@stellar/stellar-sdk");
|
|
35
43
|
|
|
36
44
|
// src/config/networks.ts
|
|
37
45
|
var import_zod = require("zod");
|
|
@@ -40,20 +48,16 @@ var NetworkConfigSchema = import_zod.z.object({
|
|
|
40
48
|
sorobanRpcUrl: import_zod.z.string().url(),
|
|
41
49
|
friendbotUrl: import_zod.z.string().url().optional()
|
|
42
50
|
});
|
|
43
|
-
var testnet = {
|
|
44
|
-
horizonUrl: "https://horizon-testnet.stellar.org",
|
|
45
|
-
sorobanRpcUrl: "https://soroban-testnet.stellar.org",
|
|
46
|
-
friendbotUrl: "https://friendbot.stellar.org"
|
|
47
|
-
};
|
|
48
51
|
var mainnet = {
|
|
49
52
|
horizonUrl: "https://horizon.stellar.org",
|
|
50
53
|
sorobanRpcUrl: "https://soroban-rpc.mainnet.stellar.gateway.fm"
|
|
51
54
|
};
|
|
52
|
-
var networks = {
|
|
55
|
+
var networks = { mainnet };
|
|
53
56
|
function getNetworkConfig(name) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
+
if (name && name !== "mainnet") {
|
|
58
|
+
throw new Error("This project is mainnet-only. Use network: 'mainnet'.");
|
|
59
|
+
}
|
|
60
|
+
return mainnet;
|
|
57
61
|
}
|
|
58
62
|
|
|
59
63
|
// src/dex/soroSwap.ts
|
|
@@ -76,10 +80,9 @@ function parseApiQuote(data) {
|
|
|
76
80
|
};
|
|
77
81
|
}
|
|
78
82
|
function createSoroSwapDexClient(networkConfig, apiKey) {
|
|
79
|
-
const networkName = networkConfig.horizonUrl.includes("testnet") ? "testnet" : "mainnet";
|
|
80
83
|
const key = apiKey ?? process.env.SOROSWAP_API_KEY;
|
|
81
84
|
async function getQuote(from, to, amount) {
|
|
82
|
-
const url = `${SOROSWAP_API_BASE}/quote?network
|
|
85
|
+
const url = `${SOROSWAP_API_BASE}/quote?network=mainnet`;
|
|
83
86
|
const body = {
|
|
84
87
|
assetIn: assetToApiString(from),
|
|
85
88
|
assetOut: assetToApiString(to),
|
|
@@ -100,7 +103,7 @@ function createSoroSwapDexClient(networkConfig, apiKey) {
|
|
|
100
103
|
if (!key) throw new Error("executeSwap requires SOROSWAP_API_KEY");
|
|
101
104
|
const keypair = import_stellar_sdk.Keypair.fromSecret(secretKey.trim());
|
|
102
105
|
const fromAddress = keypair.publicKey();
|
|
103
|
-
const buildUrl = `${SOROSWAP_API_BASE}/quote/build?network
|
|
106
|
+
const buildUrl = `${SOROSWAP_API_BASE}/quote/build?network=mainnet`;
|
|
104
107
|
const buildRes = await fetch(buildUrl, {
|
|
105
108
|
method: "POST",
|
|
106
109
|
headers: { "Content-Type": "application/json", Authorization: `Bearer ${key}` },
|
|
@@ -110,8 +113,8 @@ function createSoroSwapDexClient(networkConfig, apiKey) {
|
|
|
110
113
|
const buildData = await buildRes.json();
|
|
111
114
|
const xdrBase64 = buildData?.xdr;
|
|
112
115
|
if (!xdrBase64 || typeof xdrBase64 !== "string") throw new Error("SoroSwap build response missing xdr");
|
|
113
|
-
const config = getNetworkConfig(
|
|
114
|
-
const networkPassphrase =
|
|
116
|
+
const config = getNetworkConfig("mainnet");
|
|
117
|
+
const networkPassphrase = import_stellar_sdk.Networks.PUBLIC;
|
|
115
118
|
const tx = import_stellar_sdk.TransactionBuilder.fromXDR(xdrBase64, networkPassphrase);
|
|
116
119
|
tx.sign(keypair);
|
|
117
120
|
const server = new import_stellar_sdk2.rpc.Server(config.sorobanRpcUrl, { allowHttp: config.sorobanRpcUrl.startsWith("http:") });
|
|
@@ -127,6 +130,206 @@ function createDexClient(networkConfig, apiKey) {
|
|
|
127
130
|
return createSoroSwapDexClient(networkConfig, apiKey);
|
|
128
131
|
}
|
|
129
132
|
|
|
133
|
+
// src/oracle/reflector.ts
|
|
134
|
+
var import_stellar_sdk3 = require("@stellar/stellar-sdk");
|
|
135
|
+
|
|
136
|
+
// src/config/oracles.ts
|
|
137
|
+
var REFLECTOR_ORACLE = {
|
|
138
|
+
/** Stellar Mainnet DEX prices */
|
|
139
|
+
dex: "CALI2BYU2JE6WVRUFYTS6MSBNEHGJ35P4AVCZYF3B6QOE3QKOB2PLE6M",
|
|
140
|
+
/** External CEX & DEX rates */
|
|
141
|
+
cexDex: "CAFJZQWSED6YAWZU3GWRTOCNPPCGBN32L7QV43XX5LZLFTK6JLN34DLN",
|
|
142
|
+
/** Fiat exchange rates */
|
|
143
|
+
fiat: "CBKGPWGKSKZF52CFHMTRR23TBWTPMRDIYZ4O2P5VS65BMHYH4DXMCJZC"
|
|
144
|
+
};
|
|
145
|
+
var BAND_ORACLE = "CCQXWMZVM3KRTXTUPTN53YHL272QGKF32L7XEDNZ2S6OSUFK3NFBGG5M";
|
|
146
|
+
|
|
147
|
+
// src/oracle/reflector.ts
|
|
148
|
+
var SIMULATION_SOURCE_MAINNET = "GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN";
|
|
149
|
+
function assetToScVal(asset) {
|
|
150
|
+
if ("contractId" in asset && asset.contractId) {
|
|
151
|
+
const addr = new import_stellar_sdk3.Address(asset.contractId);
|
|
152
|
+
return import_stellar_sdk3.xdr.ScVal.scvVec([
|
|
153
|
+
import_stellar_sdk3.xdr.ScVal.scvSymbol("Stellar"),
|
|
154
|
+
import_stellar_sdk3.xdr.ScVal.scvAddress(addr.toScAddress())
|
|
155
|
+
]);
|
|
156
|
+
}
|
|
157
|
+
if ("symbol" in asset && asset.symbol) {
|
|
158
|
+
return import_stellar_sdk3.xdr.ScVal.scvVec([
|
|
159
|
+
import_stellar_sdk3.xdr.ScVal.scvSymbol("Other"),
|
|
160
|
+
import_stellar_sdk3.xdr.ScVal.scvSymbol(asset.symbol)
|
|
161
|
+
]);
|
|
162
|
+
}
|
|
163
|
+
throw new Error("Oracle asset must be { contractId } or { symbol }");
|
|
164
|
+
}
|
|
165
|
+
function parseLastPriceRetval(retvalInput, decimals) {
|
|
166
|
+
const retval = typeof retvalInput === "string" ? import_stellar_sdk3.xdr.ScVal.fromXDR(retvalInput, "base64") : retvalInput;
|
|
167
|
+
const vec = retval.vec();
|
|
168
|
+
if (!vec || vec.length === 0) {
|
|
169
|
+
throw new Error("Oracle returned no price (None) for this asset");
|
|
170
|
+
}
|
|
171
|
+
const inner = vec[0];
|
|
172
|
+
const dataVec = inner.vec();
|
|
173
|
+
if (dataVec && dataVec.length >= 2) {
|
|
174
|
+
const price = scValToI128(dataVec[0]);
|
|
175
|
+
const timestamp = Number(dataVec[1].u64()?.toString() ?? 0);
|
|
176
|
+
return { price, timestamp, decimals };
|
|
177
|
+
}
|
|
178
|
+
const m = inner.map();
|
|
179
|
+
if (m) {
|
|
180
|
+
for (const entry of m) {
|
|
181
|
+
const k = entry.key();
|
|
182
|
+
const v = entry.val();
|
|
183
|
+
if (k.sym && k.sym().toString() === "price" && v) {
|
|
184
|
+
const price = scValToI128(v);
|
|
185
|
+
let timestamp = 0;
|
|
186
|
+
for (const e2 of m) {
|
|
187
|
+
if (e2.key().sym && e2.key().sym().toString() === "timestamp") {
|
|
188
|
+
timestamp = Number(e2.val().u64()?.toString() ?? 0);
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return { price, timestamp, decimals };
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
throw new Error("Oracle price data format unexpected");
|
|
197
|
+
}
|
|
198
|
+
function scValToI128(val) {
|
|
199
|
+
const i128 = val.i128();
|
|
200
|
+
if (!i128) throw new Error("Expected i128 price");
|
|
201
|
+
const lo = i128.lo();
|
|
202
|
+
const hi = i128.hi();
|
|
203
|
+
if (!lo || hi === void 0) return "0";
|
|
204
|
+
const loNum = Number(lo);
|
|
205
|
+
const hiNum = Number(hi);
|
|
206
|
+
const negative = hiNum < 0;
|
|
207
|
+
const absLo = loNum < 0 ? 4294967296 + loNum : loNum;
|
|
208
|
+
const absHi = hiNum < 0 ? 4294967296 + hiNum : hiNum;
|
|
209
|
+
let n = BigInt(absLo) + (BigInt(absHi) << 32n);
|
|
210
|
+
if (negative) n = -n;
|
|
211
|
+
return String(n);
|
|
212
|
+
}
|
|
213
|
+
function createReflectorOracle(config) {
|
|
214
|
+
const feed = config.feed ?? "dex";
|
|
215
|
+
const contractId = REFLECTOR_ORACLE[feed];
|
|
216
|
+
const server = new import_stellar_sdk3.rpc.Server(config.networkConfig.sorobanRpcUrl, {
|
|
217
|
+
allowHttp: config.networkConfig.sorobanRpcUrl.startsWith("http:")
|
|
218
|
+
});
|
|
219
|
+
const networkPassphrase = import_stellar_sdk3.Networks.PUBLIC;
|
|
220
|
+
async function decimals() {
|
|
221
|
+
const contract = new import_stellar_sdk3.Contract(contractId);
|
|
222
|
+
const op = contract.call("decimals");
|
|
223
|
+
const acc = await server.getAccount(SIMULATION_SOURCE_MAINNET);
|
|
224
|
+
const tx = new import_stellar_sdk3.TransactionBuilder(acc, {
|
|
225
|
+
fee: "10000",
|
|
226
|
+
networkPassphrase
|
|
227
|
+
}).addOperation(op).setTimeout(30).build();
|
|
228
|
+
const sim = await server.simulateTransaction(tx);
|
|
229
|
+
if ("error" in sim && sim.error) throw new Error(String(sim.error));
|
|
230
|
+
const ret = sim?.result?.retval;
|
|
231
|
+
if (ret == null) throw new Error("No decimals retval");
|
|
232
|
+
const val = typeof ret === "string" ? import_stellar_sdk3.xdr.ScVal.fromXDR(ret, "base64") : ret;
|
|
233
|
+
const u = val.u32();
|
|
234
|
+
return u ?? 7;
|
|
235
|
+
}
|
|
236
|
+
async function lastprice(asset) {
|
|
237
|
+
const contract = new import_stellar_sdk3.Contract(contractId);
|
|
238
|
+
const assetScVal = assetToScVal(asset);
|
|
239
|
+
const op = contract.call("lastprice", assetScVal);
|
|
240
|
+
const acc = await server.getAccount(SIMULATION_SOURCE_MAINNET);
|
|
241
|
+
const tx = new import_stellar_sdk3.TransactionBuilder(acc, {
|
|
242
|
+
fee: "10000",
|
|
243
|
+
networkPassphrase
|
|
244
|
+
}).addOperation(op).setTimeout(30).build();
|
|
245
|
+
const sim = await server.simulateTransaction(tx);
|
|
246
|
+
if ("error" in sim && sim.error) throw new Error(String(sim.error));
|
|
247
|
+
const ret = sim?.result?.retval;
|
|
248
|
+
if (ret == null) throw new Error("Oracle lastprice: no retval");
|
|
249
|
+
const dec = await decimals();
|
|
250
|
+
return parseLastPriceRetval(ret, dec);
|
|
251
|
+
}
|
|
252
|
+
return { lastprice, decimals, contractId };
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// src/lending/blend.ts
|
|
256
|
+
var import_stellar_sdk4 = require("@stellar/stellar-sdk");
|
|
257
|
+
var import_blend_sdk = require("@blend-capital/blend-sdk");
|
|
258
|
+
var BLEND_POOLS_MAINNET = "CCCCIQSDILITHMM7PBSLVDT5MISSY7R26MNZXCX4H7J5JQ5FPIYOGYFS";
|
|
259
|
+
var BLEND_POOLS = { mainnet: BLEND_POOLS_MAINNET };
|
|
260
|
+
async function buildSubmitTx(networkConfig, secretKey, poolId, requests) {
|
|
261
|
+
const keypair = import_stellar_sdk4.Keypair.fromSecret(secretKey.trim());
|
|
262
|
+
const user = keypair.publicKey();
|
|
263
|
+
const pool = new import_blend_sdk.PoolContractV2(poolId);
|
|
264
|
+
const submitOpXdr = pool.submit({
|
|
265
|
+
from: user,
|
|
266
|
+
spender: user,
|
|
267
|
+
to: user,
|
|
268
|
+
requests
|
|
269
|
+
});
|
|
270
|
+
const op = import_stellar_sdk4.xdr.Operation.fromXDR(submitOpXdr, "base64");
|
|
271
|
+
const networkPassphrase = import_stellar_sdk4.Networks.PUBLIC;
|
|
272
|
+
const horizon = new import_stellar_sdk4.Horizon.Server(networkConfig.horizonUrl);
|
|
273
|
+
const sourceAccount = await horizon.loadAccount(user);
|
|
274
|
+
const tx = new import_stellar_sdk4.TransactionBuilder(sourceAccount, {
|
|
275
|
+
fee: "10000",
|
|
276
|
+
networkPassphrase
|
|
277
|
+
}).addOperation(op).setTimeout(180).build();
|
|
278
|
+
return { tx, keypair };
|
|
279
|
+
}
|
|
280
|
+
async function lendingSupply(networkConfig, secretKey, args) {
|
|
281
|
+
const amountBigInt = BigInt(args.amount);
|
|
282
|
+
const requests = [
|
|
283
|
+
{
|
|
284
|
+
request_type: import_blend_sdk.RequestType.SupplyCollateral,
|
|
285
|
+
address: args.assetContractId,
|
|
286
|
+
amount: amountBigInt
|
|
287
|
+
}
|
|
288
|
+
];
|
|
289
|
+
const { tx, keypair } = await buildSubmitTx(
|
|
290
|
+
networkConfig,
|
|
291
|
+
secretKey,
|
|
292
|
+
args.poolId,
|
|
293
|
+
requests
|
|
294
|
+
);
|
|
295
|
+
const server = new import_stellar_sdk4.rpc.Server(networkConfig.sorobanRpcUrl, {
|
|
296
|
+
allowHttp: networkConfig.sorobanRpcUrl.startsWith("http:")
|
|
297
|
+
});
|
|
298
|
+
const prepared = await server.prepareTransaction(tx);
|
|
299
|
+
prepared.sign(keypair);
|
|
300
|
+
const sendResult = await server.sendTransaction(prepared);
|
|
301
|
+
if (sendResult.errorResult) {
|
|
302
|
+
throw new Error(`Blend supply failed: ${String(sendResult.errorResult)}`);
|
|
303
|
+
}
|
|
304
|
+
return { hash: sendResult.hash, status: sendResult.status ?? "PENDING" };
|
|
305
|
+
}
|
|
306
|
+
async function lendingBorrow(networkConfig, secretKey, args) {
|
|
307
|
+
const amountBigInt = BigInt(args.amount);
|
|
308
|
+
const requests = [
|
|
309
|
+
{
|
|
310
|
+
request_type: import_blend_sdk.RequestType.Borrow,
|
|
311
|
+
address: args.assetContractId,
|
|
312
|
+
amount: amountBigInt
|
|
313
|
+
}
|
|
314
|
+
];
|
|
315
|
+
const { tx, keypair } = await buildSubmitTx(
|
|
316
|
+
networkConfig,
|
|
317
|
+
secretKey,
|
|
318
|
+
args.poolId,
|
|
319
|
+
requests
|
|
320
|
+
);
|
|
321
|
+
const server = new import_stellar_sdk4.rpc.Server(networkConfig.sorobanRpcUrl, {
|
|
322
|
+
allowHttp: networkConfig.sorobanRpcUrl.startsWith("http:")
|
|
323
|
+
});
|
|
324
|
+
const prepared = await server.prepareTransaction(tx);
|
|
325
|
+
prepared.sign(keypair);
|
|
326
|
+
const sendResult = await server.sendTransaction(prepared);
|
|
327
|
+
if (sendResult.errorResult) {
|
|
328
|
+
throw new Error(`Blend borrow failed: ${String(sendResult.errorResult)}`);
|
|
329
|
+
}
|
|
330
|
+
return { hash: sendResult.hash, status: sendResult.status ?? "PENDING" };
|
|
331
|
+
}
|
|
332
|
+
|
|
130
333
|
// src/agent.ts
|
|
131
334
|
var StellarAgentKit = class {
|
|
132
335
|
keypair;
|
|
@@ -135,18 +338,23 @@ var StellarAgentKit = class {
|
|
|
135
338
|
_initialized = false;
|
|
136
339
|
_dex = null;
|
|
137
340
|
_horizon = null;
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
341
|
+
_oracle = null;
|
|
342
|
+
constructor(secretKey, network = "mainnet") {
|
|
343
|
+
if (network !== "mainnet") {
|
|
344
|
+
throw new Error("This project is mainnet-only. Use network: 'mainnet'.");
|
|
345
|
+
}
|
|
346
|
+
this.keypair = import_stellar_sdk5.Keypair.fromSecret(secretKey.trim());
|
|
347
|
+
this.network = "mainnet";
|
|
348
|
+
this.config = getNetworkConfig();
|
|
142
349
|
}
|
|
143
350
|
/**
|
|
144
351
|
* Initialize clients (Horizon, Soroban RPC, protocol wrappers).
|
|
145
352
|
* Call after construction before using protocol methods.
|
|
146
353
|
*/
|
|
147
354
|
async initialize() {
|
|
148
|
-
this._horizon = new
|
|
355
|
+
this._horizon = new import_stellar_sdk5.Horizon.Server(this.config.horizonUrl);
|
|
149
356
|
this._dex = createDexClient(this.config, process.env.SOROSWAP_API_KEY);
|
|
357
|
+
this._oracle = createReflectorOracle({ networkConfig: this.config });
|
|
150
358
|
this._initialized = true;
|
|
151
359
|
return this;
|
|
152
360
|
}
|
|
@@ -177,6 +385,43 @@ var StellarAgentKit = class {
|
|
|
177
385
|
const quote = await this.dexGetQuote(fromAsset, toAsset, amount);
|
|
178
386
|
return this.dexSwap(quote);
|
|
179
387
|
}
|
|
388
|
+
// ─── Account & balances ────────────────────────────────────────────────────
|
|
389
|
+
/**
|
|
390
|
+
* Get balances for an account (native + trustlines).
|
|
391
|
+
* @param accountId - Stellar account ID (G...); defaults to this agent's public key
|
|
392
|
+
* @returns List of balances: asset code, issuer (if not native), balance string, and optional limit
|
|
393
|
+
*/
|
|
394
|
+
async getBalances(accountId) {
|
|
395
|
+
this.ensureInitialized();
|
|
396
|
+
if (!this._horizon) throw new Error("Horizon not initialized");
|
|
397
|
+
const id = accountId ?? this.keypair.publicKey();
|
|
398
|
+
const account = await this._horizon.loadAccount(id);
|
|
399
|
+
return account.balances.map((b) => ({
|
|
400
|
+
assetCode: b.asset_code === "native" ? "XLM" : b.asset_code,
|
|
401
|
+
issuer: b.asset_issuer,
|
|
402
|
+
balance: b.balance,
|
|
403
|
+
limit: b.limit
|
|
404
|
+
}));
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Create a new Stellar account (funding from this agent's account).
|
|
408
|
+
* @param destination - New account's public key (G...)
|
|
409
|
+
* @param startingBalance - Amount of XLM to send (e.g. "1" for 1 XLM; minimum ~1 XLM for base reserve)
|
|
410
|
+
* @returns Transaction hash
|
|
411
|
+
*/
|
|
412
|
+
async createAccount(destination, startingBalance) {
|
|
413
|
+
this.ensureInitialized();
|
|
414
|
+
if (!this._horizon) throw new Error("Horizon not initialized");
|
|
415
|
+
const networkPassphrase = import_stellar_sdk5.Networks.PUBLIC;
|
|
416
|
+
const sourceAccount = await this._horizon.loadAccount(this.keypair.publicKey());
|
|
417
|
+
const tx = new import_stellar_sdk5.TransactionBuilder(sourceAccount, {
|
|
418
|
+
fee: "100",
|
|
419
|
+
networkPassphrase
|
|
420
|
+
}).addOperation(import_stellar_sdk5.Operation.createAccount({ destination, startingBalance })).setTimeout(180).build();
|
|
421
|
+
tx.sign(this.keypair);
|
|
422
|
+
const result = await this._horizon.submitTransaction(tx);
|
|
423
|
+
return { hash: result.hash };
|
|
424
|
+
}
|
|
180
425
|
// ─── Payments (Horizon) ────────────────────────────────────────────────────
|
|
181
426
|
/**
|
|
182
427
|
* Send a native or custom-asset payment (Horizon).
|
|
@@ -188,47 +433,114 @@ var StellarAgentKit = class {
|
|
|
188
433
|
async sendPayment(to, amount, assetCode, assetIssuer) {
|
|
189
434
|
this.ensureInitialized();
|
|
190
435
|
if (!this._horizon) throw new Error("Horizon not initialized");
|
|
191
|
-
const networkPassphrase =
|
|
436
|
+
const networkPassphrase = import_stellar_sdk5.Networks.PUBLIC;
|
|
437
|
+
const sourceAccount = await this._horizon.loadAccount(this.keypair.publicKey());
|
|
438
|
+
const asset = assetCode && assetIssuer ? new import_stellar_sdk5.Asset(assetCode, assetIssuer) : import_stellar_sdk5.Asset.native();
|
|
439
|
+
const tx = new import_stellar_sdk5.TransactionBuilder(sourceAccount, {
|
|
440
|
+
fee: "100",
|
|
441
|
+
networkPassphrase
|
|
442
|
+
}).addOperation(import_stellar_sdk5.Operation.payment({ destination: to, asset, amount })).setTimeout(180).build();
|
|
443
|
+
tx.sign(this.keypair);
|
|
444
|
+
const result = await this._horizon.submitTransaction(tx);
|
|
445
|
+
return { hash: result.hash };
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Path payment (strict receive): send up to sendMax of sendAsset so destination receives exactly destAmount of destAsset.
|
|
449
|
+
* @param sendAsset - Asset to send (native or { code, issuer })
|
|
450
|
+
* @param sendMax - Maximum amount of sendAsset to send (display units)
|
|
451
|
+
* @param destination - Recipient account (G...)
|
|
452
|
+
* @param destAsset - Asset the recipient receives
|
|
453
|
+
* @param destAmount - Exact amount of destAsset the recipient gets (display units)
|
|
454
|
+
* @param path - Optional intermediate assets for the path
|
|
455
|
+
*/
|
|
456
|
+
async pathPayment(sendAsset, sendMax, destination, destAsset, destAmount, path = []) {
|
|
457
|
+
this.ensureInitialized();
|
|
458
|
+
if (!this._horizon) throw new Error("Horizon not initialized");
|
|
459
|
+
const send = sendAsset.assetCode === "XLM" && !sendAsset.issuer ? import_stellar_sdk5.Asset.native() : new import_stellar_sdk5.Asset(sendAsset.assetCode, sendAsset.issuer);
|
|
460
|
+
const dest = destAsset.assetCode === "XLM" && !destAsset.issuer ? import_stellar_sdk5.Asset.native() : new import_stellar_sdk5.Asset(destAsset.assetCode, destAsset.issuer);
|
|
461
|
+
const pathAssets = path.map(
|
|
462
|
+
(p) => p.assetCode === "XLM" && !p.issuer ? import_stellar_sdk5.Asset.native() : new import_stellar_sdk5.Asset(p.assetCode, p.issuer)
|
|
463
|
+
);
|
|
464
|
+
const networkPassphrase = import_stellar_sdk5.Networks.PUBLIC;
|
|
192
465
|
const sourceAccount = await this._horizon.loadAccount(this.keypair.publicKey());
|
|
193
|
-
const
|
|
194
|
-
const tx = new import_stellar_sdk3.TransactionBuilder(sourceAccount, {
|
|
466
|
+
const tx = new import_stellar_sdk5.TransactionBuilder(sourceAccount, {
|
|
195
467
|
fee: "100",
|
|
196
468
|
networkPassphrase
|
|
197
|
-
}).addOperation(
|
|
469
|
+
}).addOperation(
|
|
470
|
+
import_stellar_sdk5.Operation.pathPaymentStrictReceive({
|
|
471
|
+
sendAsset: send,
|
|
472
|
+
sendMax,
|
|
473
|
+
destination,
|
|
474
|
+
destAsset: dest,
|
|
475
|
+
destAmount,
|
|
476
|
+
path: pathAssets
|
|
477
|
+
})
|
|
478
|
+
).setTimeout(180).build();
|
|
198
479
|
tx.sign(this.keypair);
|
|
199
480
|
const result = await this._horizon.submitTransaction(tx);
|
|
200
481
|
return { hash: result.hash };
|
|
201
482
|
}
|
|
202
|
-
// ───
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
483
|
+
// ─── Oracle (Reflector SEP-40) ─────────────────────────────────────────────
|
|
484
|
+
/**
|
|
485
|
+
* Get latest price for an asset from Reflector oracle.
|
|
486
|
+
* @param asset - { contractId: "C..." } for on-chain token or { symbol: "XLM" } for ticker
|
|
487
|
+
*/
|
|
488
|
+
async getPrice(asset) {
|
|
489
|
+
this.ensureInitialized();
|
|
490
|
+
if (!this._oracle) throw new Error("Oracle not initialized");
|
|
491
|
+
return this._oracle.lastprice(asset);
|
|
492
|
+
}
|
|
493
|
+
// ─── Lending (Blend) ───────────────────────────────────────────────────────
|
|
494
|
+
/**
|
|
495
|
+
* Supply (deposit) an asset to a Blend pool.
|
|
496
|
+
*/
|
|
497
|
+
async lendingSupply(args) {
|
|
498
|
+
this.ensureInitialized();
|
|
499
|
+
return lendingSupply(this.config, this.keypair.secret(), args);
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Borrow an asset from a Blend pool.
|
|
503
|
+
*/
|
|
504
|
+
async lendingBorrow(args) {
|
|
505
|
+
this.ensureInitialized();
|
|
506
|
+
return lendingBorrow(this.config, this.keypair.secret(), args);
|
|
507
|
+
}
|
|
207
508
|
};
|
|
208
509
|
|
|
209
510
|
// src/config/assets.ts
|
|
210
|
-
var TESTNET_ASSETS = {
|
|
211
|
-
XLM: { contractId: "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC" },
|
|
212
|
-
USDC: { contractId: "CBBHRKEP5M3NUDRISGLJKGHDHX3DA2CN2AZBQY6WLVUJ7VNLGSKBDUCM" },
|
|
213
|
-
/** Classic testnet USDC */
|
|
214
|
-
AUSDC: { code: "AUSDC", issuer: "GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN" }
|
|
215
|
-
};
|
|
216
511
|
var MAINNET_ASSETS = {
|
|
217
512
|
XLM: { contractId: "CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA" },
|
|
218
513
|
USDC: { contractId: "CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75" }
|
|
219
514
|
};
|
|
220
|
-
var SOROSWAP_AGGREGATOR =
|
|
221
|
-
|
|
222
|
-
|
|
515
|
+
var SOROSWAP_AGGREGATOR = "CAG5LRYQ5JVEUI5TEID72EYOVX44TTUJT5BQR2J6J77FH65PCCFAJDDH";
|
|
516
|
+
|
|
517
|
+
// src/config/protocols.ts
|
|
518
|
+
var FXDAO_MAINNET = {
|
|
519
|
+
vaults: "CCUN4RXU5VNDHSF4S4RKV4ZJYMX2YWKOH6L4AKEKVNVDQ7HY5QIAO4UB",
|
|
520
|
+
lockingPool: "CDCART6WRSM2K4CKOAOB5YKUVBSJ6KLOVS7ZEJHA4OAQ2FXX7JOHLXIP",
|
|
521
|
+
usdx: "CDIKURWHYS4FFTR5KOQK6MBFZA2K3E26WGBQI6PXBYWZ4XIOPJHDFJKP",
|
|
522
|
+
eurx: "CBN3NCJSMOQTC6SPEYK3A44NU4VS3IPKTARJLI3Y77OH27EWBY36TP7U",
|
|
523
|
+
gbpx: "CBCO65UOWXY2GR66GOCMCN6IU3Y45TXCPBY3FLUNL4AOUMOCKVIVV6JC",
|
|
524
|
+
fxg: "CDBR4FMYL5WPUDBIXTBEBU2AFEYTDLXVOTRZHXS3JC575C7ZQRKYZQ55",
|
|
525
|
+
oracle: "CB5OTV4GV24T5USEZHFVYGC3F4A4MPUQ3LN56E76UK2IT7MJ6QXW4TFS"
|
|
223
526
|
};
|
|
527
|
+
var ALLBRIDGE_CORE_STELLAR_DOCS = "https://docs-core.allbridge.io/sdk/guides/stellar";
|
|
224
528
|
// Annotate the CommonJS export names for ESM import in node:
|
|
225
529
|
0 && (module.exports = {
|
|
530
|
+
ALLBRIDGE_CORE_STELLAR_DOCS,
|
|
531
|
+
BAND_ORACLE,
|
|
532
|
+
BLEND_POOLS,
|
|
533
|
+
BLEND_POOLS_MAINNET,
|
|
534
|
+
FXDAO_MAINNET,
|
|
226
535
|
MAINNET_ASSETS,
|
|
536
|
+
REFLECTOR_ORACLE,
|
|
227
537
|
SOROSWAP_AGGREGATOR,
|
|
228
538
|
StellarAgentKit,
|
|
229
|
-
TESTNET_ASSETS,
|
|
230
539
|
createDexClient,
|
|
540
|
+
createReflectorOracle,
|
|
231
541
|
getNetworkConfig,
|
|
542
|
+
lendingBorrow,
|
|
543
|
+
lendingSupply,
|
|
232
544
|
networks
|
|
233
545
|
});
|
|
234
546
|
//# sourceMappingURL=index.cjs.map
|