@anywalletkit/protocol-swap2-jupiter 0.0.0-stage → 0.2.0
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/LICENSE +202 -0
- package/README.md +94 -2
- package/dist/activity.cjs +46 -0
- package/dist/activity.cjs.map +1 -0
- package/dist/activity.d.cts +14 -0
- package/dist/activity.d.ts +14 -0
- package/dist/activity.js +10 -0
- package/dist/activity.js.map +1 -0
- package/dist/chunk-5JXNDQHW.js +56 -0
- package/dist/chunk-5JXNDQHW.js.map +1 -0
- package/dist/chunk-5L7BPEQL.js +51 -0
- package/dist/chunk-5L7BPEQL.js.map +1 -0
- package/dist/chunk-H4SP5E76.js +20 -0
- package/dist/chunk-H4SP5E76.js.map +1 -0
- package/dist/chunk-NESHFKWY.js +240 -0
- package/dist/chunk-NESHFKWY.js.map +1 -0
- package/dist/chunk-OVLAYYGP.js +44 -0
- package/dist/chunk-OVLAYYGP.js.map +1 -0
- package/dist/chunk-RSAOKVP2.js +27 -0
- package/dist/chunk-RSAOKVP2.js.map +1 -0
- package/dist/codec.cjs +76 -0
- package/dist/codec.cjs.map +1 -0
- package/dist/codec.d.cts +27 -0
- package/dist/codec.d.ts +27 -0
- package/dist/codec.js +23 -0
- package/dist/codec.js.map +1 -0
- package/dist/config.cjs +64 -0
- package/dist/config.cjs.map +1 -0
- package/dist/config.d.cts +23 -0
- package/dist/config.d.ts +23 -0
- package/dist/config.js +31 -0
- package/dist/config.js.map +1 -0
- package/dist/index.cjs +390 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +70 -0
- package/dist/index.js.map +1 -0
- package/dist/protocol.cjs +362 -0
- package/dist/protocol.cjs.map +1 -0
- package/dist/protocol.d.cts +16 -0
- package/dist/protocol.d.ts +16 -0
- package/dist/protocol.js +12 -0
- package/dist/protocol.js.map +1 -0
- package/dist/provider.cjs +348 -0
- package/dist/provider.cjs.map +1 -0
- package/dist/provider.d.cts +20 -0
- package/dist/provider.d.ts +20 -0
- package/dist/provider.js +11 -0
- package/dist/provider.js.map +1 -0
- package/dist/transaction.cjs +75 -0
- package/dist/transaction.cjs.map +1 -0
- package/dist/transaction.d.cts +23 -0
- package/dist/transaction.d.ts +23 -0
- package/dist/transaction.js +9 -0
- package/dist/transaction.js.map +1 -0
- package/module.json +16 -0
- package/package.json +96 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
|
|
2
|
+
Apache License
|
|
3
|
+
Version 2.0, January 2004
|
|
4
|
+
http://www.apache.org/licenses/
|
|
5
|
+
|
|
6
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
7
|
+
|
|
8
|
+
1. Definitions.
|
|
9
|
+
|
|
10
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
11
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
12
|
+
|
|
13
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
14
|
+
the copyright owner that is granting the License.
|
|
15
|
+
|
|
16
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
17
|
+
other entities that control, are controlled by, or are under common
|
|
18
|
+
control with that entity. For the purposes of this definition,
|
|
19
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
20
|
+
direction or management of such entity, whether by contract or
|
|
21
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
22
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
23
|
+
|
|
24
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
25
|
+
exercising permissions granted by this License.
|
|
26
|
+
|
|
27
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
28
|
+
including but not limited to software source code, documentation
|
|
29
|
+
source, and configuration files.
|
|
30
|
+
|
|
31
|
+
"Object" form shall mean any form resulting from mechanical
|
|
32
|
+
transformation or translation of a Source form, including but
|
|
33
|
+
not limited to compiled object code, generated documentation,
|
|
34
|
+
and conversions to other media types.
|
|
35
|
+
|
|
36
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
37
|
+
Object form, made available under the License, as indicated by a
|
|
38
|
+
copyright notice that is included in or attached to the work
|
|
39
|
+
(an example is provided in the Appendix below).
|
|
40
|
+
|
|
41
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
42
|
+
form, that is based on (or derived from) the Work and for which the
|
|
43
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
44
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
45
|
+
of this License, Derivative Works shall not include works that remain
|
|
46
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
47
|
+
the Work and Derivative Works thereof.
|
|
48
|
+
|
|
49
|
+
"Contribution" shall mean any work of authorship, including
|
|
50
|
+
the original version of the Work and any modifications or additions
|
|
51
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
52
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
53
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
54
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
55
|
+
means any form of electronic, verbal, or written communication sent
|
|
56
|
+
to the Licensor or its representatives, including but not limited to
|
|
57
|
+
communication on electronic mailing lists, source code control systems,
|
|
58
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
59
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
60
|
+
excluding communication that is conspicuously marked or otherwise
|
|
61
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
62
|
+
|
|
63
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
64
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
65
|
+
subsequently incorporated within the Work.
|
|
66
|
+
|
|
67
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
68
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
69
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
70
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
71
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
72
|
+
Work and such Derivative Works in Source or Object form.
|
|
73
|
+
|
|
74
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
75
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
76
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
77
|
+
(except as stated in this section) patent license to make, have made,
|
|
78
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
79
|
+
where such license applies only to those patent claims licensable
|
|
80
|
+
by such Contributor that are necessarily infringed by their
|
|
81
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
82
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
83
|
+
institute patent litigation against any entity (including a
|
|
84
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
85
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
86
|
+
or contributory patent infringement, then any patent licenses
|
|
87
|
+
granted to You under this License for that Work shall terminate
|
|
88
|
+
as of the date such litigation is filed.
|
|
89
|
+
|
|
90
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
91
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
92
|
+
modifications, and in Source or Object form, provided that You
|
|
93
|
+
meet the following conditions:
|
|
94
|
+
|
|
95
|
+
(a) You must give any other recipients of the Work or
|
|
96
|
+
Derivative Works a copy of this License; and
|
|
97
|
+
|
|
98
|
+
(b) You must cause any modified files to carry prominent notices
|
|
99
|
+
stating that You changed the files; and
|
|
100
|
+
|
|
101
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
102
|
+
that You distribute, all copyright, patent, trademark, and
|
|
103
|
+
attribution notices from the Source form of the Work,
|
|
104
|
+
excluding those notices that do not pertain to any part of
|
|
105
|
+
the Derivative Works; and
|
|
106
|
+
|
|
107
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
108
|
+
distribution, then any Derivative Works that You distribute must
|
|
109
|
+
include a readable copy of the attribution notices contained
|
|
110
|
+
within such NOTICE file, excluding those notices that do not
|
|
111
|
+
pertain to any part of the Derivative Works, in at least one
|
|
112
|
+
of the following places: within a NOTICE text file distributed
|
|
113
|
+
as part of the Derivative Works; within the Source form or
|
|
114
|
+
documentation, if provided along with the Derivative Works; or,
|
|
115
|
+
within a display generated by the Derivative Works, if and
|
|
116
|
+
wherever such third-party notices normally appear. The contents
|
|
117
|
+
of the NOTICE file are for informational purposes only and
|
|
118
|
+
do not modify the License. You may add Your own attribution
|
|
119
|
+
notices within Derivative Works that You distribute, alongside
|
|
120
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
121
|
+
that such additional attribution notices cannot be construed
|
|
122
|
+
as modifying the License.
|
|
123
|
+
|
|
124
|
+
You may add Your own copyright statement to Your modifications and
|
|
125
|
+
may provide additional or different license terms and conditions
|
|
126
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
127
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
128
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
129
|
+
the conditions stated in this License.
|
|
130
|
+
|
|
131
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
132
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
133
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
134
|
+
this License, without any additional terms or conditions.
|
|
135
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
136
|
+
the terms of any separate license agreement you may have executed
|
|
137
|
+
with Licensor regarding such Contributions.
|
|
138
|
+
|
|
139
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
140
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
141
|
+
except as required for reasonable and customary use in describing the
|
|
142
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
143
|
+
|
|
144
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
145
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
146
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
147
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
148
|
+
implied, including, without limitation, any warranties or conditions
|
|
149
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
150
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
151
|
+
appropriateness of using or redistributing the Work and assume any
|
|
152
|
+
risks associated with Your exercise of permissions under this License.
|
|
153
|
+
|
|
154
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
155
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
156
|
+
unless required by applicable law (such as deliberate and grossly
|
|
157
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
158
|
+
liable to You for damages, including any direct, indirect, special,
|
|
159
|
+
incidental, or consequential damages of any character arising as a
|
|
160
|
+
result of this License or out of the use or inability to use the
|
|
161
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
162
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
163
|
+
other commercial damages or losses), even if such Contributor
|
|
164
|
+
has been advised of the possibility of such damages.
|
|
165
|
+
|
|
166
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
167
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
168
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
169
|
+
or other liability obligations and/or rights consistent with this
|
|
170
|
+
License. However, in accepting such obligations, You may act only
|
|
171
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
172
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
173
|
+
defend, and hold each Contributor harmless for any liability
|
|
174
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
175
|
+
of your accepting any such warranty or additional liability.
|
|
176
|
+
|
|
177
|
+
END OF TERMS AND CONDITIONS
|
|
178
|
+
|
|
179
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
180
|
+
|
|
181
|
+
To apply the Apache License to your work, attach the following
|
|
182
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
183
|
+
replaced with your own identifying information. (Don't include
|
|
184
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
185
|
+
comment syntax for the file format. We also recommend that a
|
|
186
|
+
file or class name and description of purpose be included on the
|
|
187
|
+
same "printed page" as the copyright notice for easier
|
|
188
|
+
identification within third-party archives.
|
|
189
|
+
|
|
190
|
+
Copyright [yyyy] [name of copyright owner]
|
|
191
|
+
|
|
192
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
193
|
+
you may not use this file except in compliance with the License.
|
|
194
|
+
You may obtain a copy of the License at
|
|
195
|
+
|
|
196
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
197
|
+
|
|
198
|
+
Unless required by applicable law or agreed to in writing, software
|
|
199
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
200
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
201
|
+
See the License for the specific language governing permissions and
|
|
202
|
+
limitations under the License.
|
package/README.md
CHANGED
|
@@ -1,3 +1,95 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @anywalletkit/protocol-swap2-jupiter
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[Jupiter](https://developers.jup.ag/docs/swap) same-chain Solana swaps as a
|
|
4
|
+
swap2 provider. It uses Swap API V2's **Router** path (`GET /swap/v2/build`):
|
|
5
|
+
Metis on-chain routing, raw instructions, and no Jupiter swap fee. Quotes work
|
|
6
|
+
without an API key at 0.5 requests per second. Pass `apiKey` for your plan's
|
|
7
|
+
limit; the key is per organisation, so ship it on a server, not inside an app.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import {jupiterProvider} from "@anywalletkit/protocol-swap2-jupiter/provider";
|
|
11
|
+
import {RouterSwap2Protocol} from "@anywalletkit/protocol-swap2-router/swap2/router";
|
|
12
|
+
|
|
13
|
+
const swap2 = new RouterSwap2Protocol(solanaAccount, {
|
|
14
|
+
fromChain: "solana:mainnet",
|
|
15
|
+
providers: [jupiterProvider({rpcUrls: ["https://your-solana-rpc"]})],
|
|
16
|
+
});
|
|
17
|
+
const res = await swap2.swap2({fromToken: "SOL", toToken: "USDC", toChain: "solana:mainnet", fromTokenAmount: 100_000_000n, slippageBps: 50});
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The account must expose swap2's `sendSerializedTransaction` hook
|
|
21
|
+
(`@anywalletkit/wallet-solana`'s `sendSerialized` behind it): it simulates the
|
|
22
|
+
transaction, proves the balance changes against the quote, signs, and
|
|
23
|
+
broadcasts through its own RPC. Jupiter never lands the transaction.
|
|
24
|
+
|
|
25
|
+
## What is checked before the quote is handed out
|
|
26
|
+
|
|
27
|
+
`/build` returns instructions; the transaction is assembled here, and only
|
|
28
|
+
after all of the following hold:
|
|
29
|
+
|
|
30
|
+
- the instructions call only Jupiter v6 (`JUP6Lkb…`) and the plumbing a swap
|
|
31
|
+
needs: compute budget, System, SPL Token / Token-2022, Associated Token;
|
|
32
|
+
- the taker is the only signer, and there is no tip instruction;
|
|
33
|
+
- the swap instruction is `route_v2` or `shared_accounts_route_v2` (ExactIn),
|
|
34
|
+
and its own arguments — the ones the program enforces on-chain — say exactly
|
|
35
|
+
our input amount, the quoted output in the answer, our slippage, and 0 bps
|
|
36
|
+
platform fee and positive-slippage share;
|
|
37
|
+
- the answer names the mints and the amount we asked for, as a v0 transaction.
|
|
38
|
+
|
|
39
|
+
The minimum output (`minDestAmount`) is computed from the instruction:
|
|
40
|
+
`quoted × (10 000 − slippage) / 10 000`, rounded down. A `minAmountOut` above
|
|
41
|
+
it refuses the quote.
|
|
42
|
+
|
|
43
|
+
## Compute budget
|
|
44
|
+
|
|
45
|
+
Jupiter's compute-budget instructions are replaced by ours:
|
|
46
|
+
|
|
47
|
+
- **price**: Jupiter's suggestion, capped by `maxComputeUnitPrice`
|
|
48
|
+
(default 2 000 000 µlamports/CU);
|
|
49
|
+
- **limit**: 1.2× the units a simulation used when `rpcUrls` is set, otherwise
|
|
50
|
+
1 400 000. A failing simulation refuses the quote with the program's error.
|
|
51
|
+
|
|
52
|
+
The quoted network fee is 5 000 lamports plus `price × limit`.
|
|
53
|
+
|
|
54
|
+
## Limits
|
|
55
|
+
|
|
56
|
+
- Solana → Solana only, and the recipient must be the signing wallet: Jupiter
|
|
57
|
+
pays the taker's own token account.
|
|
58
|
+
- If the wallet already holds wrapped SOL, the route unwraps all of it into
|
|
59
|
+
SOL. wallet-solana's guard counts the wallet's own wSOL as its SOL, so this
|
|
60
|
+
is neutral and never counted as swap output.
|
|
61
|
+
- Quotes live 30 seconds: the blockhash in a `/build` answer expires in about a
|
|
62
|
+
minute.
|
|
63
|
+
- Status comes from `getSignatureStatuses` on `rpcUrls`; without them it stays
|
|
64
|
+
`pending`, and the wallet's own receipt is the source of truth.
|
|
65
|
+
|
|
66
|
+
## Config
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
jupiterProvider({
|
|
70
|
+
enabled: true, // default
|
|
71
|
+
apiUrl: "https://api.jup.ag/swap/v2", // default
|
|
72
|
+
apiKey: undefined, // Developer Platform key → x-api-key
|
|
73
|
+
rpcUrls: [], // compute-unit simulation + status
|
|
74
|
+
maxComputeUnitPrice: 2_000_000n, // µlamports per CU
|
|
75
|
+
computeUnitPricePercentile: undefined,// "medium" | "high" | "veryHigh" | bps
|
|
76
|
+
defaultSlippageBps: 50, // when the caller names none
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Activity
|
|
81
|
+
|
|
82
|
+
`describeActivity` recognizes a Solana transaction whose first non-plumbing
|
|
83
|
+
program is Jupiter v6 and where the wallet both gave and received an asset:
|
|
84
|
+
"Swapped A → B", counterparty Jupiter. A route that only reaches Jupiter
|
|
85
|
+
through another program, or a leg that only sends (a bridge's pre-swap), is
|
|
86
|
+
left to other modules. The fixtures are real mainnet swaps.
|
|
87
|
+
|
|
88
|
+
## Tests
|
|
89
|
+
|
|
90
|
+
- `tests/codec.test.ts` and `tests/provider.test.ts` replay recorded `/build`
|
|
91
|
+
answers (`fixtures/build-2026-10-23.json`), including tampered ones.
|
|
92
|
+
- `tests/conformance.test.ts` runs the SDK's module, activity and behaviour
|
|
93
|
+
suites.
|
|
94
|
+
- `JUPITER_LIVE=1 pnpm test`: a live `/build` answer through wallet-solana's
|
|
95
|
+
guard on mainnet for a funded public wallet (simulation only, nothing signed).
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/activity.ts
|
|
21
|
+
var activity_exports = {};
|
|
22
|
+
__export(activity_exports, {
|
|
23
|
+
JUPITER_MODULE: () => JUPITER_MODULE,
|
|
24
|
+
describeJupiterActivity: () => describeJupiterActivity
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(activity_exports);
|
|
27
|
+
var import_activity = require("@anywalletkit/protocol-swap2-core/activity");
|
|
28
|
+
|
|
29
|
+
// src/config.ts
|
|
30
|
+
var import_swap2_assets = require("@anywalletkit/swap2-assets");
|
|
31
|
+
var JUPITER_PROGRAM = "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4";
|
|
32
|
+
var SYSTEM_PROGRAM = "11111111111111111111111111111111";
|
|
33
|
+
var WSOL_MINT = "So11111111111111111111111111111111111111112";
|
|
34
|
+
var SOLANA_CAIP2 = "solana:mainnet";
|
|
35
|
+
var SOLANA_CHAINS = /* @__PURE__ */ new Set([SOLANA_CAIP2, "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"]);
|
|
36
|
+
var NATIVE = /* @__PURE__ */ new Set(["", "native", "sol", SYSTEM_PROGRAM, WSOL_MINT.toLowerCase(), "0x0000000000000000000000000000000000000000"]);
|
|
37
|
+
|
|
38
|
+
// src/activity.ts
|
|
39
|
+
var JUPITER_MODULE = "@anywalletkit/protocol-swap2-jupiter";
|
|
40
|
+
function describeJupiterActivity(tx, ctx) {
|
|
41
|
+
if (!SOLANA_CHAINS.has(tx.chain) || tx.call?.to !== JUPITER_PROGRAM) return null;
|
|
42
|
+
const item = (0, import_activity.describeSwapLike)(tx, ctx, { protocol: JUPITER_MODULE, subtitle: "Jupiter", kind: "swap", counterparty: JUPITER_PROGRAM });
|
|
43
|
+
if (item && tx.status !== "failed" && (item.assetsIn.length === 0 || item.assetsOut.length === 0)) return null;
|
|
44
|
+
return item;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=activity.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/activity.ts","../src/config.ts"],"sourcesContent":["/**\n * Activity recognition for Jupiter swaps. Solana history (wallet-solana) names the first non-plumbing program a\n * transaction runs as `call.to`: a swap sent to Jupiter v6 directly (this module's /build transactions, jup.ag) has it\n * there. A route that only passes through Jupiter inside another program (an aggregator or bridge CPI-ing into it) names\n * that program instead and is left to its module. The owner must both give and receive an asset: a leg that only sends\n * (a bridge's source leg with a Jupiter pre-swap) is not called a swap.\n */\nimport type {ActivityItem, ChainTx, DescribeActivityContext} from \"@anywalletkit/core\";\nimport {describeSwapLike} from \"@anywalletkit/protocol-swap2-core/activity\";\nimport {JUPITER_PROGRAM, SOLANA_CHAINS} from \"./config.js\";\n\nexport const JUPITER_MODULE = \"@anywalletkit/protocol-swap2-jupiter\";\n\nexport function describeJupiterActivity(tx: ChainTx, ctx: DescribeActivityContext): ActivityItem | null {\n if (!SOLANA_CHAINS.has(tx.chain) || tx.call?.to !== JUPITER_PROGRAM) return null;\n const item = describeSwapLike(tx, ctx, {protocol: JUPITER_MODULE, subtitle: \"Jupiter\", kind: \"swap\", counterparty: JUPITER_PROGRAM});\n if (item && tx.status !== \"failed\" && (item.assetsIn.length === 0 || item.assetsOut.length === 0)) return null;\n return item;\n}\n","/**\n * Jupiter (Solana) — Swap API V2, Router path (`GET /swap/v2/build`): Metis on-chain routing, raw instructions, no\n * Jupiter swap fee. The transaction is assembled here and executed by the account's serialized-transaction guard\n * (simulation + balance proof), then broadcast through the wallet's own RPC — Jupiter never lands it for us.\n * Same-chain only: Solana → Solana.\n */\nimport {ccAsset, ccAssetByToken} from \"@anywalletkit/swap2-assets\";\n\nexport const JUPITER_API_DEFAULT = \"https://api.jup.ag/swap/v2\";\n\n/** Jupiter Aggregator v6 — the only program a swap instruction may target. */\nexport const JUPITER_PROGRAM = \"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4\";\nexport const COMPUTE_BUDGET_PROGRAM = \"ComputeBudget111111111111111111111111111111\";\nexport const SYSTEM_PROGRAM = \"11111111111111111111111111111111\";\nexport const TOKEN_PROGRAM = \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\";\nexport const TOKEN_2022_PROGRAM = \"TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb\";\nexport const ATA_PROGRAM = \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\";\n/** Wrapped SOL: Jupiter's name for native SOL (it wraps / unwraps around the swap). */\nexport const WSOL_MINT = \"So11111111111111111111111111111111111111112\";\n\n/** Programs the /build instructions may invoke; anything else refuses the quote before the wallet sees it. */\nexport const JUPITER_TX_PROGRAMS: ReadonlySet<string> = new Set([JUPITER_PROGRAM, COMPUTE_BUDGET_PROGRAM, SYSTEM_PROGRAM, TOKEN_PROGRAM, TOKEN_2022_PROGRAM, ATA_PROGRAM]);\n\n/** swap2 names Solana `solana:mainnet`; wallet history uses the genesis-hash form. */\nexport const SOLANA_CAIP2 = \"solana:mainnet\";\nexport const SOLANA_CHAINS: ReadonlySet<string> = new Set([SOLANA_CAIP2, \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\"]);\n\nconst BASE58 = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;\nconst NATIVE = new Set([\"\", \"native\", \"sol\", SYSTEM_PROGRAM, WSOL_MINT.toLowerCase(), \"0x0000000000000000000000000000000000000000\"]);\n\n/** A swap2 token ref on Solana (catalog symbol, mint, or a native marker) → the mint Jupiter quotes; null when unknown. */\nexport function jupiterMint(token: string): string | null {\n if (NATIVE.has(token.toLowerCase()) || /^0x0+$/.test(token)) return WSOL_MINT;\n const bySymbol = ccAsset(SOLANA_CAIP2, token);\n if (bySymbol) return bySymbol.contract ?? WSOL_MINT;\n const byMint = BASE58.test(token) ? ccAssetByToken(SOLANA_CAIP2, token) : undefined;\n if (byMint) return byMint.contract ?? WSOL_MINT;\n return BASE58.test(token) ? token : null;\n}\n\nexport const jupiter = {\n supportsChain: (chain: string) => chain === SOLANA_CAIP2,\n supports: (from: string, to: string) => from === SOLANA_CAIP2 && to === SOLANA_CAIP2,\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA,sBAA+B;;;ACF/B,0BAAsC;AAK/B,IAAM,kBAAkB;AAExB,IAAM,iBAAiB;AAKvB,IAAM,YAAY;AAMlB,IAAM,eAAe;AACrB,IAAM,gBAAqC,oBAAI,IAAI,CAAC,cAAc,yCAAyC,CAAC;AAGnH,IAAM,SAAS,oBAAI,IAAI,CAAC,IAAI,UAAU,OAAO,gBAAgB,UAAU,YAAY,GAAG,4CAA4C,CAAC;;;ADjB5H,IAAM,iBAAiB;AAEvB,SAAS,wBAAwB,IAAa,KAAmD;AACtG,MAAI,CAAC,cAAc,IAAI,GAAG,KAAK,KAAK,GAAG,MAAM,OAAO,gBAAiB,QAAO;AAC5E,QAAM,WAAO,kCAAiB,IAAI,KAAK,EAAC,UAAU,gBAAgB,UAAU,WAAW,MAAM,QAAQ,cAAc,gBAAe,CAAC;AACnI,MAAI,QAAQ,GAAG,WAAW,aAAa,KAAK,SAAS,WAAW,KAAK,KAAK,UAAU,WAAW,GAAI,QAAO;AAC1G,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ChainTx, DescribeActivityContext, ActivityItem } from '@anywalletkit/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Activity recognition for Jupiter swaps. Solana history (wallet-solana) names the first non-plumbing program a
|
|
5
|
+
* transaction runs as `call.to`: a swap sent to Jupiter v6 directly (this module's /build transactions, jup.ag) has it
|
|
6
|
+
* there. A route that only passes through Jupiter inside another program (an aggregator or bridge CPI-ing into it) names
|
|
7
|
+
* that program instead and is left to its module. The owner must both give and receive an asset: a leg that only sends
|
|
8
|
+
* (a bridge's source leg with a Jupiter pre-swap) is not called a swap.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
declare const JUPITER_MODULE = "@anywalletkit/protocol-swap2-jupiter";
|
|
12
|
+
declare function describeJupiterActivity(tx: ChainTx, ctx: DescribeActivityContext): ActivityItem | null;
|
|
13
|
+
|
|
14
|
+
export { JUPITER_MODULE, describeJupiterActivity };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ChainTx, DescribeActivityContext, ActivityItem } from '@anywalletkit/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Activity recognition for Jupiter swaps. Solana history (wallet-solana) names the first non-plumbing program a
|
|
5
|
+
* transaction runs as `call.to`: a swap sent to Jupiter v6 directly (this module's /build transactions, jup.ag) has it
|
|
6
|
+
* there. A route that only passes through Jupiter inside another program (an aggregator or bridge CPI-ing into it) names
|
|
7
|
+
* that program instead and is left to its module. The owner must both give and receive an asset: a leg that only sends
|
|
8
|
+
* (a bridge's source leg with a Jupiter pre-swap) is not called a swap.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
declare const JUPITER_MODULE = "@anywalletkit/protocol-swap2-jupiter";
|
|
12
|
+
declare function describeJupiterActivity(tx: ChainTx, ctx: DescribeActivityContext): ActivityItem | null;
|
|
13
|
+
|
|
14
|
+
export { JUPITER_MODULE, describeJupiterActivity };
|
package/dist/activity.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// src/codec.ts
|
|
2
|
+
import { base64 } from "@scure/base";
|
|
3
|
+
var ROUTE_V2 = "bb64facc31c4af14";
|
|
4
|
+
var SHARED_ACCOUNTS_ROUTE_V2 = "d19853937cfed8e9";
|
|
5
|
+
var hex = (b) => Array.from(b, (x) => x.toString(16).padStart(2, "0")).join("");
|
|
6
|
+
var u64 = (d, o) => new DataView(d.buffer, d.byteOffset + o, 8).getBigUint64(0, true);
|
|
7
|
+
var u16 = (d, o) => new DataView(d.buffer, d.byteOffset + o, 2).getUint16(0, true);
|
|
8
|
+
var fromBase64 = (s) => base64.decode(s);
|
|
9
|
+
var toBase64 = (b) => base64.encode(b);
|
|
10
|
+
function decodeSwapArgs(data) {
|
|
11
|
+
const disc = hex(data.subarray(0, 8));
|
|
12
|
+
const at = disc === ROUTE_V2 ? 8 : disc === SHARED_ACCOUNTS_ROUTE_V2 ? 9 : -1;
|
|
13
|
+
if (at < 0) throw new Error(`unsupported Jupiter instruction ${disc}`);
|
|
14
|
+
if (data.length < at + 22 + 4) throw new Error("Jupiter swap instruction is truncated");
|
|
15
|
+
return {
|
|
16
|
+
kind: at === 8 ? "route_v2" : "shared_accounts_route_v2",
|
|
17
|
+
inAmount: u64(data, at),
|
|
18
|
+
quotedOutAmount: u64(data, at + 8),
|
|
19
|
+
slippageBps: u16(data, at + 16),
|
|
20
|
+
platformFeeBps: u16(data, at + 18),
|
|
21
|
+
positiveSlippageBps: u16(data, at + 20)
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function minOutOf(quotedOut, slippageBps) {
|
|
25
|
+
return quotedOut * BigInt(1e4 - slippageBps) / 10000n;
|
|
26
|
+
}
|
|
27
|
+
function decodeComputeBudget(data) {
|
|
28
|
+
if (data[0] === 2 && data.length === 5) return { limit: new DataView(data.buffer, data.byteOffset + 1, 4).getUint32(0, true) };
|
|
29
|
+
if (data[0] === 3 && data.length === 9) return { price: u64(data, 1) };
|
|
30
|
+
throw new Error(`unexpected compute-budget instruction ${data[0]}`);
|
|
31
|
+
}
|
|
32
|
+
function setComputeUnitLimit(units) {
|
|
33
|
+
const d = new Uint8Array(5);
|
|
34
|
+
d[0] = 2;
|
|
35
|
+
new DataView(d.buffer).setUint32(1, units, true);
|
|
36
|
+
return d;
|
|
37
|
+
}
|
|
38
|
+
function setComputeUnitPrice(microLamports) {
|
|
39
|
+
const d = new Uint8Array(9);
|
|
40
|
+
d[0] = 3;
|
|
41
|
+
new DataView(d.buffer).setBigUint64(1, microLamports, true);
|
|
42
|
+
return d;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export {
|
|
46
|
+
ROUTE_V2,
|
|
47
|
+
SHARED_ACCOUNTS_ROUTE_V2,
|
|
48
|
+
fromBase64,
|
|
49
|
+
toBase64,
|
|
50
|
+
decodeSwapArgs,
|
|
51
|
+
minOutOf,
|
|
52
|
+
decodeComputeBudget,
|
|
53
|
+
setComputeUnitLimit,
|
|
54
|
+
setComputeUnitPrice
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=chunk-5JXNDQHW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/codec.ts"],"sourcesContent":["/**\n * Byte-level checks of what `/build` returns. The swap instruction is Jupiter v6's Anchor `route_v2` /\n * `shared_accounts_route_v2` (ExactIn): its arguments carry the input amount, the quoted output, the slippage and the\n * platform-fee split that the program enforces on-chain — so they are read back here and must equal the request\n * before the transaction is assembled. Discriminators = sha256(\"global:<name>\")[0..8] (verified 2026-10-23 against\n * live /build answers).\n */\nimport {base64} from \"@scure/base\";\n\n/** `route_v2(in_amount u64, quoted_out_amount u64, slippage_bps u16, platform_fee_bps u16, positive_slippage_bps u16, route_plan Vec)` */\nexport const ROUTE_V2 = \"bb64facc31c4af14\";\n/** `shared_accounts_route_v2(id u8, …the same arguments…)` */\nexport const SHARED_ACCOUNTS_ROUTE_V2 = \"d19853937cfed8e9\";\n\nexport interface JupiterSwapArgs {\n kind: \"route_v2\" | \"shared_accounts_route_v2\";\n inAmount: bigint;\n quotedOutAmount: bigint;\n slippageBps: number;\n platformFeeBps: number;\n positiveSlippageBps: number;\n}\n\nconst hex = (b: Uint8Array) => Array.from(b, (x) => x.toString(16).padStart(2, \"0\")).join(\"\");\nconst u64 = (d: Uint8Array, o: number) => new DataView(d.buffer, d.byteOffset + o, 8).getBigUint64(0, true);\nconst u16 = (d: Uint8Array, o: number) => new DataView(d.buffer, d.byteOffset + o, 2).getUint16(0, true);\n\nexport const fromBase64 = (s: string): Uint8Array => base64.decode(s);\nexport const toBase64 = (b: Uint8Array): string => base64.encode(b);\n\n/** Decode the swap instruction's fixed arguments; throws for any other instruction (ExactOut, legacy v1 routes…). */\nexport function decodeSwapArgs(data: Uint8Array): JupiterSwapArgs {\n const disc = hex(data.subarray(0, 8));\n const at = disc === ROUTE_V2 ? 8 : disc === SHARED_ACCOUNTS_ROUTE_V2 ? 9 : -1;\n if (at < 0) throw new Error(`unsupported Jupiter instruction ${disc}`);\n if (data.length < at + 22 + 4) throw new Error(\"Jupiter swap instruction is truncated\");\n return {\n kind: at === 8 ? \"route_v2\" : \"shared_accounts_route_v2\",\n inAmount: u64(data, at),\n quotedOutAmount: u64(data, at + 8),\n slippageBps: u16(data, at + 16),\n platformFeeBps: u16(data, at + 18),\n positiveSlippageBps: u16(data, at + 20),\n };\n}\n\n/** The worst output the program accepts: quoted · (10 000 − slippage) / 10 000, rounded down (never above the on-chain check). */\nexport function minOutOf(quotedOut: bigint, slippageBps: number): bigint {\n return (quotedOut * BigInt(10_000 - slippageBps)) / 10_000n;\n}\n\n/** ComputeBudget instructions: 2 = SetComputeUnitLimit(u32), 3 = SetComputeUnitPrice(u64 micro-lamports). */\nexport function decodeComputeBudget(data: Uint8Array): {limit?: number; price?: bigint} {\n if (data[0] === 2 && data.length === 5) return {limit: new DataView(data.buffer, data.byteOffset + 1, 4).getUint32(0, true)};\n if (data[0] === 3 && data.length === 9) return {price: u64(data, 1)};\n throw new Error(`unexpected compute-budget instruction ${data[0]}`);\n}\n\nexport function setComputeUnitLimit(units: number): Uint8Array {\n const d = new Uint8Array(5);\n d[0] = 2;\n new DataView(d.buffer).setUint32(1, units, true);\n return d;\n}\n\nexport function setComputeUnitPrice(microLamports: bigint): Uint8Array {\n const d = new Uint8Array(9);\n d[0] = 3;\n new DataView(d.buffer).setBigUint64(1, microLamports, true);\n return d;\n}\n"],"mappings":";AAOA,SAAQ,cAAa;AAGd,IAAM,WAAW;AAEjB,IAAM,2BAA2B;AAWxC,IAAM,MAAM,CAAC,MAAkB,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE;AAC5F,IAAM,MAAM,CAAC,GAAe,MAAc,IAAI,SAAS,EAAE,QAAQ,EAAE,aAAa,GAAG,CAAC,EAAE,aAAa,GAAG,IAAI;AAC1G,IAAM,MAAM,CAAC,GAAe,MAAc,IAAI,SAAS,EAAE,QAAQ,EAAE,aAAa,GAAG,CAAC,EAAE,UAAU,GAAG,IAAI;AAEhG,IAAM,aAAa,CAAC,MAA0B,OAAO,OAAO,CAAC;AAC7D,IAAM,WAAW,CAAC,MAA0B,OAAO,OAAO,CAAC;AAG3D,SAAS,eAAe,MAAmC;AAChE,QAAM,OAAO,IAAI,KAAK,SAAS,GAAG,CAAC,CAAC;AACpC,QAAM,KAAK,SAAS,WAAW,IAAI,SAAS,2BAA2B,IAAI;AAC3E,MAAI,KAAK,EAAG,OAAM,IAAI,MAAM,mCAAmC,IAAI,EAAE;AACrE,MAAI,KAAK,SAAS,KAAK,KAAK,EAAG,OAAM,IAAI,MAAM,uCAAuC;AACtF,SAAO;AAAA,IACL,MAAM,OAAO,IAAI,aAAa;AAAA,IAC9B,UAAU,IAAI,MAAM,EAAE;AAAA,IACtB,iBAAiB,IAAI,MAAM,KAAK,CAAC;AAAA,IACjC,aAAa,IAAI,MAAM,KAAK,EAAE;AAAA,IAC9B,gBAAgB,IAAI,MAAM,KAAK,EAAE;AAAA,IACjC,qBAAqB,IAAI,MAAM,KAAK,EAAE;AAAA,EACxC;AACF;AAGO,SAAS,SAAS,WAAmB,aAA6B;AACvE,SAAQ,YAAY,OAAO,MAAS,WAAW,IAAK;AACtD;AAGO,SAAS,oBAAoB,MAAoD;AACtF,MAAI,KAAK,CAAC,MAAM,KAAK,KAAK,WAAW,EAAG,QAAO,EAAC,OAAO,IAAI,SAAS,KAAK,QAAQ,KAAK,aAAa,GAAG,CAAC,EAAE,UAAU,GAAG,IAAI,EAAC;AAC3H,MAAI,KAAK,CAAC,MAAM,KAAK,KAAK,WAAW,EAAG,QAAO,EAAC,OAAO,IAAI,MAAM,CAAC,EAAC;AACnE,QAAM,IAAI,MAAM,yCAAyC,KAAK,CAAC,CAAC,EAAE;AACpE;AAEO,SAAS,oBAAoB,OAA2B;AAC7D,QAAM,IAAI,IAAI,WAAW,CAAC;AAC1B,IAAE,CAAC,IAAI;AACP,MAAI,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,IAAI;AAC/C,SAAO;AACT;AAEO,SAAS,oBAAoB,eAAmC;AACrE,QAAM,IAAI,IAAI,WAAW,CAAC;AAC1B,IAAE,CAAC,IAAI;AACP,MAAI,SAAS,EAAE,MAAM,EAAE,aAAa,GAAG,eAAe,IAAI;AAC1D,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import {
|
|
2
|
+
fromBase64,
|
|
3
|
+
setComputeUnitLimit,
|
|
4
|
+
setComputeUnitPrice
|
|
5
|
+
} from "./chunk-5JXNDQHW.js";
|
|
6
|
+
import {
|
|
7
|
+
COMPUTE_BUDGET_PROGRAM
|
|
8
|
+
} from "./chunk-OVLAYYGP.js";
|
|
9
|
+
|
|
10
|
+
// src/transaction.ts
|
|
11
|
+
import {
|
|
12
|
+
AccountRole,
|
|
13
|
+
address,
|
|
14
|
+
appendTransactionMessageInstructions,
|
|
15
|
+
compileTransaction,
|
|
16
|
+
compressTransactionMessageUsingAddressLookupTables,
|
|
17
|
+
createTransactionMessage,
|
|
18
|
+
getBase58Decoder,
|
|
19
|
+
getBase64EncodedWireTransaction,
|
|
20
|
+
pipe,
|
|
21
|
+
setTransactionMessageFeePayer,
|
|
22
|
+
setTransactionMessageLifetimeUsingBlockhash
|
|
23
|
+
} from "@solana/kit";
|
|
24
|
+
var role = (a) => a.isSigner ? a.isWritable ? AccountRole.WRITABLE_SIGNER : AccountRole.READONLY_SIGNER : a.isWritable ? AccountRole.WRITABLE : AccountRole.READONLY;
|
|
25
|
+
var toInstruction = (ix) => ({
|
|
26
|
+
programAddress: address(ix.programId),
|
|
27
|
+
accounts: ix.accounts.map((a) => ({ address: address(a.pubkey), role: role(a) })),
|
|
28
|
+
data: fromBase64(ix.data)
|
|
29
|
+
});
|
|
30
|
+
function assembleTransaction(input) {
|
|
31
|
+
const budget = [
|
|
32
|
+
{ programAddress: address(COMPUTE_BUDGET_PROGRAM), data: setComputeUnitLimit(input.computeUnitLimit) },
|
|
33
|
+
{ programAddress: address(COMPUTE_BUDGET_PROGRAM), data: setComputeUnitPrice(input.computeUnitPrice) }
|
|
34
|
+
];
|
|
35
|
+
const blockhash = typeof input.blockhash === "string" ? input.blockhash : getBase58Decoder().decode(input.blockhash);
|
|
36
|
+
const tables = {};
|
|
37
|
+
for (const [table, list] of Object.entries(input.addressesByLookupTableAddress ?? {})) tables[address(table)] = list.map((a) => address(a));
|
|
38
|
+
const message = pipe(
|
|
39
|
+
createTransactionMessage({ version: 0 }),
|
|
40
|
+
(m) => setTransactionMessageFeePayer(address(input.taker), m),
|
|
41
|
+
(m) => setTransactionMessageLifetimeUsingBlockhash({ blockhash, lastValidBlockHeight: BigInt(input.lastValidBlockHeight) }, m),
|
|
42
|
+
(m) => appendTransactionMessageInstructions([...budget, ...input.instructions.map(toInstruction)], m),
|
|
43
|
+
(m) => Object.keys(tables).length ? compressTransactionMessageUsingAddressLookupTables(m, tables) : m
|
|
44
|
+
);
|
|
45
|
+
return getBase64EncodedWireTransaction(compileTransaction(message));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export {
|
|
49
|
+
assembleTransaction
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=chunk-5L7BPEQL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/transaction.ts"],"sourcesContent":["/**\n * Assemble the v0 transaction from `/build` instructions: our compute budget (limit + capped price), Jupiter's setup,\n * swap, cleanup and other instructions, compressed with the lookup tables the response names, fee payer = the taker,\n * lifetime = the blockhash Jupiter fetched. Signatures stay empty; the account signs after its own guard.\n */\nimport {\n AccountRole, address, appendTransactionMessageInstructions, compileTransaction, compressTransactionMessageUsingAddressLookupTables,\n createTransactionMessage, getBase58Decoder, getBase64EncodedWireTransaction, pipe, setTransactionMessageFeePayer,\n setTransactionMessageLifetimeUsingBlockhash, type Address, type Blockhash, type Instruction,\n} from \"@solana/kit\";\nimport {COMPUTE_BUDGET_PROGRAM} from \"./config.js\";\nimport {fromBase64, setComputeUnitLimit, setComputeUnitPrice} from \"./codec.js\";\n\nexport interface JupiterInstruction {\n programId: string;\n accounts: {pubkey: string; isSigner: boolean; isWritable: boolean}[];\n data: string;\n}\n\nexport interface AssembleInput {\n taker: string;\n /** setup → swap → cleanup → other, in that order; compute-budget instructions are ours and come first. */\n instructions: JupiterInstruction[];\n computeUnitLimit: number;\n computeUnitPrice: bigint;\n blockhash: Uint8Array | string;\n lastValidBlockHeight: number | bigint;\n addressesByLookupTableAddress: Record<string, string[]> | null | undefined;\n}\n\nconst role = (a: {isSigner: boolean; isWritable: boolean}): AccountRole =>\n a.isSigner ? (a.isWritable ? AccountRole.WRITABLE_SIGNER : AccountRole.READONLY_SIGNER) : a.isWritable ? AccountRole.WRITABLE : AccountRole.READONLY;\n\nconst toInstruction = (ix: JupiterInstruction): Instruction => ({\n programAddress: address(ix.programId),\n accounts: ix.accounts.map((a) => ({address: address(a.pubkey), role: role(a)})),\n data: fromBase64(ix.data),\n});\n\n/** The unsigned transaction as base64 wire bytes (what `TxRequest.serializedTx` carries). */\nexport function assembleTransaction(input: AssembleInput): string {\n const budget: Instruction[] = [\n {programAddress: address(COMPUTE_BUDGET_PROGRAM), data: setComputeUnitLimit(input.computeUnitLimit)},\n {programAddress: address(COMPUTE_BUDGET_PROGRAM), data: setComputeUnitPrice(input.computeUnitPrice)},\n ];\n const blockhash = (typeof input.blockhash === \"string\" ? input.blockhash : getBase58Decoder().decode(input.blockhash)) as Blockhash;\n const tables: Record<Address, Address[]> = {};\n for (const [table, list] of Object.entries(input.addressesByLookupTableAddress ?? {})) tables[address(table)] = list.map((a) => address(a));\n const message = pipe(\n createTransactionMessage({version: 0}),\n (m) => setTransactionMessageFeePayer(address(input.taker), m),\n (m) => setTransactionMessageLifetimeUsingBlockhash({blockhash, lastValidBlockHeight: BigInt(input.lastValidBlockHeight)}, m),\n (m) => appendTransactionMessageInstructions([...budget, ...input.instructions.map(toInstruction)], m),\n (m) => (Object.keys(tables).length ? compressTransactionMessageUsingAddressLookupTables(m, tables) : m),\n );\n return getBase64EncodedWireTransaction(compileTransaction(message));\n}\n"],"mappings":";;;;;;;;;;AAKA;AAAA,EACE;AAAA,EAAa;AAAA,EAAS;AAAA,EAAsC;AAAA,EAAoB;AAAA,EAChF;AAAA,EAA0B;AAAA,EAAkB;AAAA,EAAiC;AAAA,EAAM;AAAA,EACnF;AAAA,OACK;AAqBP,IAAM,OAAO,CAAC,MACZ,EAAE,WAAY,EAAE,aAAa,YAAY,kBAAkB,YAAY,kBAAmB,EAAE,aAAa,YAAY,WAAW,YAAY;AAE9I,IAAM,gBAAgB,CAAC,QAAyC;AAAA,EAC9D,gBAAgB,QAAQ,GAAG,SAAS;AAAA,EACpC,UAAU,GAAG,SAAS,IAAI,CAAC,OAAO,EAAC,SAAS,QAAQ,EAAE,MAAM,GAAG,MAAM,KAAK,CAAC,EAAC,EAAE;AAAA,EAC9E,MAAM,WAAW,GAAG,IAAI;AAC1B;AAGO,SAAS,oBAAoB,OAA8B;AAChE,QAAM,SAAwB;AAAA,IAC5B,EAAC,gBAAgB,QAAQ,sBAAsB,GAAG,MAAM,oBAAoB,MAAM,gBAAgB,EAAC;AAAA,IACnG,EAAC,gBAAgB,QAAQ,sBAAsB,GAAG,MAAM,oBAAoB,MAAM,gBAAgB,EAAC;AAAA,EACrG;AACA,QAAM,YAAa,OAAO,MAAM,cAAc,WAAW,MAAM,YAAY,iBAAiB,EAAE,OAAO,MAAM,SAAS;AACpH,QAAM,SAAqC,CAAC;AAC5C,aAAW,CAAC,OAAO,IAAI,KAAK,OAAO,QAAQ,MAAM,iCAAiC,CAAC,CAAC,EAAG,QAAO,QAAQ,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,QAAQ,CAAC,CAAC;AAC1I,QAAM,UAAU;AAAA,IACd,yBAAyB,EAAC,SAAS,EAAC,CAAC;AAAA,IACrC,CAAC,MAAM,8BAA8B,QAAQ,MAAM,KAAK,GAAG,CAAC;AAAA,IAC5D,CAAC,MAAM,4CAA4C,EAAC,WAAW,sBAAsB,OAAO,MAAM,oBAAoB,EAAC,GAAG,CAAC;AAAA,IAC3H,CAAC,MAAM,qCAAqC,CAAC,GAAG,QAAQ,GAAG,MAAM,aAAa,IAAI,aAAa,CAAC,GAAG,CAAC;AAAA,IACpG,CAAC,MAAO,OAAO,KAAK,MAAM,EAAE,SAAS,mDAAmD,GAAG,MAAM,IAAI;AAAA,EACvG;AACA,SAAO,gCAAgC,mBAAmB,OAAO,CAAC;AACpE;","names":[]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
JUPITER_PROGRAM,
|
|
3
|
+
SOLANA_CHAINS
|
|
4
|
+
} from "./chunk-OVLAYYGP.js";
|
|
5
|
+
|
|
6
|
+
// src/activity.ts
|
|
7
|
+
import { describeSwapLike } from "@anywalletkit/protocol-swap2-core/activity";
|
|
8
|
+
var JUPITER_MODULE = "@anywalletkit/protocol-swap2-jupiter";
|
|
9
|
+
function describeJupiterActivity(tx, ctx) {
|
|
10
|
+
if (!SOLANA_CHAINS.has(tx.chain) || tx.call?.to !== JUPITER_PROGRAM) return null;
|
|
11
|
+
const item = describeSwapLike(tx, ctx, { protocol: JUPITER_MODULE, subtitle: "Jupiter", kind: "swap", counterparty: JUPITER_PROGRAM });
|
|
12
|
+
if (item && tx.status !== "failed" && (item.assetsIn.length === 0 || item.assetsOut.length === 0)) return null;
|
|
13
|
+
return item;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export {
|
|
17
|
+
JUPITER_MODULE,
|
|
18
|
+
describeJupiterActivity
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=chunk-H4SP5E76.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/activity.ts"],"sourcesContent":["/**\n * Activity recognition for Jupiter swaps. Solana history (wallet-solana) names the first non-plumbing program a\n * transaction runs as `call.to`: a swap sent to Jupiter v6 directly (this module's /build transactions, jup.ag) has it\n * there. A route that only passes through Jupiter inside another program (an aggregator or bridge CPI-ing into it) names\n * that program instead and is left to its module. The owner must both give and receive an asset: a leg that only sends\n * (a bridge's source leg with a Jupiter pre-swap) is not called a swap.\n */\nimport type {ActivityItem, ChainTx, DescribeActivityContext} from \"@anywalletkit/core\";\nimport {describeSwapLike} from \"@anywalletkit/protocol-swap2-core/activity\";\nimport {JUPITER_PROGRAM, SOLANA_CHAINS} from \"./config.js\";\n\nexport const JUPITER_MODULE = \"@anywalletkit/protocol-swap2-jupiter\";\n\nexport function describeJupiterActivity(tx: ChainTx, ctx: DescribeActivityContext): ActivityItem | null {\n if (!SOLANA_CHAINS.has(tx.chain) || tx.call?.to !== JUPITER_PROGRAM) return null;\n const item = describeSwapLike(tx, ctx, {protocol: JUPITER_MODULE, subtitle: \"Jupiter\", kind: \"swap\", counterparty: JUPITER_PROGRAM});\n if (item && tx.status !== \"failed\" && (item.assetsIn.length === 0 || item.assetsOut.length === 0)) return null;\n return item;\n}\n"],"mappings":";;;;;;AAQA,SAAQ,wBAAuB;AAGxB,IAAM,iBAAiB;AAEvB,SAAS,wBAAwB,IAAa,KAAmD;AACtG,MAAI,CAAC,cAAc,IAAI,GAAG,KAAK,KAAK,GAAG,MAAM,OAAO,gBAAiB,QAAO;AAC5E,QAAM,OAAO,iBAAiB,IAAI,KAAK,EAAC,UAAU,gBAAgB,UAAU,WAAW,MAAM,QAAQ,cAAc,gBAAe,CAAC;AACnI,MAAI,QAAQ,GAAG,WAAW,aAAa,KAAK,SAAS,WAAW,KAAK,KAAK,UAAU,WAAW,GAAI,QAAO;AAC1G,SAAO;AACT;","names":[]}
|