@renegade-fi/renegade-sdk 0.1.2 → 0.1.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/biome.json +44 -0
- package/examples/basic.ts +30 -34
- package/examples/malleable_external_match.ts +149 -0
- package/examples/order_book_depth.ts +41 -0
- package/examples/shared_bundle.ts +29 -34
- package/index.ts +9 -4
- package/package.json +8 -6
- package/src/client.ts +191 -39
- package/src/http.ts +42 -42
- package/src/types/fixedPoint.ts +23 -0
- package/src/{types.ts → types/index.ts} +20 -1
- package/src/types/malleableMatch.ts +259 -0
- package/src/version.ts +2 -2
- package/tsconfig.build.json +3 -9
- package/tsconfig.json +23 -23
package/biome.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
|
|
3
|
+
"files": {
|
|
4
|
+
"ignore": [
|
|
5
|
+
"CHANGELOG.md",
|
|
6
|
+
"pnpm-lock.yaml",
|
|
7
|
+
"package.json",
|
|
8
|
+
"tsconfig.base.json",
|
|
9
|
+
"wasm/**",
|
|
10
|
+
"dist/**",
|
|
11
|
+
"renegade-utils/**",
|
|
12
|
+
"*.d.ts"
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
"formatter": {
|
|
16
|
+
"indentStyle": "space",
|
|
17
|
+
"indentWidth": 4,
|
|
18
|
+
"lineWidth": 100
|
|
19
|
+
},
|
|
20
|
+
"linter": {
|
|
21
|
+
"rules": {
|
|
22
|
+
"recommended": true,
|
|
23
|
+
"correctness": {
|
|
24
|
+
"noUnusedVariables": "error",
|
|
25
|
+
"useExhaustiveDependencies": "error",
|
|
26
|
+
"noUnusedImports": "error"
|
|
27
|
+
},
|
|
28
|
+
"style": {
|
|
29
|
+
"useShorthandArrayType": "error"
|
|
30
|
+
},
|
|
31
|
+
"suspicious": {
|
|
32
|
+
"noExplicitAny": "off"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"organizeImports": {
|
|
37
|
+
"enabled": true
|
|
38
|
+
},
|
|
39
|
+
"vcs": {
|
|
40
|
+
"enabled": true,
|
|
41
|
+
"clientKind": "git",
|
|
42
|
+
"useIgnoreFile": true
|
|
43
|
+
}
|
|
44
|
+
}
|
package/examples/basic.ts
CHANGED
|
@@ -1,43 +1,39 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Basic example of using the Renegade External Match Client
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* This example demonstrates how to create a client, request a quote, assemble a match, and submit the transaction on-chain.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
OrderSide,
|
|
10
|
-
} from '../index';
|
|
11
|
-
import type { ExternalOrder } from '../index';
|
|
12
|
-
import { stringifyBigJSON } from '../src/http';
|
|
7
|
+
import { ExternalMatchClient, OrderSide } from "../index";
|
|
8
|
+
import type { ExternalOrder } from "../index";
|
|
13
9
|
|
|
14
10
|
// Viem imports for on-chain transactions
|
|
15
|
-
import { http, createWalletClient } from
|
|
16
|
-
import { privateKeyToAccount } from
|
|
17
|
-
import { arbitrumSepolia } from
|
|
11
|
+
import { http, createWalletClient } from "viem";
|
|
12
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
13
|
+
import { arbitrumSepolia } from "viem/chains";
|
|
18
14
|
|
|
19
15
|
// Get API credentials from environment variables
|
|
20
|
-
const API_KEY = process.env.EXTERNAL_MATCH_KEY ||
|
|
21
|
-
const API_SECRET = process.env.EXTERNAL_MATCH_SECRET ||
|
|
22
|
-
const PRIVATE_KEY = process.env.PKEY ||
|
|
23
|
-
const RPC_URL = process.env.RPC_URL ||
|
|
16
|
+
const API_KEY = process.env.EXTERNAL_MATCH_KEY || "";
|
|
17
|
+
const API_SECRET = process.env.EXTERNAL_MATCH_SECRET || "";
|
|
18
|
+
const PRIVATE_KEY = process.env.PKEY || "";
|
|
19
|
+
const RPC_URL = process.env.RPC_URL || "https://sepolia-rollup.arbitrum.io/rpc";
|
|
24
20
|
|
|
25
21
|
// Validate API credentials
|
|
26
22
|
if (!API_KEY || !API_SECRET) {
|
|
27
|
-
console.error(
|
|
28
|
-
console.error(
|
|
23
|
+
console.error("Error: Missing API credentials");
|
|
24
|
+
console.error("Please set EXTERNAL_MATCH_KEY and EXTERNAL_MATCH_SECRET environment variables");
|
|
29
25
|
process.exit(1);
|
|
30
26
|
}
|
|
31
27
|
|
|
32
28
|
// Validate wallet private key
|
|
33
29
|
if (!PRIVATE_KEY) {
|
|
34
|
-
console.error(
|
|
35
|
-
console.error(
|
|
30
|
+
console.error("Error: Missing private key");
|
|
31
|
+
console.error("Please set PKEY environment variable");
|
|
36
32
|
process.exit(1);
|
|
37
33
|
}
|
|
38
34
|
|
|
39
35
|
// Set up wallet client for blockchain transactions
|
|
40
|
-
const privateKey = PRIVATE_KEY.startsWith(
|
|
36
|
+
const privateKey = PRIVATE_KEY.startsWith("0x") ? PRIVATE_KEY : `0x${PRIVATE_KEY}`;
|
|
41
37
|
const walletClient = createWalletClient({
|
|
42
38
|
account: privateKeyToAccount(privateKey as `0x${string}`),
|
|
43
39
|
chain: arbitrumSepolia,
|
|
@@ -45,13 +41,13 @@ const walletClient = createWalletClient({
|
|
|
45
41
|
});
|
|
46
42
|
|
|
47
43
|
// Create the external match client
|
|
48
|
-
console.log(
|
|
44
|
+
console.log("API KEY", API_KEY);
|
|
49
45
|
const client = ExternalMatchClient.newSepoliaClient(API_KEY, API_SECRET);
|
|
50
46
|
|
|
51
47
|
// Example order for USDC/WETH pair
|
|
52
48
|
const order: ExternalOrder = {
|
|
53
|
-
quote_mint:
|
|
54
|
-
base_mint:
|
|
49
|
+
quote_mint: "0xdf8d259c04020562717557f2b5a3cf28e92707d1", // USDC
|
|
50
|
+
base_mint: "0xc3414a7ef14aaaa9c4522dfc00a4e66e74e9c25a", // WETH
|
|
55
51
|
side: OrderSide.BUY,
|
|
56
52
|
quote_amount: BigInt(20_000_000), // 20 USDC
|
|
57
53
|
};
|
|
@@ -62,7 +58,7 @@ const order: ExternalOrder = {
|
|
|
62
58
|
* @returns The transaction hash
|
|
63
59
|
*/
|
|
64
60
|
async function submitTransaction(settlementTx: any): Promise<`0x${string}`> {
|
|
65
|
-
console.log(
|
|
61
|
+
console.log("Submitting transaction...");
|
|
66
62
|
|
|
67
63
|
const tx = await walletClient.sendTransaction({
|
|
68
64
|
to: settlementTx.to as `0x${string}`,
|
|
@@ -77,45 +73,45 @@ async function submitTransaction(settlementTx: any): Promise<`0x${string}`> {
|
|
|
77
73
|
async function fullExample() {
|
|
78
74
|
try {
|
|
79
75
|
// Step 1: Request a quote
|
|
80
|
-
console.log(
|
|
76
|
+
console.log("Requesting quote...");
|
|
81
77
|
const quote = await client.requestQuote(order);
|
|
82
78
|
|
|
83
79
|
if (!quote) {
|
|
84
|
-
console.log(
|
|
80
|
+
console.log("No quote available");
|
|
85
81
|
return;
|
|
86
82
|
}
|
|
87
83
|
|
|
88
|
-
console.log(
|
|
84
|
+
console.log("Quote received!");
|
|
89
85
|
|
|
90
86
|
// Step 2: Assemble the quote into a match bundle
|
|
91
|
-
console.log(
|
|
87
|
+
console.log("Assembling match...");
|
|
92
88
|
const bundle = await client.assembleQuote(quote);
|
|
93
89
|
|
|
94
90
|
if (!bundle) {
|
|
95
|
-
console.log(
|
|
91
|
+
console.log("No match available");
|
|
96
92
|
return;
|
|
97
93
|
}
|
|
98
94
|
|
|
99
|
-
console.log(
|
|
95
|
+
console.log("Match assembled!");
|
|
100
96
|
|
|
101
97
|
// Step 3: Submit the transaction on-chain
|
|
102
98
|
const txHash = await submitTransaction(bundle.match_bundle.settlement_tx);
|
|
103
99
|
console.log(
|
|
104
|
-
|
|
105
|
-
`${walletClient.chain.blockExplorers?.default.url}/tx/${txHash}
|
|
100
|
+
"Transaction submitted:",
|
|
101
|
+
`${walletClient.chain.blockExplorers?.default.url}/tx/${txHash}`,
|
|
106
102
|
);
|
|
107
103
|
} catch (error) {
|
|
108
|
-
console.error(
|
|
104
|
+
console.error("Error:", error);
|
|
109
105
|
}
|
|
110
106
|
}
|
|
111
107
|
|
|
112
108
|
// Run the examples
|
|
113
109
|
async function main() {
|
|
114
|
-
console.log(
|
|
110
|
+
console.log("Running full example with on-chain submission...");
|
|
115
111
|
await fullExample();
|
|
116
112
|
}
|
|
117
113
|
|
|
118
114
|
// Only run if this file is being executed directly
|
|
119
115
|
if (require.main === module) {
|
|
120
116
|
main().catch(console.error);
|
|
121
|
-
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetch a quote from the external api and execute a malleable match
|
|
3
|
+
*
|
|
4
|
+
* Malleable matches allow the exact swap amount to be determined at settlement
|
|
5
|
+
* time within a predefined range, offering more flexibility than standard
|
|
6
|
+
* matches.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { ExternalMatchClient, OrderSide } from "../index";
|
|
10
|
+
import type { ExternalOrder } from "../index";
|
|
11
|
+
|
|
12
|
+
// Viem imports for on-chain transactions
|
|
13
|
+
import { http, createWalletClient } from "viem";
|
|
14
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
15
|
+
import { arbitrumSepolia } from "viem/chains";
|
|
16
|
+
|
|
17
|
+
// Get API credentials from environment variables
|
|
18
|
+
const API_KEY = process.env.EXTERNAL_MATCH_KEY || "";
|
|
19
|
+
const API_SECRET = process.env.EXTERNAL_MATCH_SECRET || "";
|
|
20
|
+
const PRIVATE_KEY = process.env.PKEY || "";
|
|
21
|
+
const RPC_URL = process.env.RPC_URL || "https://sepolia-rollup.arbitrum.io/rpc";
|
|
22
|
+
|
|
23
|
+
// Validate API credentials
|
|
24
|
+
if (!API_KEY || !API_SECRET) {
|
|
25
|
+
console.error("Error: Missing API credentials");
|
|
26
|
+
console.error("Please set EXTERNAL_MATCH_KEY and EXTERNAL_MATCH_SECRET environment variables");
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Validate wallet private key
|
|
31
|
+
if (!PRIVATE_KEY) {
|
|
32
|
+
console.error("Error: Missing private key");
|
|
33
|
+
console.error("Please set PKEY environment variable");
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Set up wallet client for blockchain transactions
|
|
38
|
+
const privateKey = PRIVATE_KEY.startsWith("0x") ? PRIVATE_KEY : `0x${PRIVATE_KEY}`;
|
|
39
|
+
const walletClient = createWalletClient({
|
|
40
|
+
account: privateKeyToAccount(privateKey as `0x${string}`),
|
|
41
|
+
chain: arbitrumSepolia,
|
|
42
|
+
transport: http(RPC_URL),
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Create the external match client
|
|
46
|
+
console.log("API KEY", API_KEY);
|
|
47
|
+
const client = ExternalMatchClient.newSepoliaClient(API_KEY, API_SECRET);
|
|
48
|
+
|
|
49
|
+
// Example order for USDC/WETH pair
|
|
50
|
+
const order: ExternalOrder = {
|
|
51
|
+
quote_mint: "0xdf8d259c04020562717557f2b5a3cf28e92707d1", // USDC
|
|
52
|
+
base_mint: "0xc3414a7ef14aaaa9c4522dfc00a4e66e74e9c25a", // WETH
|
|
53
|
+
side: OrderSide.SELL,
|
|
54
|
+
quote_amount: BigInt(20_000_000), // 20 USDC
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Submit a transaction to the chain
|
|
59
|
+
* @param settlementTx The settlement transaction
|
|
60
|
+
* @returns The transaction hash
|
|
61
|
+
*/
|
|
62
|
+
async function submitTransaction(settlementTx: any): Promise<`0x${string}`> {
|
|
63
|
+
console.log("Submitting transaction...");
|
|
64
|
+
|
|
65
|
+
const tx = await walletClient.sendTransaction({
|
|
66
|
+
to: settlementTx.to as `0x${string}`,
|
|
67
|
+
data: settlementTx.data as `0x${string}`,
|
|
68
|
+
value: settlementTx.value ? BigInt(settlementTx.value) : BigInt(0),
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
return tx;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async function fullExample() {
|
|
75
|
+
try {
|
|
76
|
+
// Step 1: Request a quote
|
|
77
|
+
console.log("Requesting quote...");
|
|
78
|
+
const quote = await client.requestQuote(order);
|
|
79
|
+
|
|
80
|
+
if (!quote) {
|
|
81
|
+
console.log("No quote available");
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
console.log("Quote received!");
|
|
86
|
+
|
|
87
|
+
// Step 2: Assemble the quote into a match bundle
|
|
88
|
+
console.log("Assembling match...");
|
|
89
|
+
const bundle = await client.assembleMalleableQuote(quote);
|
|
90
|
+
|
|
91
|
+
if (!bundle) {
|
|
92
|
+
console.log("No match available");
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Print bundle info
|
|
97
|
+
console.log("Bundle info:");
|
|
98
|
+
const [minBase, maxBase] = bundle.baseBounds();
|
|
99
|
+
console.log(`Base bounds: ${minBase} - ${maxBase}`);
|
|
100
|
+
|
|
101
|
+
// Pick a random base amount and see the send and receive amounts at that base amount
|
|
102
|
+
const dummyBaseAmount = randomInRange(minBase, maxBase);
|
|
103
|
+
const dummySendAmount = bundle.sendAmountAtBase(dummyBaseAmount);
|
|
104
|
+
const dummyReceiveAmount = bundle.receiveAmountAtBase(dummyBaseAmount);
|
|
105
|
+
console.log(`Hypothetical base amount: ${dummyBaseAmount}`);
|
|
106
|
+
console.log(`Hypothetical send amount: ${dummySendAmount}`);
|
|
107
|
+
console.log(`Hypothetical receive amount: ${dummyReceiveAmount}`);
|
|
108
|
+
|
|
109
|
+
// Pick an actual base amount to swap with
|
|
110
|
+
const swappedBaseAmount = randomInRange(minBase, maxBase);
|
|
111
|
+
|
|
112
|
+
// Setting the base amount will return the receive amount at the new base
|
|
113
|
+
// You can also call sendAmount and receiveAmount to get the amounts at the
|
|
114
|
+
// currently set base amount
|
|
115
|
+
const _recv = bundle.setBaseAmount(swappedBaseAmount);
|
|
116
|
+
const send = bundle.sendAmount();
|
|
117
|
+
const recv = bundle.receiveAmount();
|
|
118
|
+
console.log(`Swapped base amount: ${swappedBaseAmount}`);
|
|
119
|
+
console.log(`Send amount: ${send}`);
|
|
120
|
+
console.log(`Receive amount: ${recv}`);
|
|
121
|
+
|
|
122
|
+
// Step 3: Submit the transaction on-chain
|
|
123
|
+
const txHash = await submitTransaction(bundle.match_bundle.settlement_tx);
|
|
124
|
+
console.log(
|
|
125
|
+
"Transaction submitted:",
|
|
126
|
+
`${walletClient.chain.blockExplorers?.default.url}/tx/${txHash}`,
|
|
127
|
+
);
|
|
128
|
+
} catch (error) {
|
|
129
|
+
console.error("Error:", error);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Generate a random value in the given range
|
|
135
|
+
*/
|
|
136
|
+
function randomInRange(min: bigint, max: bigint): bigint {
|
|
137
|
+
return min + BigInt(Math.floor(Math.random() * (Number(max) - Number(min))));
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Run the examples
|
|
141
|
+
async function main() {
|
|
142
|
+
console.log("Running full example with on-chain submission...");
|
|
143
|
+
await fullExample();
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Only run if this file is being executed directly
|
|
147
|
+
if (require.main === module) {
|
|
148
|
+
main().catch(console.error);
|
|
149
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example of using the Renegade External Match Client to fetch order book depth.
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates how to create a client and request order book depth for a given base token mint.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { ExternalMatchClient } from "../index";
|
|
8
|
+
import type { OrderBookDepth } from "../src/types";
|
|
9
|
+
|
|
10
|
+
// Get API credentials from environment variables
|
|
11
|
+
const API_KEY = process.env.EXTERNAL_MATCH_KEY || "";
|
|
12
|
+
const API_SECRET = process.env.EXTERNAL_MATCH_SECRET || "";
|
|
13
|
+
|
|
14
|
+
// Validate API credentials
|
|
15
|
+
if (!API_KEY || !API_SECRET) {
|
|
16
|
+
console.error("Error: Missing API credentials");
|
|
17
|
+
console.error("Please set EXTERNAL_MATCH_KEY and EXTERNAL_MATCH_SECRET environment variables");
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Create the external match client
|
|
22
|
+
console.log("API KEY", API_KEY);
|
|
23
|
+
const client = ExternalMatchClient.newSepoliaClient(API_KEY, API_SECRET);
|
|
24
|
+
|
|
25
|
+
// Example base token mint (USDC)
|
|
26
|
+
const WETH = "0xc3414a7ef14aaaa9c4522dfc00a4e66e74e9c25a";
|
|
27
|
+
|
|
28
|
+
async function main() {
|
|
29
|
+
try {
|
|
30
|
+
console.log("Fetching order book depth for", WETH);
|
|
31
|
+
const depth = (await client.getOrderBookDepth(WETH)) as OrderBookDepth;
|
|
32
|
+
console.log("Order book depth:", JSON.stringify(depth, null, 2));
|
|
33
|
+
} catch (error) {
|
|
34
|
+
console.error("Error:", error);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Only run if this file is being executed directly
|
|
39
|
+
if (require.main === module) {
|
|
40
|
+
main().catch(console.error);
|
|
41
|
+
}
|
|
@@ -1,44 +1,39 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Basic example of using the Renegade External Match Client
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* This example demonstrates how to create a client, request a quote, assemble a match, and submit the transaction on-chain.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
ExternalMatchClient,
|
|
10
|
-
OrderSide,
|
|
11
|
-
} from '../index';
|
|
12
|
-
import type { ExternalOrder } from '../index';
|
|
13
|
-
import { stringifyBigJSON } from '../src/http';
|
|
7
|
+
import { AssembleExternalMatchOptions, ExternalMatchClient, OrderSide } from "../index";
|
|
8
|
+
import type { ExternalOrder } from "../index";
|
|
14
9
|
|
|
15
10
|
// Viem imports for on-chain transactions
|
|
16
|
-
import { http, createWalletClient } from
|
|
17
|
-
import { privateKeyToAccount } from
|
|
18
|
-
import { arbitrumSepolia } from
|
|
11
|
+
import { http, createWalletClient } from "viem";
|
|
12
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
13
|
+
import { arbitrumSepolia } from "viem/chains";
|
|
19
14
|
|
|
20
15
|
// Get API credentials from environment variables
|
|
21
|
-
const API_KEY = process.env.EXTERNAL_MATCH_KEY ||
|
|
22
|
-
const API_SECRET = process.env.EXTERNAL_MATCH_SECRET ||
|
|
23
|
-
const PRIVATE_KEY = process.env.PKEY ||
|
|
24
|
-
const RPC_URL = process.env.RPC_URL ||
|
|
16
|
+
const API_KEY = process.env.EXTERNAL_MATCH_KEY || "";
|
|
17
|
+
const API_SECRET = process.env.EXTERNAL_MATCH_SECRET || "";
|
|
18
|
+
const PRIVATE_KEY = process.env.PKEY || "";
|
|
19
|
+
const RPC_URL = process.env.RPC_URL || "https://sepolia-rollup.arbitrum.io/rpc";
|
|
25
20
|
|
|
26
21
|
// Validate API credentials
|
|
27
22
|
if (!API_KEY || !API_SECRET) {
|
|
28
|
-
console.error(
|
|
29
|
-
console.error(
|
|
23
|
+
console.error("Error: Missing API credentials");
|
|
24
|
+
console.error("Please set EXTERNAL_MATCH_KEY and EXTERNAL_MATCH_SECRET environment variables");
|
|
30
25
|
process.exit(1);
|
|
31
26
|
}
|
|
32
27
|
|
|
33
28
|
// Validate wallet private key
|
|
34
29
|
if (!PRIVATE_KEY) {
|
|
35
|
-
console.error(
|
|
36
|
-
console.error(
|
|
30
|
+
console.error("Error: Missing private key");
|
|
31
|
+
console.error("Please set PKEY environment variable");
|
|
37
32
|
process.exit(1);
|
|
38
33
|
}
|
|
39
34
|
|
|
40
35
|
// Set up wallet client for blockchain transactions
|
|
41
|
-
const privateKey = PRIVATE_KEY.startsWith(
|
|
36
|
+
const privateKey = PRIVATE_KEY.startsWith("0x") ? PRIVATE_KEY : `0x${PRIVATE_KEY}`;
|
|
42
37
|
const walletClient = createWalletClient({
|
|
43
38
|
account: privateKeyToAccount(privateKey as `0x${string}`),
|
|
44
39
|
chain: arbitrumSepolia,
|
|
@@ -46,13 +41,13 @@ const walletClient = createWalletClient({
|
|
|
46
41
|
});
|
|
47
42
|
|
|
48
43
|
// Create the external match client
|
|
49
|
-
console.log(
|
|
44
|
+
console.log("API KEY", API_KEY);
|
|
50
45
|
const client = ExternalMatchClient.newSepoliaClient(API_KEY, API_SECRET);
|
|
51
46
|
|
|
52
47
|
// Example order for USDC/WETH pair
|
|
53
48
|
const order: ExternalOrder = {
|
|
54
|
-
quote_mint:
|
|
55
|
-
base_mint:
|
|
49
|
+
quote_mint: "0xdf8d259c04020562717557f2b5a3cf28e92707d1", // USDC
|
|
50
|
+
base_mint: "0xc3414a7ef14aaaa9c4522dfc00a4e66e74e9c25a", // WETH
|
|
56
51
|
side: OrderSide.BUY,
|
|
57
52
|
quote_amount: BigInt(20_000_000), // 20 USDC
|
|
58
53
|
};
|
|
@@ -63,7 +58,7 @@ const order: ExternalOrder = {
|
|
|
63
58
|
* @returns The transaction hash
|
|
64
59
|
*/
|
|
65
60
|
async function submitTransaction(settlementTx: any): Promise<`0x${string}`> {
|
|
66
|
-
console.log(
|
|
61
|
+
console.log("Submitting transaction...");
|
|
67
62
|
|
|
68
63
|
const tx = await walletClient.sendTransaction({
|
|
69
64
|
to: settlementTx.to as `0x${string}`,
|
|
@@ -78,40 +73,40 @@ async function submitTransaction(settlementTx: any): Promise<`0x${string}`> {
|
|
|
78
73
|
async function main() {
|
|
79
74
|
try {
|
|
80
75
|
// Step 1: Request a quote
|
|
81
|
-
console.log(
|
|
76
|
+
console.log("Requesting quote...");
|
|
82
77
|
const quote = await client.requestQuote(order);
|
|
83
78
|
|
|
84
79
|
if (!quote) {
|
|
85
|
-
console.log(
|
|
80
|
+
console.log("No quote available");
|
|
86
81
|
return;
|
|
87
82
|
}
|
|
88
83
|
|
|
89
|
-
console.log(
|
|
84
|
+
console.log("Quote received!");
|
|
90
85
|
|
|
91
86
|
// Step 2: Assemble the quote into a match bundle
|
|
92
|
-
console.log(
|
|
87
|
+
console.log("Assembling match...");
|
|
93
88
|
const options = AssembleExternalMatchOptions.new().withAllowShared(true);
|
|
94
89
|
const bundle = await client.assembleQuoteWithOptions(quote, options);
|
|
95
90
|
|
|
96
91
|
if (!bundle) {
|
|
97
|
-
console.log(
|
|
92
|
+
console.log("No match available");
|
|
98
93
|
return;
|
|
99
94
|
}
|
|
100
95
|
|
|
101
|
-
console.log(
|
|
96
|
+
console.log("Match assembled!");
|
|
102
97
|
|
|
103
98
|
// Step 3: Submit the transaction on-chain
|
|
104
99
|
const txHash = await submitTransaction(bundle.match_bundle.settlement_tx);
|
|
105
100
|
console.log(
|
|
106
|
-
|
|
107
|
-
`${walletClient.chain.blockExplorers?.default.url}/tx/${txHash}
|
|
101
|
+
"Transaction submitted:",
|
|
102
|
+
`${walletClient.chain.blockExplorers?.default.url}/tx/${txHash}`,
|
|
108
103
|
);
|
|
109
104
|
} catch (error) {
|
|
110
|
-
console.error(
|
|
105
|
+
console.error("Error:", error);
|
|
111
106
|
}
|
|
112
107
|
}
|
|
113
108
|
|
|
114
109
|
// Only run if this file is being executed directly
|
|
115
110
|
if (require.main === module) {
|
|
116
111
|
main().catch(console.error);
|
|
117
|
-
}
|
|
112
|
+
}
|
package/index.ts
CHANGED
|
@@ -4,7 +4,12 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
// Export main client
|
|
7
|
-
export {
|
|
7
|
+
export {
|
|
8
|
+
ExternalMatchClient,
|
|
9
|
+
ExternalMatchClientError,
|
|
10
|
+
RequestQuoteOptions,
|
|
11
|
+
AssembleExternalMatchOptions,
|
|
12
|
+
} from "./src/client";
|
|
8
13
|
|
|
9
14
|
// Export types
|
|
10
15
|
export type {
|
|
@@ -23,8 +28,8 @@ export type {
|
|
|
23
28
|
ExternalQuoteRequest,
|
|
24
29
|
ExternalQuoteResponse,
|
|
25
30
|
AssembleExternalMatchRequest,
|
|
26
|
-
ExternalMatchResponse
|
|
27
|
-
} from
|
|
31
|
+
ExternalMatchResponse,
|
|
32
|
+
} from "./src/types/index";
|
|
28
33
|
|
|
29
34
|
// Export enums
|
|
30
|
-
export { OrderSide } from
|
|
35
|
+
export { OrderSide } from "./src/types/index";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@renegade-fi/renegade-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "A TypeScript client for interacting with the Renegade Darkpool API",
|
|
5
5
|
"module": "index.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"scripts": {
|
|
10
10
|
"build": "tsc -p tsconfig.build.json",
|
|
11
11
|
"update-version": "bash scripts/update-version.sh",
|
|
12
|
-
"prepublishOnly": "npm run update-version && npm run build"
|
|
12
|
+
"prepublishOnly": "npm run update-version && npm run build",
|
|
13
|
+
"check": "biome check --write ."
|
|
13
14
|
},
|
|
14
15
|
"keywords": [
|
|
15
16
|
"renegade",
|
|
@@ -24,13 +25,14 @@
|
|
|
24
25
|
"license": "MIT",
|
|
25
26
|
"dependencies": {
|
|
26
27
|
"@noble/hashes": "^1.7.1",
|
|
27
|
-
"json-bigint": "^1.0.0"
|
|
28
|
+
"json-bigint": "^1.0.0",
|
|
29
|
+
"viem": "^2.23.15"
|
|
28
30
|
},
|
|
29
31
|
"devDependencies": {
|
|
32
|
+
"@biomejs/biome": "^1.9.4",
|
|
30
33
|
"@types/bun": "latest",
|
|
31
34
|
"@types/json-bigint": "^1.0.4",
|
|
32
|
-
"typescript": "^5"
|
|
33
|
-
"viem": "^2.23.15"
|
|
35
|
+
"typescript": "^5"
|
|
34
36
|
},
|
|
35
37
|
"repository": {
|
|
36
38
|
"type": "git",
|
|
@@ -39,4 +41,4 @@
|
|
|
39
41
|
"engines": {
|
|
40
42
|
"node": ">=18"
|
|
41
43
|
}
|
|
42
|
-
}
|
|
44
|
+
}
|