@atomiqlabs/chain-solana 7.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.
Files changed (105) hide show
  1. package/LICENSE +201 -0
  2. package/dist/index.d.ts +28 -0
  3. package/dist/index.js +44 -0
  4. package/dist/solana/SolanaChainType.d.ts +9 -0
  5. package/dist/solana/SolanaChainType.js +2 -0
  6. package/dist/solana/base/SolanaAction.d.ts +26 -0
  7. package/dist/solana/base/SolanaAction.js +99 -0
  8. package/dist/solana/base/SolanaBase.d.ts +36 -0
  9. package/dist/solana/base/SolanaBase.js +30 -0
  10. package/dist/solana/base/SolanaModule.d.ts +14 -0
  11. package/dist/solana/base/SolanaModule.js +13 -0
  12. package/dist/solana/base/modules/SolanaAddresses.d.ts +9 -0
  13. package/dist/solana/base/modules/SolanaAddresses.js +23 -0
  14. package/dist/solana/base/modules/SolanaBlocks.d.ts +28 -0
  15. package/dist/solana/base/modules/SolanaBlocks.js +83 -0
  16. package/dist/solana/base/modules/SolanaEvents.d.ts +25 -0
  17. package/dist/solana/base/modules/SolanaEvents.js +69 -0
  18. package/dist/solana/base/modules/SolanaFees.d.ts +121 -0
  19. package/dist/solana/base/modules/SolanaFees.js +393 -0
  20. package/dist/solana/base/modules/SolanaSignatures.d.ts +23 -0
  21. package/dist/solana/base/modules/SolanaSignatures.js +39 -0
  22. package/dist/solana/base/modules/SolanaSlots.d.ts +31 -0
  23. package/dist/solana/base/modules/SolanaSlots.js +81 -0
  24. package/dist/solana/base/modules/SolanaTokens.d.ts +134 -0
  25. package/dist/solana/base/modules/SolanaTokens.js +269 -0
  26. package/dist/solana/base/modules/SolanaTransactions.d.ts +124 -0
  27. package/dist/solana/base/modules/SolanaTransactions.js +354 -0
  28. package/dist/solana/btcrelay/SolanaBtcRelay.d.ts +229 -0
  29. package/dist/solana/btcrelay/SolanaBtcRelay.js +477 -0
  30. package/dist/solana/btcrelay/headers/SolanaBtcHeader.d.ts +29 -0
  31. package/dist/solana/btcrelay/headers/SolanaBtcHeader.js +34 -0
  32. package/dist/solana/btcrelay/headers/SolanaBtcStoredHeader.d.ts +46 -0
  33. package/dist/solana/btcrelay/headers/SolanaBtcStoredHeader.js +78 -0
  34. package/dist/solana/btcrelay/program/programIdl.json +671 -0
  35. package/dist/solana/events/SolanaChainEvents.d.ts +84 -0
  36. package/dist/solana/events/SolanaChainEvents.js +268 -0
  37. package/dist/solana/events/SolanaChainEventsBrowser.d.ts +85 -0
  38. package/dist/solana/events/SolanaChainEventsBrowser.js +202 -0
  39. package/dist/solana/program/SolanaProgramBase.d.ts +34 -0
  40. package/dist/solana/program/SolanaProgramBase.js +43 -0
  41. package/dist/solana/program/modules/SolanaProgramEvents.d.ts +58 -0
  42. package/dist/solana/program/modules/SolanaProgramEvents.js +114 -0
  43. package/dist/solana/swaps/SolanaSwapData.d.ts +55 -0
  44. package/dist/solana/swaps/SolanaSwapData.js +251 -0
  45. package/dist/solana/swaps/SolanaSwapModule.d.ts +9 -0
  46. package/dist/solana/swaps/SolanaSwapModule.js +12 -0
  47. package/dist/solana/swaps/SolanaSwapProgram.d.ts +218 -0
  48. package/dist/solana/swaps/SolanaSwapProgram.js +523 -0
  49. package/dist/solana/swaps/SwapTypeEnum.d.ts +11 -0
  50. package/dist/solana/swaps/SwapTypeEnum.js +42 -0
  51. package/dist/solana/swaps/modules/SolanaDataAccount.d.ts +94 -0
  52. package/dist/solana/swaps/modules/SolanaDataAccount.js +255 -0
  53. package/dist/solana/swaps/modules/SolanaLpVault.d.ts +72 -0
  54. package/dist/solana/swaps/modules/SolanaLpVault.js +196 -0
  55. package/dist/solana/swaps/modules/SwapClaim.d.ts +129 -0
  56. package/dist/solana/swaps/modules/SwapClaim.js +307 -0
  57. package/dist/solana/swaps/modules/SwapInit.d.ts +212 -0
  58. package/dist/solana/swaps/modules/SwapInit.js +508 -0
  59. package/dist/solana/swaps/modules/SwapRefund.d.ts +83 -0
  60. package/dist/solana/swaps/modules/SwapRefund.js +264 -0
  61. package/dist/solana/swaps/programIdl.json +945 -0
  62. package/dist/solana/swaps/programTypes.d.ts +943 -0
  63. package/dist/solana/swaps/programTypes.js +945 -0
  64. package/dist/solana/wallet/SolanaKeypairWallet.d.ts +9 -0
  65. package/dist/solana/wallet/SolanaKeypairWallet.js +33 -0
  66. package/dist/solana/wallet/SolanaSigner.d.ts +10 -0
  67. package/dist/solana/wallet/SolanaSigner.js +16 -0
  68. package/dist/utils/Utils.d.ts +43 -0
  69. package/dist/utils/Utils.js +143 -0
  70. package/package.json +40 -0
  71. package/src/index.ts +35 -0
  72. package/src/solana/SolanaChainType.ts +20 -0
  73. package/src/solana/base/SolanaAction.ts +109 -0
  74. package/src/solana/base/SolanaBase.ts +57 -0
  75. package/src/solana/base/SolanaModule.ts +21 -0
  76. package/src/solana/base/modules/SolanaAddresses.ts +22 -0
  77. package/src/solana/base/modules/SolanaBlocks.ts +79 -0
  78. package/src/solana/base/modules/SolanaEvents.ts +58 -0
  79. package/src/solana/base/modules/SolanaFees.ts +445 -0
  80. package/src/solana/base/modules/SolanaSignatures.ts +40 -0
  81. package/src/solana/base/modules/SolanaSlots.ts +83 -0
  82. package/src/solana/base/modules/SolanaTokens.ts +310 -0
  83. package/src/solana/base/modules/SolanaTransactions.ts +366 -0
  84. package/src/solana/btcrelay/SolanaBtcRelay.ts +591 -0
  85. package/src/solana/btcrelay/headers/SolanaBtcHeader.ts +58 -0
  86. package/src/solana/btcrelay/headers/SolanaBtcStoredHeader.ts +103 -0
  87. package/src/solana/btcrelay/program/programIdl.json +671 -0
  88. package/src/solana/events/SolanaChainEvents.ts +286 -0
  89. package/src/solana/events/SolanaChainEventsBrowser.ts +251 -0
  90. package/src/solana/program/SolanaProgramBase.ts +77 -0
  91. package/src/solana/program/modules/SolanaProgramEvents.ts +140 -0
  92. package/src/solana/swaps/SolanaSwapData.ts +360 -0
  93. package/src/solana/swaps/SolanaSwapModule.ts +17 -0
  94. package/src/solana/swaps/SolanaSwapProgram.ts +739 -0
  95. package/src/solana/swaps/SwapTypeEnum.ts +30 -0
  96. package/src/solana/swaps/modules/SolanaDataAccount.ts +309 -0
  97. package/src/solana/swaps/modules/SolanaLpVault.ts +216 -0
  98. package/src/solana/swaps/modules/SwapClaim.ts +397 -0
  99. package/src/solana/swaps/modules/SwapInit.ts +621 -0
  100. package/src/solana/swaps/modules/SwapRefund.ts +316 -0
  101. package/src/solana/swaps/programIdl.json +945 -0
  102. package/src/solana/swaps/programTypes.ts +1885 -0
  103. package/src/solana/wallet/SolanaKeypairWallet.ts +36 -0
  104. package/src/solana/wallet/SolanaSigner.ts +23 -0
  105. package/src/utils/Utils.ts +145 -0
