@atomiqlabs/chain-solana 12.0.14 → 12.0.15
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 +201 -201
- package/dist/index.d.ts +29 -29
- package/dist/index.js +45 -45
- package/dist/solana/SolanaChainType.d.ts +11 -11
- package/dist/solana/SolanaChainType.js +2 -2
- package/dist/solana/SolanaChains.d.ts +20 -20
- package/dist/solana/SolanaChains.js +25 -25
- package/dist/solana/SolanaInitializer.d.ts +18 -18
- package/dist/solana/SolanaInitializer.js +63 -63
- package/dist/solana/btcrelay/SolanaBtcRelay.d.ts +228 -228
- package/dist/solana/btcrelay/SolanaBtcRelay.js +441 -441
- package/dist/solana/btcrelay/headers/SolanaBtcHeader.d.ts +29 -29
- package/dist/solana/btcrelay/headers/SolanaBtcHeader.js +34 -34
- package/dist/solana/btcrelay/headers/SolanaBtcStoredHeader.d.ts +46 -46
- package/dist/solana/btcrelay/headers/SolanaBtcStoredHeader.js +78 -78
- package/dist/solana/btcrelay/program/programIdl.json +671 -671
- package/dist/solana/chain/SolanaAction.d.ts +26 -26
- package/dist/solana/chain/SolanaAction.js +86 -86
- package/dist/solana/chain/SolanaChainInterface.d.ts +65 -65
- package/dist/solana/chain/SolanaChainInterface.js +125 -125
- package/dist/solana/chain/SolanaModule.d.ts +14 -14
- package/dist/solana/chain/SolanaModule.js +13 -13
- package/dist/solana/chain/modules/SolanaAddresses.d.ts +8 -8
- package/dist/solana/chain/modules/SolanaAddresses.js +22 -22
- package/dist/solana/chain/modules/SolanaBlocks.d.ts +28 -28
- package/dist/solana/chain/modules/SolanaBlocks.js +72 -72
- package/dist/solana/chain/modules/SolanaEvents.d.ts +68 -68
- package/dist/solana/chain/modules/SolanaEvents.js +238 -238
- package/dist/solana/chain/modules/SolanaFees.d.ts +121 -121
- package/dist/solana/chain/modules/SolanaFees.js +379 -379
- package/dist/solana/chain/modules/SolanaSignatures.d.ts +23 -23
- package/dist/solana/chain/modules/SolanaSignatures.js +39 -39
- package/dist/solana/chain/modules/SolanaSlots.d.ts +31 -31
- package/dist/solana/chain/modules/SolanaSlots.js +68 -68
- package/dist/solana/chain/modules/SolanaTokens.d.ts +136 -136
- package/dist/solana/chain/modules/SolanaTokens.js +248 -248
- package/dist/solana/chain/modules/SolanaTransactions.d.ts +124 -124
- package/dist/solana/chain/modules/SolanaTransactions.js +323 -323
- package/dist/solana/events/SolanaChainEvents.d.ts +88 -88
- package/dist/solana/events/SolanaChainEvents.js +256 -256
- package/dist/solana/events/SolanaChainEventsBrowser.d.ts +75 -75
- package/dist/solana/events/SolanaChainEventsBrowser.js +172 -172
- package/dist/solana/program/SolanaProgramBase.d.ts +40 -40
- package/dist/solana/program/SolanaProgramBase.js +43 -43
- package/dist/solana/program/SolanaProgramModule.d.ts +8 -8
- package/dist/solana/program/SolanaProgramModule.js +11 -11
- package/dist/solana/program/modules/SolanaProgramEvents.d.ts +53 -53
- package/dist/solana/program/modules/SolanaProgramEvents.js +114 -114
- package/dist/solana/swaps/SolanaSwapData.d.ts +71 -71
- package/dist/solana/swaps/SolanaSwapData.js +292 -292
- package/dist/solana/swaps/SolanaSwapModule.d.ts +10 -10
- package/dist/solana/swaps/SolanaSwapModule.js +11 -11
- package/dist/solana/swaps/SolanaSwapProgram.d.ts +224 -224
- package/dist/solana/swaps/SolanaSwapProgram.js +570 -570
- package/dist/solana/swaps/SwapTypeEnum.d.ts +11 -11
- package/dist/solana/swaps/SwapTypeEnum.js +42 -42
- package/dist/solana/swaps/modules/SolanaDataAccount.d.ts +94 -94
- package/dist/solana/swaps/modules/SolanaDataAccount.js +231 -231
- package/dist/solana/swaps/modules/SolanaLpVault.d.ts +71 -71
- package/dist/solana/swaps/modules/SolanaLpVault.js +173 -173
- package/dist/solana/swaps/modules/SwapClaim.d.ts +129 -129
- package/dist/solana/swaps/modules/SwapClaim.js +291 -291
- package/dist/solana/swaps/modules/SwapInit.d.ts +217 -217
- package/dist/solana/swaps/modules/SwapInit.js +519 -519
- package/dist/solana/swaps/modules/SwapRefund.d.ts +82 -82
- package/dist/solana/swaps/modules/SwapRefund.js +262 -262
- package/dist/solana/swaps/programIdl.json +945 -945
- package/dist/solana/swaps/programTypes.d.ts +943 -943
- package/dist/solana/swaps/programTypes.js +945 -945
- package/dist/solana/wallet/SolanaKeypairWallet.d.ts +9 -9
- package/dist/solana/wallet/SolanaKeypairWallet.js +33 -33
- package/dist/solana/wallet/SolanaSigner.d.ts +11 -11
- package/dist/solana/wallet/SolanaSigner.js +17 -17
- package/dist/utils/Utils.d.ts +53 -53
- package/dist/utils/Utils.js +170 -170
- package/package.json +41 -41
- package/src/index.ts +36 -36
- package/src/solana/SolanaChainType.ts +27 -27
- package/src/solana/SolanaChains.ts +23 -23
- package/src/solana/SolanaInitializer.ts +102 -102
- package/src/solana/btcrelay/SolanaBtcRelay.ts +589 -589
- package/src/solana/btcrelay/headers/SolanaBtcHeader.ts +57 -57
- package/src/solana/btcrelay/headers/SolanaBtcStoredHeader.ts +102 -102
- package/src/solana/btcrelay/program/programIdl.json +670 -670
- package/src/solana/chain/SolanaAction.ts +108 -108
- package/src/solana/chain/SolanaChainInterface.ts +192 -192
- package/src/solana/chain/SolanaModule.ts +20 -20
- package/src/solana/chain/modules/SolanaAddresses.ts +20 -20
- package/src/solana/chain/modules/SolanaBlocks.ts +78 -78
- package/src/solana/chain/modules/SolanaEvents.ts +270 -270
- package/src/solana/chain/modules/SolanaFees.ts +450 -450
- package/src/solana/chain/modules/SolanaSignatures.ts +39 -39
- package/src/solana/chain/modules/SolanaSlots.ts +82 -82
- package/src/solana/chain/modules/SolanaTokens.ts +307 -307
- package/src/solana/chain/modules/SolanaTransactions.ts +365 -365
- package/src/solana/events/SolanaChainEvents.ts +299 -299
- package/src/solana/events/SolanaChainEventsBrowser.ts +209 -209
- package/src/solana/program/SolanaProgramBase.ts +79 -79
- package/src/solana/program/SolanaProgramModule.ts +15 -15
- package/src/solana/program/modules/SolanaProgramEvents.ts +155 -155
- package/src/solana/swaps/SolanaSwapData.ts +430 -430
- package/src/solana/swaps/SolanaSwapModule.ts +16 -16
- package/src/solana/swaps/SolanaSwapProgram.ts +854 -854
- package/src/solana/swaps/SwapTypeEnum.ts +29 -29
- package/src/solana/swaps/modules/SolanaDataAccount.ts +307 -307
- package/src/solana/swaps/modules/SolanaLpVault.ts +215 -215
- package/src/solana/swaps/modules/SwapClaim.ts +389 -389
- package/src/solana/swaps/modules/SwapInit.ts +663 -663
- package/src/solana/swaps/modules/SwapRefund.ts +323 -323
- package/src/solana/swaps/programIdl.json +944 -944
- package/src/solana/swaps/programTypes.ts +1885 -1885
- package/src/solana/wallet/SolanaKeypairWallet.ts +36 -36
- package/src/solana/wallet/SolanaSigner.ts +24 -24
- package/src/utils/Utils.ts +180 -180
|
@@ -1,248 +1,248 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SolanaTokens = void 0;
|
|
4
|
-
const SolanaModule_1 = require("../SolanaModule");
|
|
5
|
-
const web3_js_1 = require("@solana/web3.js");
|
|
6
|
-
const spl_token_1 = require("@solana/spl-token");
|
|
7
|
-
const SolanaAction_1 = require("../SolanaAction");
|
|
8
|
-
const Utils_1 = require("../../../utils/Utils");
|
|
9
|
-
class SolanaTokens extends SolanaModule_1.SolanaModule {
|
|
10
|
-
/**
|
|
11
|
-
* Creates an ATA for a specific public key & token, the ATA creation is paid for by the underlying provider's
|
|
12
|
-
* public key
|
|
13
|
-
*
|
|
14
|
-
* @param signer
|
|
15
|
-
* @param publicKey public key address of the user for which to initiate the ATA
|
|
16
|
-
* @param token token identification for which the ATA should be initialized
|
|
17
|
-
* @param requiredAta optional required ata address to use, if the address doesn't match it returns null
|
|
18
|
-
* @constructor
|
|
19
|
-
*/
|
|
20
|
-
InitAta(signer, publicKey, token, requiredAta) {
|
|
21
|
-
const ata = (0, spl_token_1.getAssociatedTokenAddressSync)(token, publicKey, true);
|
|
22
|
-
if (requiredAta != null && !ata.equals(requiredAta))
|
|
23
|
-
return null;
|
|
24
|
-
return new SolanaAction_1.SolanaAction(signer, this.root, (0, spl_token_1.createAssociatedTokenAccountInstruction)(signer, ata, publicKey, token), SolanaTokens.CUCosts.ATA_INIT);
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Action for wrapping SOL to WSOL for a specific public key
|
|
28
|
-
*
|
|
29
|
-
* @param publicKey public key of the user for which to wrap the SOL
|
|
30
|
-
* @param amount amount of SOL in lamports (smallest unit) to wrap
|
|
31
|
-
* @param initAta whether we should also initialize the ATA before depositing SOL
|
|
32
|
-
* @constructor
|
|
33
|
-
*/
|
|
34
|
-
Wrap(publicKey, amount, initAta) {
|
|
35
|
-
const ata = (0, spl_token_1.getAssociatedTokenAddressSync)(SolanaTokens.WSOL_ADDRESS, publicKey, true);
|
|
36
|
-
const action = new SolanaAction_1.SolanaAction(publicKey, this.root);
|
|
37
|
-
if (initAta)
|
|
38
|
-
action.addIx((0, spl_token_1.createAssociatedTokenAccountInstruction)(publicKey, ata, publicKey, SolanaTokens.WSOL_ADDRESS), SolanaTokens.CUCosts.ATA_INIT);
|
|
39
|
-
action.addIx(web3_js_1.SystemProgram.transfer({
|
|
40
|
-
fromPubkey: publicKey,
|
|
41
|
-
toPubkey: ata,
|
|
42
|
-
lamports: amount
|
|
43
|
-
}), SolanaTokens.CUCosts.WRAP_SOL);
|
|
44
|
-
action.addIx((0, spl_token_1.createSyncNativeInstruction)(ata));
|
|
45
|
-
return action;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Action for unwrapping WSOL to SOL for a specific public key
|
|
49
|
-
*
|
|
50
|
-
* @param publicKey public key of the user for which to unwrap the sol
|
|
51
|
-
* @constructor
|
|
52
|
-
*/
|
|
53
|
-
Unwrap(publicKey) {
|
|
54
|
-
const ata = (0, spl_token_1.getAssociatedTokenAddressSync)(SolanaTokens.WSOL_ADDRESS, publicKey, true);
|
|
55
|
-
return new SolanaAction_1.SolanaAction(publicKey, this.root, (0, spl_token_1.createCloseAccountInstruction)(ata, publicKey, publicKey), SolanaTokens.CUCosts.ATA_CLOSE);
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Action for transferring the native SOL token, uses provider's public key as a sender
|
|
59
|
-
*
|
|
60
|
-
* @param signer
|
|
61
|
-
* @param recipient
|
|
62
|
-
* @param amount
|
|
63
|
-
* @constructor
|
|
64
|
-
* @private
|
|
65
|
-
*/
|
|
66
|
-
SolTransfer(signer, recipient, amount) {
|
|
67
|
-
return new SolanaAction_1.SolanaAction(signer, this.root, web3_js_1.SystemProgram.transfer({
|
|
68
|
-
fromPubkey: signer,
|
|
69
|
-
toPubkey: recipient,
|
|
70
|
-
lamports: amount
|
|
71
|
-
}), SolanaTokens.CUCosts.TRANSFER_SOL);
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Action for transferring the SPL token, uses provider's public key as a sender
|
|
75
|
-
*
|
|
76
|
-
* @param signer
|
|
77
|
-
* @param recipient
|
|
78
|
-
* @param token
|
|
79
|
-
* @param amount
|
|
80
|
-
* @constructor
|
|
81
|
-
* @private
|
|
82
|
-
*/
|
|
83
|
-
Transfer(signer, recipient, token, amount) {
|
|
84
|
-
const srcAta = (0, spl_token_1.getAssociatedTokenAddressSync)(token, signer, true);
|
|
85
|
-
const dstAta = (0, spl_token_1.getAssociatedTokenAddressSync)(token, recipient, true);
|
|
86
|
-
return new SolanaAction_1.SolanaAction(signer, this.root, (0, spl_token_1.createTransferInstruction)(srcAta, dstAta, signer, amount), SolanaTokens.CUCosts.TRANSFER);
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Creates transactions for sending SOL (the native token)
|
|
90
|
-
*
|
|
91
|
-
* @param signer
|
|
92
|
-
* @param amount amount of the SOL in lamports (smallest unit) to send
|
|
93
|
-
* @param recipient recipient's address
|
|
94
|
-
* @param feeRate fee rate to use for the transactions
|
|
95
|
-
* @private
|
|
96
|
-
*/
|
|
97
|
-
async txsTransferSol(signer, amount, recipient, feeRate) {
|
|
98
|
-
const wsolAta = (0, spl_token_1.getAssociatedTokenAddressSync)(SolanaTokens.WSOL_ADDRESS, signer, true);
|
|
99
|
-
const shouldUnwrap = await this.ataExists(wsolAta);
|
|
100
|
-
const action = new SolanaAction_1.SolanaAction(signer, this.root);
|
|
101
|
-
if (shouldUnwrap) {
|
|
102
|
-
feeRate = feeRate || await this.root.Fees.getFeeRate([signer, recipient, wsolAta]);
|
|
103
|
-
action.add(this.Unwrap(signer));
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
106
|
-
feeRate = feeRate || await this.root.Fees.getFeeRate([signer, recipient]);
|
|
107
|
-
}
|
|
108
|
-
action.add(this.SolTransfer(signer, recipient, amount));
|
|
109
|
-
this.logger.debug("txsTransferSol(): transfer native solana TX created, recipient: " + recipient.toString() +
|
|
110
|
-
" amount: " + amount.toString(10) + " unwrapping: " + shouldUnwrap);
|
|
111
|
-
return [await action.tx(feeRate)];
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Creates transactions for sending the over the tokens
|
|
115
|
-
*
|
|
116
|
-
* @param signer
|
|
117
|
-
* @param token token to send
|
|
118
|
-
* @param amount amount of the token to send
|
|
119
|
-
* @param recipient recipient's address
|
|
120
|
-
* @param feeRate fee rate to use for the transactions
|
|
121
|
-
* @private
|
|
122
|
-
*/
|
|
123
|
-
async txsTransferTokens(signer, token, amount, recipient, feeRate) {
|
|
124
|
-
const srcAta = (0, spl_token_1.getAssociatedTokenAddressSync)(token, signer, true);
|
|
125
|
-
const dstAta = (0, spl_token_1.getAssociatedTokenAddressSync)(token, recipient, true);
|
|
126
|
-
feeRate = feeRate || await this.root.Fees.getFeeRate([signer, srcAta, dstAta]);
|
|
127
|
-
const initAta = !await this.ataExists(dstAta);
|
|
128
|
-
const action = new SolanaAction_1.SolanaAction(signer, this.root);
|
|
129
|
-
if (initAta) {
|
|
130
|
-
action.add(this.InitAta(signer, recipient, token));
|
|
131
|
-
}
|
|
132
|
-
action.add(this.Transfer(signer, recipient, token, amount));
|
|
133
|
-
this.logger.debug("txsTransferTokens(): transfer TX created, recipient: " + recipient.toString() +
|
|
134
|
-
" token: " + token.toString() + " amount: " + amount.toString(10) + " initAta: " + initAta);
|
|
135
|
-
return [await action.tx(feeRate)];
|
|
136
|
-
}
|
|
137
|
-
///////////////////
|
|
138
|
-
//// Tokens
|
|
139
|
-
/**
|
|
140
|
-
* Checks if the provided string is a valid solana token
|
|
141
|
-
*
|
|
142
|
-
* @param token
|
|
143
|
-
*/
|
|
144
|
-
isValidToken(token) {
|
|
145
|
-
try {
|
|
146
|
-
new web3_js_1.PublicKey(token);
|
|
147
|
-
return true;
|
|
148
|
-
}
|
|
149
|
-
catch (e) {
|
|
150
|
-
return false;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Returns the specific ATA or null if it doesn't exist
|
|
155
|
-
*
|
|
156
|
-
* @param ata
|
|
157
|
-
*/
|
|
158
|
-
getATAOrNull(ata) {
|
|
159
|
-
return (0, spl_token_1.getAccount)(this.connection, ata).catch(e => {
|
|
160
|
-
if (e instanceof spl_token_1.TokenAccountNotFoundError)
|
|
161
|
-
return null;
|
|
162
|
-
throw e;
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* Checks whether the specific ATA exists, uses tryWithRetries so retries on failure
|
|
167
|
-
*
|
|
168
|
-
* @param ata
|
|
169
|
-
*/
|
|
170
|
-
async ataExists(ata) {
|
|
171
|
-
const account = await (0, Utils_1.tryWithRetries)(() => this.getATAOrNull(ata), this.retryPolicy);
|
|
172
|
-
return account != null;
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Returns the rent exempt deposit required to initiate the ATA
|
|
176
|
-
*/
|
|
177
|
-
getATARentExemptLamports() {
|
|
178
|
-
return Promise.resolve(BigInt(SolanaTokens.SPL_ATA_RENT_EXEMPT));
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Returns the token balance of the public key
|
|
182
|
-
*
|
|
183
|
-
* @param publicKey
|
|
184
|
-
* @param token
|
|
185
|
-
*/
|
|
186
|
-
async getTokenBalance(publicKey, token) {
|
|
187
|
-
const ata = (0, spl_token_1.getAssociatedTokenAddressSync)(token, publicKey, true);
|
|
188
|
-
const [ataAccount, balance] = await Promise.all([
|
|
189
|
-
this.getATAOrNull(ata),
|
|
190
|
-
(token != null && token.equals(SolanaTokens.WSOL_ADDRESS)) ? this.connection.getBalance(publicKey) : Promise.resolve(null)
|
|
191
|
-
]);
|
|
192
|
-
let ataExists = ataAccount != null;
|
|
193
|
-
let sum = 0n;
|
|
194
|
-
if (ataExists) {
|
|
195
|
-
sum += ataAccount.amount;
|
|
196
|
-
}
|
|
197
|
-
if (balance != null) {
|
|
198
|
-
let balanceLamports = BigInt(balance);
|
|
199
|
-
if (!ataExists)
|
|
200
|
-
balanceLamports = balanceLamports - await this.getATARentExemptLamports();
|
|
201
|
-
if (balanceLamports >= 0n)
|
|
202
|
-
sum += balanceLamports;
|
|
203
|
-
}
|
|
204
|
-
this.logger.debug("getTokenBalance(): token balance fetched, token: " + token.toString() +
|
|
205
|
-
" address: " + publicKey.toString() + " amount: " + sum.toString());
|
|
206
|
-
return { balance: sum, ataExists };
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* Returns the native currency address, we use WSOL address as placeholder for SOL
|
|
210
|
-
*/
|
|
211
|
-
getNativeCurrencyAddress() {
|
|
212
|
-
return SolanaTokens.WSOL_ADDRESS;
|
|
213
|
-
}
|
|
214
|
-
/**
|
|
215
|
-
* Parses string base58 representation of the token address to a PublicKey object
|
|
216
|
-
* @param address
|
|
217
|
-
*/
|
|
218
|
-
toTokenAddress(address) {
|
|
219
|
-
return new web3_js_1.PublicKey(address);
|
|
220
|
-
}
|
|
221
|
-
///////////////////
|
|
222
|
-
//// Transfers
|
|
223
|
-
/**
|
|
224
|
-
* Create transactions for sending a specific token to a destination address
|
|
225
|
-
*
|
|
226
|
-
* @param signer
|
|
227
|
-
* @param token token to use for the transfer
|
|
228
|
-
* @param amount amount of token in base units to transfer
|
|
229
|
-
* @param dstAddress destination address of the recipient
|
|
230
|
-
* @param feeRate fee rate to use for the transaction
|
|
231
|
-
*/
|
|
232
|
-
txsTransfer(signer, token, amount, dstAddress, feeRate) {
|
|
233
|
-
if (SolanaTokens.WSOL_ADDRESS.equals(token)) {
|
|
234
|
-
return this.txsTransferSol(signer, amount, dstAddress, feeRate);
|
|
235
|
-
}
|
|
236
|
-
return this.txsTransferTokens(signer, token, amount, dstAddress, feeRate);
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
exports.SolanaTokens = SolanaTokens;
|
|
240
|
-
SolanaTokens.CUCosts = {
|
|
241
|
-
WRAP_SOL: 10000,
|
|
242
|
-
ATA_CLOSE: 10000,
|
|
243
|
-
ATA_INIT: 40000,
|
|
244
|
-
TRANSFER: 50000,
|
|
245
|
-
TRANSFER_SOL: 5000
|
|
246
|
-
};
|
|
247
|
-
SolanaTokens.WSOL_ADDRESS = new web3_js_1.PublicKey("So11111111111111111111111111111111111111112");
|
|
248
|
-
SolanaTokens.SPL_ATA_RENT_EXEMPT = 2039280;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SolanaTokens = void 0;
|
|
4
|
+
const SolanaModule_1 = require("../SolanaModule");
|
|
5
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
6
|
+
const spl_token_1 = require("@solana/spl-token");
|
|
7
|
+
const SolanaAction_1 = require("../SolanaAction");
|
|
8
|
+
const Utils_1 = require("../../../utils/Utils");
|
|
9
|
+
class SolanaTokens extends SolanaModule_1.SolanaModule {
|
|
10
|
+
/**
|
|
11
|
+
* Creates an ATA for a specific public key & token, the ATA creation is paid for by the underlying provider's
|
|
12
|
+
* public key
|
|
13
|
+
*
|
|
14
|
+
* @param signer
|
|
15
|
+
* @param publicKey public key address of the user for which to initiate the ATA
|
|
16
|
+
* @param token token identification for which the ATA should be initialized
|
|
17
|
+
* @param requiredAta optional required ata address to use, if the address doesn't match it returns null
|
|
18
|
+
* @constructor
|
|
19
|
+
*/
|
|
20
|
+
InitAta(signer, publicKey, token, requiredAta) {
|
|
21
|
+
const ata = (0, spl_token_1.getAssociatedTokenAddressSync)(token, publicKey, true);
|
|
22
|
+
if (requiredAta != null && !ata.equals(requiredAta))
|
|
23
|
+
return null;
|
|
24
|
+
return new SolanaAction_1.SolanaAction(signer, this.root, (0, spl_token_1.createAssociatedTokenAccountInstruction)(signer, ata, publicKey, token), SolanaTokens.CUCosts.ATA_INIT);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Action for wrapping SOL to WSOL for a specific public key
|
|
28
|
+
*
|
|
29
|
+
* @param publicKey public key of the user for which to wrap the SOL
|
|
30
|
+
* @param amount amount of SOL in lamports (smallest unit) to wrap
|
|
31
|
+
* @param initAta whether we should also initialize the ATA before depositing SOL
|
|
32
|
+
* @constructor
|
|
33
|
+
*/
|
|
34
|
+
Wrap(publicKey, amount, initAta) {
|
|
35
|
+
const ata = (0, spl_token_1.getAssociatedTokenAddressSync)(SolanaTokens.WSOL_ADDRESS, publicKey, true);
|
|
36
|
+
const action = new SolanaAction_1.SolanaAction(publicKey, this.root);
|
|
37
|
+
if (initAta)
|
|
38
|
+
action.addIx((0, spl_token_1.createAssociatedTokenAccountInstruction)(publicKey, ata, publicKey, SolanaTokens.WSOL_ADDRESS), SolanaTokens.CUCosts.ATA_INIT);
|
|
39
|
+
action.addIx(web3_js_1.SystemProgram.transfer({
|
|
40
|
+
fromPubkey: publicKey,
|
|
41
|
+
toPubkey: ata,
|
|
42
|
+
lamports: amount
|
|
43
|
+
}), SolanaTokens.CUCosts.WRAP_SOL);
|
|
44
|
+
action.addIx((0, spl_token_1.createSyncNativeInstruction)(ata));
|
|
45
|
+
return action;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Action for unwrapping WSOL to SOL for a specific public key
|
|
49
|
+
*
|
|
50
|
+
* @param publicKey public key of the user for which to unwrap the sol
|
|
51
|
+
* @constructor
|
|
52
|
+
*/
|
|
53
|
+
Unwrap(publicKey) {
|
|
54
|
+
const ata = (0, spl_token_1.getAssociatedTokenAddressSync)(SolanaTokens.WSOL_ADDRESS, publicKey, true);
|
|
55
|
+
return new SolanaAction_1.SolanaAction(publicKey, this.root, (0, spl_token_1.createCloseAccountInstruction)(ata, publicKey, publicKey), SolanaTokens.CUCosts.ATA_CLOSE);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Action for transferring the native SOL token, uses provider's public key as a sender
|
|
59
|
+
*
|
|
60
|
+
* @param signer
|
|
61
|
+
* @param recipient
|
|
62
|
+
* @param amount
|
|
63
|
+
* @constructor
|
|
64
|
+
* @private
|
|
65
|
+
*/
|
|
66
|
+
SolTransfer(signer, recipient, amount) {
|
|
67
|
+
return new SolanaAction_1.SolanaAction(signer, this.root, web3_js_1.SystemProgram.transfer({
|
|
68
|
+
fromPubkey: signer,
|
|
69
|
+
toPubkey: recipient,
|
|
70
|
+
lamports: amount
|
|
71
|
+
}), SolanaTokens.CUCosts.TRANSFER_SOL);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Action for transferring the SPL token, uses provider's public key as a sender
|
|
75
|
+
*
|
|
76
|
+
* @param signer
|
|
77
|
+
* @param recipient
|
|
78
|
+
* @param token
|
|
79
|
+
* @param amount
|
|
80
|
+
* @constructor
|
|
81
|
+
* @private
|
|
82
|
+
*/
|
|
83
|
+
Transfer(signer, recipient, token, amount) {
|
|
84
|
+
const srcAta = (0, spl_token_1.getAssociatedTokenAddressSync)(token, signer, true);
|
|
85
|
+
const dstAta = (0, spl_token_1.getAssociatedTokenAddressSync)(token, recipient, true);
|
|
86
|
+
return new SolanaAction_1.SolanaAction(signer, this.root, (0, spl_token_1.createTransferInstruction)(srcAta, dstAta, signer, amount), SolanaTokens.CUCosts.TRANSFER);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Creates transactions for sending SOL (the native token)
|
|
90
|
+
*
|
|
91
|
+
* @param signer
|
|
92
|
+
* @param amount amount of the SOL in lamports (smallest unit) to send
|
|
93
|
+
* @param recipient recipient's address
|
|
94
|
+
* @param feeRate fee rate to use for the transactions
|
|
95
|
+
* @private
|
|
96
|
+
*/
|
|
97
|
+
async txsTransferSol(signer, amount, recipient, feeRate) {
|
|
98
|
+
const wsolAta = (0, spl_token_1.getAssociatedTokenAddressSync)(SolanaTokens.WSOL_ADDRESS, signer, true);
|
|
99
|
+
const shouldUnwrap = await this.ataExists(wsolAta);
|
|
100
|
+
const action = new SolanaAction_1.SolanaAction(signer, this.root);
|
|
101
|
+
if (shouldUnwrap) {
|
|
102
|
+
feeRate = feeRate || await this.root.Fees.getFeeRate([signer, recipient, wsolAta]);
|
|
103
|
+
action.add(this.Unwrap(signer));
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
feeRate = feeRate || await this.root.Fees.getFeeRate([signer, recipient]);
|
|
107
|
+
}
|
|
108
|
+
action.add(this.SolTransfer(signer, recipient, amount));
|
|
109
|
+
this.logger.debug("txsTransferSol(): transfer native solana TX created, recipient: " + recipient.toString() +
|
|
110
|
+
" amount: " + amount.toString(10) + " unwrapping: " + shouldUnwrap);
|
|
111
|
+
return [await action.tx(feeRate)];
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Creates transactions for sending the over the tokens
|
|
115
|
+
*
|
|
116
|
+
* @param signer
|
|
117
|
+
* @param token token to send
|
|
118
|
+
* @param amount amount of the token to send
|
|
119
|
+
* @param recipient recipient's address
|
|
120
|
+
* @param feeRate fee rate to use for the transactions
|
|
121
|
+
* @private
|
|
122
|
+
*/
|
|
123
|
+
async txsTransferTokens(signer, token, amount, recipient, feeRate) {
|
|
124
|
+
const srcAta = (0, spl_token_1.getAssociatedTokenAddressSync)(token, signer, true);
|
|
125
|
+
const dstAta = (0, spl_token_1.getAssociatedTokenAddressSync)(token, recipient, true);
|
|
126
|
+
feeRate = feeRate || await this.root.Fees.getFeeRate([signer, srcAta, dstAta]);
|
|
127
|
+
const initAta = !await this.ataExists(dstAta);
|
|
128
|
+
const action = new SolanaAction_1.SolanaAction(signer, this.root);
|
|
129
|
+
if (initAta) {
|
|
130
|
+
action.add(this.InitAta(signer, recipient, token));
|
|
131
|
+
}
|
|
132
|
+
action.add(this.Transfer(signer, recipient, token, amount));
|
|
133
|
+
this.logger.debug("txsTransferTokens(): transfer TX created, recipient: " + recipient.toString() +
|
|
134
|
+
" token: " + token.toString() + " amount: " + amount.toString(10) + " initAta: " + initAta);
|
|
135
|
+
return [await action.tx(feeRate)];
|
|
136
|
+
}
|
|
137
|
+
///////////////////
|
|
138
|
+
//// Tokens
|
|
139
|
+
/**
|
|
140
|
+
* Checks if the provided string is a valid solana token
|
|
141
|
+
*
|
|
142
|
+
* @param token
|
|
143
|
+
*/
|
|
144
|
+
isValidToken(token) {
|
|
145
|
+
try {
|
|
146
|
+
new web3_js_1.PublicKey(token);
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
catch (e) {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Returns the specific ATA or null if it doesn't exist
|
|
155
|
+
*
|
|
156
|
+
* @param ata
|
|
157
|
+
*/
|
|
158
|
+
getATAOrNull(ata) {
|
|
159
|
+
return (0, spl_token_1.getAccount)(this.connection, ata).catch(e => {
|
|
160
|
+
if (e instanceof spl_token_1.TokenAccountNotFoundError)
|
|
161
|
+
return null;
|
|
162
|
+
throw e;
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Checks whether the specific ATA exists, uses tryWithRetries so retries on failure
|
|
167
|
+
*
|
|
168
|
+
* @param ata
|
|
169
|
+
*/
|
|
170
|
+
async ataExists(ata) {
|
|
171
|
+
const account = await (0, Utils_1.tryWithRetries)(() => this.getATAOrNull(ata), this.retryPolicy);
|
|
172
|
+
return account != null;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Returns the rent exempt deposit required to initiate the ATA
|
|
176
|
+
*/
|
|
177
|
+
getATARentExemptLamports() {
|
|
178
|
+
return Promise.resolve(BigInt(SolanaTokens.SPL_ATA_RENT_EXEMPT));
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Returns the token balance of the public key
|
|
182
|
+
*
|
|
183
|
+
* @param publicKey
|
|
184
|
+
* @param token
|
|
185
|
+
*/
|
|
186
|
+
async getTokenBalance(publicKey, token) {
|
|
187
|
+
const ata = (0, spl_token_1.getAssociatedTokenAddressSync)(token, publicKey, true);
|
|
188
|
+
const [ataAccount, balance] = await Promise.all([
|
|
189
|
+
this.getATAOrNull(ata),
|
|
190
|
+
(token != null && token.equals(SolanaTokens.WSOL_ADDRESS)) ? this.connection.getBalance(publicKey) : Promise.resolve(null)
|
|
191
|
+
]);
|
|
192
|
+
let ataExists = ataAccount != null;
|
|
193
|
+
let sum = 0n;
|
|
194
|
+
if (ataExists) {
|
|
195
|
+
sum += ataAccount.amount;
|
|
196
|
+
}
|
|
197
|
+
if (balance != null) {
|
|
198
|
+
let balanceLamports = BigInt(balance);
|
|
199
|
+
if (!ataExists)
|
|
200
|
+
balanceLamports = balanceLamports - await this.getATARentExemptLamports();
|
|
201
|
+
if (balanceLamports >= 0n)
|
|
202
|
+
sum += balanceLamports;
|
|
203
|
+
}
|
|
204
|
+
this.logger.debug("getTokenBalance(): token balance fetched, token: " + token.toString() +
|
|
205
|
+
" address: " + publicKey.toString() + " amount: " + sum.toString());
|
|
206
|
+
return { balance: sum, ataExists };
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Returns the native currency address, we use WSOL address as placeholder for SOL
|
|
210
|
+
*/
|
|
211
|
+
getNativeCurrencyAddress() {
|
|
212
|
+
return SolanaTokens.WSOL_ADDRESS;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Parses string base58 representation of the token address to a PublicKey object
|
|
216
|
+
* @param address
|
|
217
|
+
*/
|
|
218
|
+
toTokenAddress(address) {
|
|
219
|
+
return new web3_js_1.PublicKey(address);
|
|
220
|
+
}
|
|
221
|
+
///////////////////
|
|
222
|
+
//// Transfers
|
|
223
|
+
/**
|
|
224
|
+
* Create transactions for sending a specific token to a destination address
|
|
225
|
+
*
|
|
226
|
+
* @param signer
|
|
227
|
+
* @param token token to use for the transfer
|
|
228
|
+
* @param amount amount of token in base units to transfer
|
|
229
|
+
* @param dstAddress destination address of the recipient
|
|
230
|
+
* @param feeRate fee rate to use for the transaction
|
|
231
|
+
*/
|
|
232
|
+
txsTransfer(signer, token, amount, dstAddress, feeRate) {
|
|
233
|
+
if (SolanaTokens.WSOL_ADDRESS.equals(token)) {
|
|
234
|
+
return this.txsTransferSol(signer, amount, dstAddress, feeRate);
|
|
235
|
+
}
|
|
236
|
+
return this.txsTransferTokens(signer, token, amount, dstAddress, feeRate);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
exports.SolanaTokens = SolanaTokens;
|
|
240
|
+
SolanaTokens.CUCosts = {
|
|
241
|
+
WRAP_SOL: 10000,
|
|
242
|
+
ATA_CLOSE: 10000,
|
|
243
|
+
ATA_INIT: 40000,
|
|
244
|
+
TRANSFER: 50000,
|
|
245
|
+
TRANSFER_SOL: 5000
|
|
246
|
+
};
|
|
247
|
+
SolanaTokens.WSOL_ADDRESS = new web3_js_1.PublicKey("So11111111111111111111111111111111111111112");
|
|
248
|
+
SolanaTokens.SPL_ATA_RENT_EXEMPT = 2039280;
|