@@ -0,0 +1,255 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.SolanaDataAccount = exports.StoredDataAccount = void 0;
13
+ const SolanaSwapModule_1 = require("../SolanaSwapModule");
14
+ const web3_js_1 = require("@solana/web3.js");
15
+ const SolanaAction_1 = require("../../base/SolanaAction");
16
+ const Utils_1 = require("../../../utils/Utils");
17
+ const randomBytes = require("randombytes");
18
+ const SolanaSigner_1 = require("../../wallet/SolanaSigner");
19
+ const BN = require("bn.js");
20
+ class StoredDataAccount {
21
+ constructor(accountKeyOrData, owner) {
22
+ if (accountKeyOrData instanceof web3_js_1.PublicKey) {
23
+ this.accountKey = accountKeyOrData;
24
+ this.owner = owner;
25
+ }
26
+ else {
27
+ this.accountKey = new web3_js_1.PublicKey(accountKeyOrData.accountKey);
28
+ this.owner = new web3_js_1.PublicKey(accountKeyOrData.owner);
29
+ }
30
+ }
31
+ serialize() {
32
+ return {
33
+ accountKey: this.accountKey.toBase58(),
34
+ owner: this.owner.toBase58()
35
+ };
36
+ }
37
+ }
38
+ exports.StoredDataAccount = StoredDataAccount;
39
+ class SolanaDataAccount extends SolanaSwapModule_1.SolanaSwapModule {
40
+ /**
41
+ * Action for initialization of the data account
42
+ *
43
+ * @param signer
44
+ * @param accountKey
45
+ * @param dataLength
46
+ * @private
47
+ */
48
+ InitDataAccount(signer, accountKey, dataLength) {
49
+ return __awaiter(this, void 0, void 0, function* () {
50
+ const accountSize = 32 + dataLength;
51
+ const lamportsDeposit = yield (0, Utils_1.tryWithRetries)(() => this.connection.getMinimumBalanceForRentExemption(accountSize), this.retryPolicy);
52
+ return new SolanaAction_1.SolanaAction(signer, this.root, [
53
+ web3_js_1.SystemProgram.createAccount({
54
+ fromPubkey: signer,
55
+ newAccountPubkey: accountKey.publicKey,
56
+ lamports: lamportsDeposit,
57
+ space: accountSize,
58
+ programId: this.program.programId
59
+ }),
60
+ yield this.program.methods
61
+ .initData()
62
+ .accounts({
63
+ signer,
64
+ data: accountKey.publicKey
65
+ })
66
+ .instruction(),
67
+ ], SolanaDataAccount.CUCosts.DATA_CREATE, null, [accountKey]);
68
+ });
69
+ }
70
+ /**
71
+ * Action for closing the specific data account
72
+ *
73
+ * @param signer
74
+ * @param publicKey
75
+ */
76
+ CloseDataAccount(signer, publicKey) {
77
+ return __awaiter(this, void 0, void 0, function* () {
78
+ return new SolanaAction_1.SolanaAction(signer, this.root, yield this.program.methods
79
+ .closeData()
80
+ .accounts({
81
+ signer,
82
+ data: publicKey
83
+ })
84
+ .instruction(), SolanaDataAccount.CUCosts.DATA_REMOVE, yield this.root.Fees.getFeeRate([signer, publicKey]));
85
+ });
86
+ }
87
+ /**
88
+ * Action for writing data to a data account, writes up to sizeLimit starting from the offset position of the
89
+ * provided writeData buffer
90
+ *
91
+ * @param signer
92
+ * @param accountKey account public key to write to
93
+ * @param writeData buffer holding the write data
94
+ * @param offset data from buffer starting at offset are written
95
+ * @param sizeLimit maximum amount of data to be written to the data account in this action
96
+ * @private
97
+ * @returns {Promise<{bytesWritten: number, action: SolanaAction}>} bytes written to the data account & action
98
+ */
99
+ WriteData(signer, accountKey, writeData, offset, sizeLimit) {
100
+ return __awaiter(this, void 0, void 0, function* () {
101
+ const writeLen = Math.min(writeData.length - offset, sizeLimit);
102
+ return {
103
+ bytesWritten: writeLen,
104
+ action: new SolanaAction_1.SolanaAction(signer, this.root, yield this.program.methods
105
+ .writeData(offset, writeData.slice(offset, offset + writeLen))
106
+ .accounts({
107
+ signer,
108
+ data: accountKey.publicKey
109
+ })
110
+ .instruction(), SolanaDataAccount.CUCosts.DATA_WRITE)
111
+ };
112
+ });
113
+ }
114
+ constructor(root, storage) {
115
+ super(root);
116
+ this.SwapTxDataAlt = this.root.keypair((reversedTxId, signer) => [Buffer.from(signer.secretKey), reversedTxId]);
117
+ this.SwapTxDataAltBuffer = this.root.keypair((reversedTxId, secret) => [secret, reversedTxId]);
118
+ this.storage = storage;
119
+ }
120
+ /**
121
+ * Saves data account to the storage, the storage is required such that we are able to close the accounts later
122
+ * manually in case the claim doesn't happen (expires due to fees, etc.)
123
+ *
124
+ * @param signer
125
+ * @param publicKey
126
+ * @private
127
+ */
128
+ saveDataAccount(signer, publicKey) {
129
+ return this.storage.saveData(publicKey.toBase58(), new StoredDataAccount(publicKey, signer));
130
+ }
131
+ /**
132
+ * Initializes the data account handler, loads the existing data accounts which should be checked and closed
133
+ */
134
+ init() {
135
+ return __awaiter(this, void 0, void 0, function* () {
136
+ yield this.storage.init();
137
+ const loadedData = yield this.storage.loadData(StoredDataAccount);
138
+ this.logger.info("init(): initialized & loaded stored data accounts, count: " + loadedData.length);
139
+ });
140
+ }
141
+ /**
142
+ * Removes data account from the list of accounts that should be checked for reclaiming the locked SOL, this should
143
+ * be called after a batch of transactions claiming the swap was confirmed
144
+ *
145
+ * @param publicKey
146
+ */
147
+ removeDataAccount(publicKey) {
148
+ return this.storage.removeData(publicKey.toBase58());
149
+ }
150
+ getDataAccountsInfo(signer) {
151
+ return __awaiter(this, void 0, void 0, function* () {
152
+ const closePublicKeys = [];
153
+ let totalLocked = new BN(0);
154
+ for (let key in this.storage.data) {
155
+ const { accountKey, owner } = this.storage.data[key];
156
+ if (!owner.equals(signer))
157
+ continue;
158
+ try {
159
+ const fetchedDataAccount = yield this.connection.getAccountInfo(accountKey);
160
+ if (fetchedDataAccount == null) {
161
+ yield this.removeDataAccount(accountKey);
162
+ continue;
163
+ }
164
+ closePublicKeys.push(accountKey);
165
+ totalLocked = totalLocked.add(new BN(fetchedDataAccount.lamports));
166
+ }
167
+ catch (e) { }
168
+ }
169
+ return {
170
+ closePublicKeys,
171
+ count: closePublicKeys.length,
172
+ totalValue: totalLocked
173
+ };
174
+ });
175
+ }
176
+ /**
177
+ * Sweeps all old data accounts, reclaiming the SOL locked in the PDAs
178
+ */
179
+ sweepDataAccounts(signer) {
180
+ return __awaiter(this, void 0, void 0, function* () {
181
+ const { closePublicKeys, totalValue } = yield this.getDataAccountsInfo(signer.getPublicKey());
182
+ if (closePublicKeys.length === 0) {
183
+ this.logger.debug("sweepDataAccounts(): no old data accounts found, no need to close any!");
184
+ return;
185
+ }
186
+ this.logger.debug("sweepDataAccounts(): closing old data accounts: ", closePublicKeys);
187
+ let txns = [];
188
+ for (let publicKey of closePublicKeys) {
189
+ yield (yield this.CloseDataAccount(signer.getPublicKey(), publicKey)).addToTxs(txns);
190
+ }
191
+ const result = yield this.root.Transactions.sendAndConfirm(signer, txns, true, null, true);
192
+ this.logger.info("sweepDataAccounts(): old data accounts closed: " +
193
+ closePublicKeys.map(pk => pk.toBase58()).join());
194
+ for (let publicKey of closePublicKeys) {
195
+ yield this.removeDataAccount(publicKey);
196
+ }
197
+ return {
198
+ txIds: result,
199
+ count: closePublicKeys.length,
200
+ totalValue: totalValue
201
+ };
202
+ });
203
+ }
204
+ /**
205
+ * Adds the transactions writing (and also initializing if it doesn't exist) data to the data account
206
+ *
207
+ * @param signer
208
+ * @param reversedTxId reversed btc tx id is used to derive the data account address
209
+ * @param writeData full data to be written to the data account
210
+ * @param txs solana transactions array, where txns for writing & initializing will be added
211
+ * @param feeRate fee rate to use for the transactions
212
+ */
213
+ addTxsWriteData(signer, reversedTxId, writeData, txs, feeRate) {
214
+ return __awaiter(this, void 0, void 0, function* () {
215
+ let txDataKey;
216
+ let fetchedDataAccount = null;
217
+ if (signer instanceof SolanaSigner_1.SolanaSigner && signer.keypair != null) {
218
+ txDataKey = this.SwapTxDataAlt(reversedTxId, signer.keypair);
219
+ fetchedDataAccount = yield (0, Utils_1.tryWithRetries)(() => this.connection.getAccountInfo(txDataKey.publicKey), this.retryPolicy);
220
+ }
221
+ else {
222
+ const secret = randomBytes(32);
223
+ txDataKey = this.SwapTxDataAltBuffer(reversedTxId, secret);
224
+ }
225
+ const signerKey = signer instanceof SolanaSigner_1.SolanaSigner ? signer.getPublicKey() : signer;
226
+ let pointer = 0;
227
+ if (fetchedDataAccount == null) {
228
+ const action = new SolanaAction_1.SolanaAction(signerKey, this.root);
229
+ action.add(yield this.InitDataAccount(signerKey, txDataKey, writeData.length));
230
+ const { bytesWritten, action: writeAction } = yield this.WriteData(signerKey, txDataKey, writeData, pointer, 420);
231
+ this.logger.debug("addTxsWriteData(): Write partial data (" + pointer + " .. " + (pointer + bytesWritten) + ")/" + writeData.length +
232
+ " key: " + txDataKey.publicKey.toBase58());
233
+ pointer += bytesWritten;
234
+ action.add(writeAction);
235
+ yield action.addToTxs(txs, feeRate);
236
+ yield this.saveDataAccount(signerKey, txDataKey.publicKey);
237
+ }
238
+ while (pointer < writeData.length) {
239
+ const { bytesWritten, action } = yield this.WriteData(signerKey, txDataKey, writeData, pointer, 950);
240
+ this.logger.debug("addTxsWriteData(): Write partial data (" + pointer + " .. " + (pointer + bytesWritten) + ")/" + writeData.length +
241
+ " key: " + txDataKey.publicKey.toBase58());
242
+ pointer += bytesWritten;
243
+ yield action.addToTxs(txs, feeRate);
244
+ }
245
+ return txDataKey.publicKey;
246
+ });
247
+ }
248
+ }
249
+ exports.SolanaDataAccount = SolanaDataAccount;
250
+ SolanaDataAccount.CUCosts = {
251
+ DATA_REMOVE: 50000,
252
+ DATA_CREATE_AND_WRITE: 15000,
253
+ DATA_CREATE: 5000,
254
+ DATA_WRITE: 15000
255
+ };
@@ -0,0 +1,72 @@
1
+ import { SolanaSwapModule } from "../SolanaSwapModule";
2
+ import * as BN from "bn.js";
3
+ import { PublicKey } from "@solana/web3.js";
4
+ import { SolanaTx } from "../../base/modules/SolanaTransactions";
5
+ import { IntermediaryReputationType } from "@atomiqlabs/base";
6
+ export declare class SolanaLpVault extends SolanaSwapModule {
7
+ private static readonly CUCosts;
8
+ /**
9
+ * Action for withdrawing funds from the LP vault
10
+ *
11
+ * @param signer
12
+ * @param token
13
+ * @param amount
14
+ * @constructor
15
+ * @private
16
+ */
17
+ private Withdraw;
18
+ /**
19
+ * Action for depositing funds to the LP vault
20
+ *
21
+ * @param signer
22
+ * @param token
23
+ * @param amount
24
+ * @constructor
25
+ * @private
26
+ */
27
+ private Deposit;
28
+ /**
29
+ * Returns intermediary's reputation & vault balance for a specific token
30
+ *
31
+ * @param address
32
+ * @param token
33
+ */
34
+ getIntermediaryData(address: PublicKey, token: PublicKey): Promise<{
35
+ balance: BN;
36
+ reputation: IntermediaryReputationType;
37
+ }>;
38
+ /**
39
+ * Returns intermediary's reputation for a specific token
40
+ *
41
+ * @param address
42
+ * @param token
43
+ */
44
+ getIntermediaryReputation(address: PublicKey, token: PublicKey): Promise<IntermediaryReputationType>;
45
+ /**
46
+ * Returns the balance of the token an intermediary has in his LP vault
47
+ *
48
+ * @param address
49
+ * @param token
50
+ */
51
+ getIntermediaryBalance(address: PublicKey, token: PublicKey): Promise<BN>;
52
+ /**
53
+ * Creates transactions for withdrawing funds from the LP vault, creates ATA if it doesn't exist and unwraps
54
+ * WSOL to SOL if required
55
+ *
56
+ * @param signer
57
+ * @param token
58
+ * @param amount
59
+ * @param feeRate
60
+ */
61
+ txsWithdraw(signer: PublicKey, token: PublicKey, amount: BN, feeRate?: string): Promise<SolanaTx[]>;
62
+ /**
63
+ * Creates transaction for depositing funds into the LP vault, wraps SOL to WSOL if required
64
+ *
65
+ * @param signer
66
+ * @param token
67
+ * @param amount
68
+ * @param feeRate
69
+ */
70
+ txsDeposit(signer: PublicKey, token: PublicKey, amount: BN, feeRate?: string): Promise<SolanaTx[]>;
71
+ getFeeRate(signer: PublicKey, token: PublicKey): Promise<string>;
72
+ }
@@ -0,0 +1,196 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.SolanaLpVault = void 0;
13
+ const SolanaSwapModule_1 = require("../SolanaSwapModule");
14
+ const SolanaAction_1 = require("../../base/SolanaAction");
15
+ const BN = require("bn.js");
16
+ const web3_js_1 = require("@solana/web3.js");
17
+ const spl_token_1 = require("@solana/spl-token");
18
+ const Utils_1 = require("../../../utils/Utils");
19
+ class SolanaLpVault extends SolanaSwapModule_1.SolanaSwapModule {
20
+ /**
21
+ * Action for withdrawing funds from the LP vault
22
+ *
23
+ * @param signer
24
+ * @param token
25
+ * @param amount
26
+ * @constructor
27
+ * @private
28
+ */
29
+ Withdraw(signer, token, amount) {
30
+ return __awaiter(this, void 0, void 0, function* () {
31
+ const ata = (0, spl_token_1.getAssociatedTokenAddressSync)(token, signer);
32
+ return new SolanaAction_1.SolanaAction(signer, this.root, yield this.program.methods
33
+ .withdraw(new BN(amount))
34
+ .accounts({
35
+ signer,
36
+ signerAta: ata,
37
+ userData: this.root.SwapUserVault(signer, token),
38
+ vault: this.root.SwapVault(token),
39
+ vaultAuthority: this.root.SwapVaultAuthority,
40
+ mint: token,
41
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID
42
+ })
43
+ .instruction(), SolanaLpVault.CUCosts.WITHDRAW);
44
+ });
45
+ }
46
+ /**
47
+ * Action for depositing funds to the LP vault
48
+ *
49
+ * @param signer
50
+ * @param token
51
+ * @param amount
52
+ * @constructor
53
+ * @private
54
+ */
55
+ Deposit(signer, token, amount) {
56
+ return __awaiter(this, void 0, void 0, function* () {
57
+ const ata = (0, spl_token_1.getAssociatedTokenAddressSync)(token, signer);
58
+ return new SolanaAction_1.SolanaAction(signer, this.root, yield this.program.methods
59
+ .deposit(new BN(amount))
60
+ .accounts({
61
+ signer,
62
+ signerAta: ata,
63
+ userData: this.root.SwapUserVault(signer, token),
64
+ vault: this.root.SwapVault(token),
65
+ vaultAuthority: this.root.SwapVaultAuthority,
66
+ mint: token,
67
+ systemProgram: web3_js_1.SystemProgram.programId,
68
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID
69
+ })
70
+ .instruction(), SolanaLpVault.CUCosts.DEPOSIT);
71
+ });
72
+ }
73
+ /**
74
+ * Returns intermediary's reputation & vault balance for a specific token
75
+ *
76
+ * @param address
77
+ * @param token
78
+ */
79
+ getIntermediaryData(address, token) {
80
+ return __awaiter(this, void 0, void 0, function* () {
81
+ const data = yield this.program.account.userAccount.fetchNullable(this.root.SwapUserVault(address, token));
82
+ if (data == null)
83
+ return null;
84
+ const response = [];
85
+ for (let i = 0; i < data.successVolume.length; i++) {
86
+ response[i] = {
87
+ successVolume: data.successVolume[i],
88
+ successCount: data.successCount[i],
89
+ failVolume: data.failVolume[i],
90
+ failCount: data.failCount[i],
91
+ coopCloseVolume: data.coopCloseVolume[i],
92
+ coopCloseCount: data.coopCloseCount[i]
93
+ };
94
+ }
95
+ return {
96
+ balance: data.amount,
97
+ reputation: response
98
+ };
99
+ });
100
+ }
101
+ /**
102
+ * Returns intermediary's reputation for a specific token
103
+ *
104
+ * @param address
105
+ * @param token
106
+ */
107
+ getIntermediaryReputation(address, token) {
108
+ return __awaiter(this, void 0, void 0, function* () {
109
+ const intermediaryData = yield this.getIntermediaryData(address, token);
110
+ return intermediaryData === null || intermediaryData === void 0 ? void 0 : intermediaryData.reputation;
111
+ });
112
+ }
113
+ /**
114
+ * Returns the balance of the token an intermediary has in his LP vault
115
+ *
116
+ * @param address
117
+ * @param token
118
+ */
119
+ getIntermediaryBalance(address, token) {
120
+ return __awaiter(this, void 0, void 0, function* () {
121
+ const intermediaryData = yield this.getIntermediaryData(address, token);
122
+ const balance = intermediaryData === null || intermediaryData === void 0 ? void 0 : intermediaryData.balance;
123
+ this.logger.debug("getIntermediaryBalance(): token LP balance fetched, token: " + token.toString() +
124
+ " address: " + address + " amount: " + (balance == null ? "null" : balance.toString()));
125
+ return intermediaryData === null || intermediaryData === void 0 ? void 0 : intermediaryData.balance;
126
+ });
127
+ }
128
+ /**
129
+ * Creates transactions for withdrawing funds from the LP vault, creates ATA if it doesn't exist and unwraps
130
+ * WSOL to SOL if required
131
+ *
132
+ * @param signer
133
+ * @param token
134
+ * @param amount
135
+ * @param feeRate
136
+ */
137
+ txsWithdraw(signer, token, amount, feeRate) {
138
+ return __awaiter(this, void 0, void 0, function* () {
139
+ const ata = yield (0, spl_token_1.getAssociatedTokenAddress)(token, signer);
140
+ feeRate = feeRate || (yield this.getFeeRate(signer, token));
141
+ const action = new SolanaAction_1.SolanaAction(signer, this.root);
142
+ if (!(yield this.root.Tokens.ataExists(ata))) {
143
+ action.add(this.root.Tokens.InitAta(signer, signer, token));
144
+ }
145
+ action.add(yield this.Withdraw(signer, token, amount));
146
+ const shouldUnwrap = token.equals(this.root.Tokens.WSOL_ADDRESS);
147
+ if (shouldUnwrap)
148
+ action.add(this.root.Tokens.Unwrap(signer));
149
+ this.logger.debug("txsWithdraw(): withdraw TX created, token: " + token.toString() +
150
+ " amount: " + amount.toString(10) + " unwrapping: " + shouldUnwrap);
151
+ return [yield action.tx(feeRate)];
152
+ });
153
+ }
154
+ /**
155
+ * Creates transaction for depositing funds into the LP vault, wraps SOL to WSOL if required
156
+ *
157
+ * @param signer
158
+ * @param token
159
+ * @param amount
160
+ * @param feeRate
161
+ */
162
+ txsDeposit(signer, token, amount, feeRate) {
163
+ return __awaiter(this, void 0, void 0, function* () {
164
+ const ata = (0, spl_token_1.getAssociatedTokenAddressSync)(token, signer);
165
+ feeRate = feeRate || (yield this.getFeeRate(signer, token));
166
+ const action = new SolanaAction_1.SolanaAction(signer, this.root);
167
+ let wrapping = false;
168
+ if (token.equals(this.root.Tokens.WSOL_ADDRESS)) {
169
+ const account = yield (0, Utils_1.tryWithRetries)(() => this.root.Tokens.getATAOrNull(ata), this.retryPolicy);
170
+ let balance = account == null ? new BN(0) : new BN(account.amount.toString());
171
+ if (balance.lt(amount)) {
172
+ action.add(this.root.Tokens.Wrap(signer, amount.sub(balance), account == null));
173
+ wrapping = true;
174
+ }
175
+ }
176
+ action.addAction(yield this.Deposit(signer, token, amount));
177
+ this.logger.debug("txsDeposit(): deposit TX created, token: " + token.toString() +
178
+ " amount: " + amount.toString(10) + " wrapping: " + wrapping);
179
+ return [yield action.tx(feeRate)];
180
+ });
181
+ }
182
+ getFeeRate(signer, token) {
183
+ const ata = (0, spl_token_1.getAssociatedTokenAddressSync)(token, signer);
184
+ return this.root.Fees.getFeeRate([
185
+ signer,
186
+ ata,
187
+ this.root.SwapUserVault(signer, token),
188
+ this.root.SwapVault(token)
189
+ ]);
190
+ }
191
+ }
192
+ exports.SolanaLpVault = SolanaLpVault;
193
+ SolanaLpVault.CUCosts = {
194
+ WITHDRAW: 50000,
195
+ DEPOSIT: 50000
196
+ };
@@ -0,0 +1,129 @@
1
+ import { SolanaSwapModule } from "../SolanaSwapModule";
2
+ import { SolanaSwapData } from "../SolanaSwapData";
3
+ import { RelaySynchronizer } from "@atomiqlabs/base";
4
+ import { PublicKey } from "@solana/web3.js";
5
+ import { SolanaTx } from "../../base/modules/SolanaTransactions";
6
+ import { SolanaBtcStoredHeader } from "../../btcrelay/headers/SolanaBtcStoredHeader";
7
+ import { SolanaBtcRelay } from "../../btcrelay/SolanaBtcRelay";
8
+ import { SolanaSwapProgram } from "../SolanaSwapProgram";
9
+ import * as BN from "bn.js";
10
+ import { SolanaSigner } from "../../wallet/SolanaSigner";
11
+ export declare class SwapClaim extends SolanaSwapModule {
12
+ private static readonly CUCosts;
13
+ readonly btcRelay: SolanaBtcRelay<any>;
14
+ /**
15
+ * Claim action which uses the provided hex encoded secret for claiming the swap
16
+ *
17
+ * @param signer
18
+ * @param swapData
19
+ * @param secret
20
+ * @constructor
21
+ * @private
22
+ */
23
+ private Claim;
24
+ /**
25
+ * Verify and claim action required for BTC on-chain swaps verified through btc relay, adds the btc relay verify
26
+ * instruction to the 0th index in the transaction, also intentionally sets compute budget to null such that no
27
+ * compute budget instruction is added, since that takes up too much space and txs are limited to 1232 bytes
28
+ *
29
+ * @param signer
30
+ * @param swapData
31
+ * @param storeDataKey
32
+ * @param merkleProof
33
+ * @param commitedHeader
34
+ * @constructor
35
+ * @private
36
+ */
37
+ private VerifyAndClaim;
38
+ constructor(root: SolanaSwapProgram, btcRelay: SolanaBtcRelay<any>);
39
+ /**
40
+ * Gets the compute budget required for claiming the swap
41
+ *
42
+ * @param swapData
43
+ * @private
44
+ */
45
+ private getComputeBudget;
46
+ /**
47
+ * Gets committed header, identified by blockhash & blockheight, determines required BTC relay blockheight based on
48
+ * requiredConfirmations
49
+ * If synchronizer is passed & blockhash is not found, it produces transactions to sync up the btc relay to the
50
+ * current chain tip & adds them to the txs array
51
+ *
52
+ * @param signer
53
+ * @param txBlockheight transaction blockheight
54
+ * @param requiredConfirmations required confirmation for the swap to be claimable with that TX
55
+ * @param blockhash blockhash of the block which includes the transaction
56
+ * @param txs solana transaction array, in case we need to synchronize the btc relay ourselves the synchronization
57
+ * txns are added here
58
+ * @param synchronizer optional synchronizer to use to synchronize the btc relay in case it is not yet synchronized
59
+ * to the required blockheight
60
+ * @private
61
+ */
62
+ private getCommitedHeaderAndSynchronize;
63
+ /**
64
+ * Adds the transactions required for initialization and writing of transaction data to the data account
65
+ *
66
+ * @param signer
67
+ * @param tx transaction to be written
68
+ * @param vout vout of the transaction to use to satisfy swap conditions
69
+ * @param feeRate fee rate for the transactions
70
+ * @param txs solana transaction array, init & write transactions are added here
71
+ * @private
72
+ * @returns {Promise<PublicKey>} publicKey/address of the data account
73
+ */
74
+ private addTxsWriteTransactionData;
75
+ /**
76
+ * Checks whether we should unwrap the WSOL to SOL when claiming the swap
77
+ *
78
+ * @param signer
79
+ * @param swapData
80
+ * @private
81
+ */
82
+ private shouldUnwrap;
83
+ /**
84
+ * Creates transactions claiming the swap using a secret (for HTLC swaps)
85
+ *
86
+ * @param signer
87
+ * @param swapData swap to claim
88
+ * @param secret hex encoded secret pre-image to the HTLC hash
89
+ * @param checkExpiry whether to check if the swap is already expired (trying to claim an expired swap with a secret
90
+ * is dangerous because we might end up revealing the secret to the counterparty without being able to claim the swap)
91
+ * @param initAta whether to init the claimer's ATA if it doesn't exist
92
+ * @param feeRate fee rate to use for the transaction
93
+ * @param skipAtaCheck whether to check if ATA exists
94
+ */
95
+ txsClaimWithSecret(signer: PublicKey, swapData: SolanaSwapData, secret: string, checkExpiry?: boolean, initAta?: boolean, feeRate?: string, skipAtaCheck?: boolean): Promise<SolanaTx[]>;
96
+ /**
97
+ * Creates transaction claiming the swap using a confirmed transaction data (for BTC on-chain swaps)
98
+ *
99
+ * @param signer
100
+ * @param swapData swap to claim
101
+ * @param blockheight blockheight of the bitcoin transaction
102
+ * @param tx bitcoin transaction that satisfies the swap condition
103
+ * @param vout vout of the bitcoin transaction that satisfies the swap condition
104
+ * @param commitedHeader commited header data from btc relay (fetched internally if null)
105
+ * @param synchronizer optional synchronizer to use in case we need to sync up the btc relay ourselves
106
+ * @param initAta whether to initialize claimer's ATA
107
+ * @param storageAccHolder an object holder filled in with the created data account where tx data is written
108
+ * @param feeRate fee rate to be used for the transactions
109
+ */
110
+ txsClaimWithTxData(signer: PublicKey | SolanaSigner, swapData: SolanaSwapData, blockheight: number, tx: {
111
+ blockhash: string;
112
+ confirmations: number;
113
+ txid: string;
114
+ hex: string;
115
+ }, vout: number, commitedHeader?: SolanaBtcStoredHeader, synchronizer?: RelaySynchronizer<any, SolanaTx, any>, initAta?: boolean, storageAccHolder?: {
116
+ storageAcc: PublicKey;
117
+ }, feeRate?: string): Promise<SolanaTx[] | null>;
118
+ getClaimFeeRate(signer: PublicKey, swapData: SolanaSwapData): Promise<string>;
119
+ /**
120
+ * Get the estimated solana transaction fee of the claim transaction, this fee might be negative since it
121
+ * includes the rebate for closing the swap PDA
122
+ */
123
+ getClaimFee(signer: PublicKey, swapData: SolanaSwapData, feeRate?: string): Promise<BN>;
124
+ /**
125
+ * Get the estimated solana transaction fee of the claim transaction in the worst case scenario in case where the
126
+ * ATA needs to be initialized again (i.e. adding the ATA rent exempt lamports to the fee)
127
+ */
128
+ getRawClaimFee(signer: PublicKey, swapData: SolanaSwapData, feeRate?: string): Promise<BN>;
129
+ }