@augustdigital/sdk 5.1.1 → 7.0.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/lib/adapters/evm/getters.d.ts +1 -1
- package/lib/adapters/evm/getters.js +14 -19
- package/lib/adapters/evm/index.d.ts +8 -1
- package/lib/adapters/evm/index.js +24 -0
- package/lib/adapters/solana/index.d.ts +4 -4
- package/lib/adapters/solana/utils.d.ts +5 -4
- package/lib/adapters/solana/utils.js +82 -45
- package/lib/adapters/solana/vault.actions.d.ts +2 -2
- package/lib/adapters/solana/vault.actions.js +112 -74
- package/lib/adapters/stellar/actions.js +3 -2
- package/lib/adapters/stellar/constants.d.ts +2 -0
- package/lib/adapters/stellar/constants.js +3 -1
- package/lib/adapters/stellar/getters.js +2 -2
- package/lib/adapters/stellar/soroban.js +19 -8
- package/lib/adapters/stellar/submit.js +16 -6
- package/lib/adapters/stellar/utils.d.ts +2 -1
- package/lib/adapters/stellar/utils.js +7 -15
- package/lib/adapters/sui/utils.d.ts +1 -1
- package/lib/adapters/sui/utils.js +3 -7
- package/lib/core/analytics/chain-name.d.ts +1 -0
- package/lib/core/analytics/chain-name.js +26 -0
- package/lib/core/analytics/env.d.ts +4 -0
- package/lib/core/analytics/env.js +33 -0
- package/lib/core/analytics/index.d.ts +6 -2
- package/lib/core/analytics/index.js +16 -1
- package/lib/core/analytics/instrumentation.js +56 -48
- package/lib/core/analytics/method-taxonomy.d.ts +3 -0
- package/lib/core/analytics/method-taxonomy.js +82 -0
- package/lib/core/analytics/metrics.js +18 -42
- package/lib/core/analytics/sanitize.d.ts +1 -0
- package/lib/core/analytics/sanitize.js +34 -0
- package/lib/core/analytics/sentry-runtime.d.ts +4 -0
- package/lib/core/analytics/sentry-runtime.js +78 -0
- package/lib/core/analytics/sentry.d.ts +7 -1
- package/lib/core/analytics/sentry.js +107 -51
- package/lib/core/analytics/types.d.ts +2 -0
- package/lib/core/analytics/version.d.ts +1 -0
- package/lib/core/analytics/version.js +5 -0
- package/lib/core/base.class.d.ts +2 -1
- package/lib/core/base.class.js +5 -1
- package/lib/core/cache.d.ts +4 -0
- package/lib/core/cache.js +25 -0
- package/lib/core/constants/web3.js +1 -1
- package/lib/core/fetcher.d.ts +4 -4
- package/lib/core/fetcher.js +49 -60
- package/lib/core/helpers/chain-address.d.ts +3 -0
- package/lib/core/helpers/chain-address.js +36 -0
- package/lib/core/helpers/explorer-link.d.ts +2 -0
- package/lib/core/helpers/explorer-link.js +11 -0
- package/lib/core/helpers/vault-version.d.ts +4 -0
- package/lib/core/helpers/vault-version.js +59 -0
- package/lib/core/helpers/vaults.d.ts +3 -4
- package/lib/core/helpers/vaults.js +12 -62
- package/lib/core/helpers/web3.d.ts +6 -6
- package/lib/core/helpers/web3.js +142 -79
- package/lib/core/logger/slack.js +2 -2
- package/lib/core/vault-metadata.d.ts +6 -0
- package/lib/core/vault-metadata.js +36 -0
- package/lib/evm/methods/crossChainVault.js +72 -16
- package/lib/evm/types/crossChain.d.ts +4 -0
- package/lib/evm/types/crossChain.js +6 -0
- package/lib/modules/vaults/fetcher.d.ts +1 -6
- package/lib/modules/vaults/fetcher.js +27 -36
- package/lib/modules/vaults/getters.d.ts +1 -1
- package/lib/modules/vaults/getters.js +3 -2
- package/lib/modules/vaults/read.actions.d.ts +27 -0
- package/lib/modules/vaults/read.actions.js +220 -0
- package/lib/modules/vaults/utils/date-utils.js +1 -2
- package/lib/modules/vaults/utils.js +57 -36
- package/lib/modules/vaults/write.actions.d.ts +35 -2
- package/lib/modules/vaults/write.actions.js +254 -94
- package/package.json +5 -2
|
@@ -7,14 +7,18 @@ const web3_js_1 = require("@solana/web3.js");
|
|
|
7
7
|
const spl_token_1 = require("@solana/spl-token");
|
|
8
8
|
const constants_1 = require("./constants");
|
|
9
9
|
const utils_1 = require("./utils");
|
|
10
|
+
const core_1 = require("../../core");
|
|
10
11
|
async function handleSolanaDeposit({ provider, connection, network = constants_1.fallbackNetwork, vaultProgramId, vaultAddress, depositAmount, publicKey, sendTransaction, idl, }) {
|
|
11
12
|
try {
|
|
12
13
|
if (!publicKey)
|
|
13
|
-
throw new
|
|
14
|
-
if (
|
|
15
|
-
|
|
14
|
+
throw new core_1.AugustValidationError('INVALID_INPUT', 'handleSolanaDeposit: wallet not connected');
|
|
15
|
+
if (depositAmount === undefined ||
|
|
16
|
+
depositAmount === null ||
|
|
17
|
+
(typeof depositAmount === 'bigint' && depositAmount <= 0n) ||
|
|
18
|
+
(typeof depositAmount === 'number' && !(depositAmount > 0)))
|
|
19
|
+
throw new core_1.AugustValidationError('INVALID_INPUT', 'handleSolanaDeposit: depositAmount is required and must be > 0');
|
|
16
20
|
if (!vaultProgramId)
|
|
17
|
-
throw new
|
|
21
|
+
throw new core_1.AugustValidationError('INVALID_INPUT', 'handleSolanaDeposit: vaultProgramId is required');
|
|
18
22
|
const { depositMint, shareMint, vaultVersion } = await utils_1.SolanaUtils.getVaultMints({
|
|
19
23
|
network,
|
|
20
24
|
connection,
|
|
@@ -33,71 +37,72 @@ async function handleSolanaDeposit({ provider, connection, network = constants_1
|
|
|
33
37
|
idl,
|
|
34
38
|
programId: _vaultProgramId.toBase58(),
|
|
35
39
|
});
|
|
36
|
-
|
|
40
|
+
core_1.Logger.log.info('handleSolanaDeposit', 'Program', program);
|
|
37
41
|
const vaultStatePda = vaultAddress
|
|
38
42
|
? new web3_js_1.PublicKey(vaultAddress)
|
|
39
43
|
: utils_1.SolanaUtils.deriveVaultStatePda(_vaultProgramId);
|
|
40
|
-
|
|
44
|
+
core_1.Logger.log.info('handleSolanaDeposit', 'Vault state PDA', vaultStatePda.toBase58());
|
|
41
45
|
const vaultTokenAtaPda = utils_1.SolanaUtils.deriveVaultTokenAtaPda(_vaultProgramId, _depositMint, vaultVersion);
|
|
42
|
-
|
|
46
|
+
core_1.Logger.log.info('handleSolanaDeposit', 'Vault token ATA PDA', vaultTokenAtaPda.toBase58());
|
|
43
47
|
const shareMintAddr = new web3_js_1.PublicKey(shareMint);
|
|
44
|
-
|
|
48
|
+
core_1.Logger.log.info('handleSolanaDeposit', 'Share mint', shareMintAddr.toBase58());
|
|
45
49
|
const mintInfo = await connection.getParsedAccountInfo(_depositMint);
|
|
46
50
|
if (!mintInfo.value) {
|
|
47
51
|
throw new Error('Could not fetch mint info');
|
|
48
52
|
}
|
|
49
53
|
const { decimals } = mintInfo.value.data.parsed.info;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const paddedFraction = fraction.padEnd(decimals, '0').slice(0, decimals);
|
|
54
|
-
const rawAmountStr = whole + paddedFraction;
|
|
55
|
-
const depositAmountRaw = new anchor_1.BN(rawAmountStr.replace(/^0+/, '') || '0');
|
|
56
|
-
if (isNaN(depositAmount)) {
|
|
57
|
-
throw new Error('Please enter a valid number for the deposit amount');
|
|
54
|
+
let depositAmountRaw;
|
|
55
|
+
if (typeof depositAmount === 'bigint') {
|
|
56
|
+
depositAmountRaw = new anchor_1.BN(depositAmount.toString());
|
|
58
57
|
}
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
else {
|
|
59
|
+
if (isNaN(depositAmount)) {
|
|
60
|
+
throw new core_1.AugustValidationError('INVALID_INPUT', 'Please enter a valid number for the deposit amount');
|
|
61
|
+
}
|
|
62
|
+
if (depositAmount <= 0) {
|
|
63
|
+
throw new core_1.AugustValidationError('INVALID_INPUT', 'Deposit amount must be greater than 0');
|
|
64
|
+
}
|
|
65
|
+
depositAmountRaw = (0, utils_1.uiAmountToRawBn)(depositAmount, decimals);
|
|
61
66
|
}
|
|
62
67
|
const userTokenAccounts = await connection.getParsedTokenAccountsByOwner(_publicKey, {
|
|
63
68
|
mint: _depositMint,
|
|
64
69
|
});
|
|
65
|
-
|
|
70
|
+
core_1.Logger.log.info('handleSolanaDeposit', 'User token accounts', userTokenAccounts);
|
|
66
71
|
const userShareAccounts = await connection.getParsedTokenAccountsByOwner(_publicKey, {
|
|
67
72
|
mint: shareMintAddr,
|
|
68
73
|
});
|
|
69
|
-
|
|
74
|
+
core_1.Logger.log.info('handleSolanaDeposit', 'User share accounts', userShareAccounts);
|
|
70
75
|
if (userTokenAccounts.value.length === 0) {
|
|
71
|
-
throw new
|
|
76
|
+
throw new core_1.AugustValidationError('INVALID_INPUT', 'No token account found for deposit mint. Please create a token account first.');
|
|
72
77
|
}
|
|
73
78
|
let senderShareAccount;
|
|
74
79
|
if (userShareAccounts.value.length === 0) {
|
|
75
|
-
|
|
80
|
+
core_1.Logger.log.info('handleSolanaDeposit', 'Creating share account');
|
|
76
81
|
senderShareAccount = await (0, spl_token_1.getAssociatedTokenAddress)(shareMintAddr, _publicKey);
|
|
77
|
-
|
|
82
|
+
core_1.Logger.log.info('handleSolanaDeposit', 'Sender share account', senderShareAccount.toBase58());
|
|
78
83
|
const createAtaIx = (0, spl_token_1.createAssociatedTokenAccountInstruction)(_publicKey, senderShareAccount, _publicKey, shareMintAddr);
|
|
79
|
-
|
|
84
|
+
core_1.Logger.log.info('handleSolanaDeposit', 'Create ATA Ix', createAtaIx.programId.toBase58());
|
|
80
85
|
const transaction = new web3_js_1.Transaction().add(createAtaIx);
|
|
81
86
|
const signature = await sendTransaction(transaction, connection);
|
|
82
|
-
|
|
87
|
+
core_1.Logger.log.info('handleSolanaDeposit', 'Created share account:', signature.toString());
|
|
83
88
|
}
|
|
84
89
|
else {
|
|
85
90
|
senderShareAccount = userShareAccounts.value[0]?.pubkey;
|
|
86
91
|
}
|
|
87
92
|
const senderTokenAccount = userTokenAccounts.value[0]?.pubkey;
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
93
|
+
core_1.Logger.log.info('handleSolanaDeposit', 'Sender token account', senderTokenAccount);
|
|
94
|
+
core_1.Logger.log.info('handleSolanaDeposit', '\n\nDeposit TX Params:\n');
|
|
95
|
+
core_1.Logger.log.info('handleSolanaDeposit', 'Program', depositAmountRaw);
|
|
96
|
+
core_1.Logger.log.info('handleSolanaDeposit', 'Vault state PDA', vaultStatePda.toBase58());
|
|
97
|
+
core_1.Logger.log.info('handleSolanaDeposit', 'Vault token ATA PDA', vaultTokenAtaPda.toBase58());
|
|
98
|
+
core_1.Logger.log.info('handleSolanaDeposit', 'Sender token account', senderTokenAccount?.toBase58());
|
|
99
|
+
core_1.Logger.log.info('handleSolanaDeposit', 'Sender share account', senderShareAccount?.toBase58());
|
|
100
|
+
core_1.Logger.log.info('handleSolanaDeposit', 'Share mint', shareMintAddr.toBase58());
|
|
101
|
+
core_1.Logger.log.info('handleSolanaDeposit', 'Deposit mint', _depositMint?.toBase58());
|
|
102
|
+
core_1.Logger.log.info('handleSolanaDeposit', 'Signer', _publicKey.toBase58());
|
|
98
103
|
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('confirmed');
|
|
99
104
|
const tx = await program.methods
|
|
100
|
-
.deposit(
|
|
105
|
+
.deposit(depositAmountRaw)
|
|
101
106
|
.accounts({
|
|
102
107
|
vaultState: vaultStatePda,
|
|
103
108
|
vaultTokenAta: vaultTokenAtaPda,
|
|
@@ -112,7 +117,7 @@ async function handleSolanaDeposit({ provider, connection, network = constants_1
|
|
|
112
117
|
skipPreflight: false,
|
|
113
118
|
preflightCommitment: 'confirmed',
|
|
114
119
|
});
|
|
115
|
-
|
|
120
|
+
core_1.Logger.log.info('handleSolanaDeposit', 'Deposit successful:', tx);
|
|
116
121
|
await connection.confirmTransaction({
|
|
117
122
|
signature: tx,
|
|
118
123
|
blockhash,
|
|
@@ -121,18 +126,37 @@ async function handleSolanaDeposit({ provider, connection, network = constants_1
|
|
|
121
126
|
return tx;
|
|
122
127
|
}
|
|
123
128
|
catch (e) {
|
|
124
|
-
|
|
125
|
-
|
|
129
|
+
if (e instanceof core_1.AugustSDKError)
|
|
130
|
+
throw e;
|
|
131
|
+
const depositAmountForLog = typeof depositAmount === 'bigint'
|
|
132
|
+
? depositAmount.toString()
|
|
133
|
+
: depositAmount;
|
|
134
|
+
core_1.Logger.log.error('handleSolanaDeposit', e, {
|
|
135
|
+
vaultProgramId: String(vaultProgramId),
|
|
136
|
+
vaultAddress: vaultAddress ? String(vaultAddress) : undefined,
|
|
137
|
+
depositAmount: depositAmountForLog,
|
|
138
|
+
});
|
|
139
|
+
throw new core_1.AugustSDKError('UNKNOWN', `Solana deposit failed: ${e instanceof Error ? e.message : 'Unknown error'}`, {
|
|
140
|
+
cause: e,
|
|
141
|
+
context: {
|
|
142
|
+
vaultProgramId: String(vaultProgramId),
|
|
143
|
+
vaultAddress: vaultAddress ? String(vaultAddress) : undefined,
|
|
144
|
+
depositAmount: depositAmountForLog,
|
|
145
|
+
},
|
|
146
|
+
});
|
|
126
147
|
}
|
|
127
148
|
}
|
|
128
149
|
async function handleSolanaRedeem({ provider, connection, vaultProgramId, vaultAddress, publicKey, redeemShares, sendTransaction, idl, }) {
|
|
129
150
|
try {
|
|
130
151
|
if (!publicKey)
|
|
131
|
-
throw new
|
|
132
|
-
if (
|
|
133
|
-
|
|
152
|
+
throw new core_1.AugustValidationError('INVALID_INPUT', 'handleSolanaRedeem: wallet not connected');
|
|
153
|
+
if (redeemShares === undefined ||
|
|
154
|
+
redeemShares === null ||
|
|
155
|
+
(typeof redeemShares === 'bigint' && redeemShares <= 0n) ||
|
|
156
|
+
(typeof redeemShares === 'number' && !(redeemShares > 0)))
|
|
157
|
+
throw new core_1.AugustValidationError('INVALID_INPUT', 'handleSolanaRedeem: redeemShares is required and must be > 0');
|
|
134
158
|
if (!vaultProgramId)
|
|
135
|
-
throw new
|
|
159
|
+
throw new core_1.AugustValidationError('INVALID_INPUT', 'handleSolanaRedeem: vaultProgramId is required');
|
|
136
160
|
const { depositMint, shareMint, vaultVersion } = await utils_1.SolanaUtils.getVaultMints({
|
|
137
161
|
network: provider.connection.rpcEndpoint.includes('devnet')
|
|
138
162
|
? 'devnet'
|
|
@@ -164,18 +188,18 @@ async function handleSolanaRedeem({ provider, connection, vaultProgramId, vaultA
|
|
|
164
188
|
}
|
|
165
189
|
const shareDecimals = shareMintInfo.value.data.parsed.info
|
|
166
190
|
.decimals;
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
.padEnd(shareDecimals, '0')
|
|
171
|
-
.slice(0, shareDecimals);
|
|
172
|
-
const rawAmountStr = whole + paddedFraction;
|
|
173
|
-
const redeemSharesRaw = parseInt(rawAmountStr.replace(/^0+/, '') || '0', 10);
|
|
174
|
-
if (isNaN(redeemShares)) {
|
|
175
|
-
throw new Error('Please enter a valid number for the shares to redeem');
|
|
191
|
+
let redeemSharesRaw;
|
|
192
|
+
if (typeof redeemShares === 'bigint') {
|
|
193
|
+
redeemSharesRaw = new anchor_1.BN(redeemShares.toString());
|
|
176
194
|
}
|
|
177
|
-
|
|
178
|
-
|
|
195
|
+
else {
|
|
196
|
+
if (isNaN(redeemShares)) {
|
|
197
|
+
throw new core_1.AugustValidationError('INVALID_INPUT', 'Please enter a valid number for the shares to redeem');
|
|
198
|
+
}
|
|
199
|
+
if (redeemShares <= 0) {
|
|
200
|
+
throw new core_1.AugustValidationError('INVALID_INPUT', 'Shares to redeem must be greater than 0');
|
|
201
|
+
}
|
|
202
|
+
redeemSharesRaw = (0, utils_1.uiAmountToRawBn)(redeemShares, shareDecimals);
|
|
179
203
|
}
|
|
180
204
|
const userTokenAccounts = await connection.getParsedTokenAccountsByOwner(_publicKey, {
|
|
181
205
|
mint: _depositMint,
|
|
@@ -184,10 +208,10 @@ async function handleSolanaRedeem({ provider, connection, vaultProgramId, vaultA
|
|
|
184
208
|
mint: shareMintAddr,
|
|
185
209
|
});
|
|
186
210
|
if (userTokenAccounts.value.length === 0) {
|
|
187
|
-
throw new
|
|
211
|
+
throw new core_1.AugustValidationError('INVALID_INPUT', 'No token account found for deposit mint. Please create a token account first.');
|
|
188
212
|
}
|
|
189
213
|
if (userShareAccounts.value.length === 0) {
|
|
190
|
-
throw new
|
|
214
|
+
throw new core_1.AugustValidationError('INVALID_INPUT', 'No share account found. You need to deposit first to get shares before you can redeem.');
|
|
191
215
|
}
|
|
192
216
|
const senderTokenAccount = userTokenAccounts?.value[0]?.pubkey;
|
|
193
217
|
const senderShareAccount = userShareAccounts?.value[0]?.pubkey;
|
|
@@ -204,27 +228,27 @@ async function handleSolanaRedeem({ provider, connection, vaultProgramId, vaultA
|
|
|
204
228
|
const createFeeRecipientAtaIx = (0, spl_token_1.createAssociatedTokenAccountInstruction)(_publicKey, feeRecipientTokenAccount, vaultStateData.feeRecipient, _depositMint);
|
|
205
229
|
const createAccountTx = new web3_js_1.Transaction().add(createFeeRecipientAtaIx);
|
|
206
230
|
const createAccountSignature = await sendTransaction(createAccountTx, connection);
|
|
207
|
-
|
|
231
|
+
core_1.Logger.log.info('handleSolanaRedeem', 'Fee recipient token account created:', createAccountSignature);
|
|
208
232
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
209
233
|
}
|
|
210
234
|
else {
|
|
211
|
-
|
|
235
|
+
core_1.Logger.log.info('handleSolanaRedeem', 'Fee recipient token account already exists');
|
|
212
236
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
237
|
+
core_1.Logger.log.info('handleSolanaRedeem', '\n\nRedeem TX Params:\n');
|
|
238
|
+
core_1.Logger.log.info('handleSolanaRedeem', 'Redeem shares (UI):', redeemShares);
|
|
239
|
+
core_1.Logger.log.info('handleSolanaRedeem', 'Redeem shares (raw):', redeemSharesRaw);
|
|
240
|
+
core_1.Logger.log.info('handleSolanaRedeem', 'Share decimals:', shareDecimals);
|
|
241
|
+
core_1.Logger.log.info('handleSolanaRedeem', 'Vault state PDA:', vaultStatePda.toBase58());
|
|
242
|
+
core_1.Logger.log.info('handleSolanaRedeem', 'Vault token ATA PDA:', vaultTokenAtaPda.toBase58());
|
|
243
|
+
core_1.Logger.log.info('handleSolanaRedeem', 'Sender token account:', senderTokenAccount?.toBase58());
|
|
244
|
+
core_1.Logger.log.info('handleSolanaRedeem', 'Sender share account:', senderShareAccount?.toBase58());
|
|
245
|
+
core_1.Logger.log.info('handleSolanaRedeem', 'Fee recipient account:', feeRecipientTokenAccount.toBase58());
|
|
246
|
+
core_1.Logger.log.info('handleSolanaRedeem', 'Share mint:', shareMintAddr.toBase58());
|
|
247
|
+
core_1.Logger.log.info('handleSolanaRedeem', 'Deposit mint:', _depositMint?.toBase58());
|
|
248
|
+
core_1.Logger.log.info('handleSolanaRedeem', 'Signer:', _publicKey.toBase58());
|
|
225
249
|
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('confirmed');
|
|
226
250
|
const tx = await program.methods
|
|
227
|
-
.redeem(
|
|
251
|
+
.redeem(redeemSharesRaw)
|
|
228
252
|
.accounts({
|
|
229
253
|
vaultState: vaultStatePda,
|
|
230
254
|
vaultDepositAta: vaultTokenAtaPda,
|
|
@@ -240,7 +264,7 @@ async function handleSolanaRedeem({ provider, connection, vaultProgramId, vaultA
|
|
|
240
264
|
skipPreflight: false,
|
|
241
265
|
preflightCommitment: 'confirmed',
|
|
242
266
|
});
|
|
243
|
-
|
|
267
|
+
core_1.Logger.log.info('handleSolanaRedeem', 'Redeem successful:', tx);
|
|
244
268
|
await connection.confirmTransaction({
|
|
245
269
|
signature: tx,
|
|
246
270
|
blockhash,
|
|
@@ -249,8 +273,22 @@ async function handleSolanaRedeem({ provider, connection, vaultProgramId, vaultA
|
|
|
249
273
|
return tx;
|
|
250
274
|
}
|
|
251
275
|
catch (e) {
|
|
252
|
-
|
|
253
|
-
|
|
276
|
+
if (e instanceof core_1.AugustSDKError)
|
|
277
|
+
throw e;
|
|
278
|
+
const redeemSharesForLog = typeof redeemShares === 'bigint' ? redeemShares.toString() : redeemShares;
|
|
279
|
+
core_1.Logger.log.error('handleSolanaRedeem', e, {
|
|
280
|
+
vaultProgramId: String(vaultProgramId),
|
|
281
|
+
vaultAddress: vaultAddress ? String(vaultAddress) : undefined,
|
|
282
|
+
redeemShares: redeemSharesForLog,
|
|
283
|
+
});
|
|
284
|
+
throw new core_1.AugustSDKError('UNKNOWN', `Solana redeem failed: ${e instanceof Error ? e.message : 'Unknown error'}`, {
|
|
285
|
+
cause: e,
|
|
286
|
+
context: {
|
|
287
|
+
vaultProgramId: String(vaultProgramId),
|
|
288
|
+
vaultAddress: vaultAddress ? String(vaultAddress) : undefined,
|
|
289
|
+
redeemShares: redeemSharesForLog,
|
|
290
|
+
},
|
|
291
|
+
});
|
|
254
292
|
}
|
|
255
293
|
}
|
|
256
294
|
//# sourceMappingURL=vault.actions.js.map
|
|
@@ -5,14 +5,15 @@ exports.handleStellarRedeem = handleStellarRedeem;
|
|
|
5
5
|
const stellar_sdk_1 = require("@stellar/stellar-sdk");
|
|
6
6
|
const soroban_1 = require("./soroban");
|
|
7
7
|
const utils_1 = require("./utils");
|
|
8
|
+
const core_1 = require("../../core");
|
|
8
9
|
function validateContractAddress(contractId) {
|
|
9
10
|
if (!(0, utils_1.isStellarAddress)(contractId) || contractId[0] !== 'C') {
|
|
10
|
-
throw new
|
|
11
|
+
throw new core_1.AugustValidationError('INVALID_ADDRESS', `Invalid contract address: expected a Stellar contract (C-prefix), got "${contractId}"`);
|
|
11
12
|
}
|
|
12
13
|
}
|
|
13
14
|
function validateAccountAddress(address, label) {
|
|
14
15
|
if (!(0, utils_1.isStellarAddress)(address) || address[0] !== 'G') {
|
|
15
|
-
throw new
|
|
16
|
+
throw new core_1.AugustValidationError('INVALID_ADDRESS', `Invalid ${label} address: expected a Stellar account (G-prefix), got "${address}"`);
|
|
16
17
|
}
|
|
17
18
|
}
|
|
18
19
|
function buildSelfOperationArgs(amount, userAddress) {
|
|
@@ -12,4 +12,6 @@ export declare const TX_TIMEOUT_SECONDS = 120;
|
|
|
12
12
|
export declare const QUERY_TIMEOUT_SECONDS = 10;
|
|
13
13
|
export declare const MAX_FEE_STROOPS = "1000000";
|
|
14
14
|
export declare const POLL_INTERVAL_MS = 2000;
|
|
15
|
+
export declare const POLL_INTERVAL_MAX_MS = 8000;
|
|
16
|
+
export declare const POLL_INTERVAL_BACKOFF = 1.5;
|
|
15
17
|
export declare const MAX_POLL_ATTEMPTS = 30;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MAX_POLL_ATTEMPTS = exports.POLL_INTERVAL_MS = exports.MAX_FEE_STROOPS = exports.QUERY_TIMEOUT_SECONDS = exports.TX_TIMEOUT_SECONDS = exports.STELLAR_FALLBACK_DECIMALS = exports.NETWORK_PASSPHRASES = exports.SOROBAN_RPC_URLS = exports.STELLAR_CHAIN = exports.STELLAR_CHAIN_ID = void 0;
|
|
3
|
+
exports.MAX_POLL_ATTEMPTS = exports.POLL_INTERVAL_BACKOFF = exports.POLL_INTERVAL_MAX_MS = exports.POLL_INTERVAL_MS = exports.MAX_FEE_STROOPS = exports.QUERY_TIMEOUT_SECONDS = exports.TX_TIMEOUT_SECONDS = exports.STELLAR_FALLBACK_DECIMALS = exports.NETWORK_PASSPHRASES = exports.SOROBAN_RPC_URLS = exports.STELLAR_CHAIN = exports.STELLAR_CHAIN_ID = void 0;
|
|
4
4
|
const stellar_sdk_1 = require("@stellar/stellar-sdk");
|
|
5
5
|
const web3_1 = require("../../core/constants/web3");
|
|
6
6
|
exports.STELLAR_CHAIN_ID = web3_1.SPECIAL_CHAINS.stellar.chainId;
|
|
@@ -18,5 +18,7 @@ exports.TX_TIMEOUT_SECONDS = 120;
|
|
|
18
18
|
exports.QUERY_TIMEOUT_SECONDS = 10;
|
|
19
19
|
exports.MAX_FEE_STROOPS = '1000000';
|
|
20
20
|
exports.POLL_INTERVAL_MS = 2000;
|
|
21
|
+
exports.POLL_INTERVAL_MAX_MS = 8000;
|
|
22
|
+
exports.POLL_INTERVAL_BACKOFF = 1.5;
|
|
21
23
|
exports.MAX_POLL_ATTEMPTS = 30;
|
|
22
24
|
//# sourceMappingURL=constants.js.map
|
|
@@ -118,7 +118,7 @@ const getStellarUserPosition = async (vaultAddress, walletAddress, network = 'ma
|
|
|
118
118
|
userAddress = new stellar_sdk_1.Address(walletAddress);
|
|
119
119
|
}
|
|
120
120
|
catch (addrErr) {
|
|
121
|
-
throw new
|
|
121
|
+
throw new core_1.AugustValidationError('INVALID_ADDRESS', `getStellarUserPosition: invalid walletAddress "${walletAddress}": ${String(addrErr)}`, { cause: addrErr });
|
|
122
122
|
}
|
|
123
123
|
try {
|
|
124
124
|
const [balanceResult, decimalsResult] = await Promise.all([
|
|
@@ -165,7 +165,7 @@ const convertToShares = async (vaultAddress, rawAmount, network = 'mainnet') =>
|
|
|
165
165
|
new stellar_sdk_1.Address(vaultAddress);
|
|
166
166
|
}
|
|
167
167
|
catch (addrErr) {
|
|
168
|
-
throw new
|
|
168
|
+
throw new core_1.AugustValidationError('INVALID_ADDRESS', `convertToShares: invalid vaultAddress "${vaultAddress}": ${String(addrErr)}`, { cause: addrErr });
|
|
169
169
|
}
|
|
170
170
|
const config = (0, soroban_1.resolveNetworkConfig)(network);
|
|
171
171
|
const amountBigInt = (0, soroban_1.toBigIntAmount)(rawAmount, 'rawAmount');
|
|
@@ -21,17 +21,17 @@ function resolveNetworkConfig(network) {
|
|
|
21
21
|
}
|
|
22
22
|
function toBigIntAmount(value, label) {
|
|
23
23
|
if (value === '') {
|
|
24
|
-
throw new
|
|
24
|
+
throw new core_1.AugustValidationError('INVALID_INPUT', `Invalid ${label}: value must not be empty`);
|
|
25
25
|
}
|
|
26
26
|
let result;
|
|
27
27
|
try {
|
|
28
28
|
result = BigInt(value);
|
|
29
29
|
}
|
|
30
30
|
catch {
|
|
31
|
-
throw new
|
|
31
|
+
throw new core_1.AugustValidationError('INVALID_INPUT', `Invalid ${label}: "${value}" is not a valid integer string`);
|
|
32
32
|
}
|
|
33
33
|
if (result < 0n) {
|
|
34
|
-
throw new
|
|
34
|
+
throw new core_1.AugustValidationError('INVALID_INPUT', `Invalid ${label}: value must be non-negative, got "${value}"`);
|
|
35
35
|
}
|
|
36
36
|
return result;
|
|
37
37
|
}
|
|
@@ -78,7 +78,18 @@ async function queryContract(config, contractId, method, args = []) {
|
|
|
78
78
|
}
|
|
79
79
|
async function buildSorobanTx(config, sourceAddress, contractId, method, args) {
|
|
80
80
|
const server = createServer(config.rpcUrl);
|
|
81
|
-
|
|
81
|
+
let account;
|
|
82
|
+
try {
|
|
83
|
+
account = await server.getAccount(sourceAddress);
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
87
|
+
const isAccountNotFound = err instanceof stellar_sdk_1.NotFoundError || /Account not found/.test(msg);
|
|
88
|
+
if (isAccountNotFound) {
|
|
89
|
+
throw new core_1.AugustValidationError('INVALID_INPUT', `Stellar account ${sourceAddress} is not funded. Send at least 1 XLM to this address to activate it before depositing or redeeming.`, { cause: err, context: { sourceAddress, method, contractId } });
|
|
90
|
+
}
|
|
91
|
+
throw err;
|
|
92
|
+
}
|
|
82
93
|
const contract = new stellar_sdk_1.Contract(contractId);
|
|
83
94
|
const tx = new stellar_sdk_1.TransactionBuilder(account, {
|
|
84
95
|
fee: constants_1.MAX_FEE_STROOPS,
|
|
@@ -89,18 +100,18 @@ async function buildSorobanTx(config, sourceAddress, contractId, method, args) {
|
|
|
89
100
|
.build();
|
|
90
101
|
const simulated = await server.simulateTransaction(tx);
|
|
91
102
|
if (stellar_sdk_1.rpc.Api.isSimulationError(simulated)) {
|
|
92
|
-
throw new
|
|
103
|
+
throw new core_1.AugustSDKError('UNKNOWN', `Soroban simulation failed: ${extractSimulationError(simulated)}`, { context: { method, contractId } });
|
|
93
104
|
}
|
|
94
105
|
if ('restorePreamble' in simulated && simulated.restorePreamble) {
|
|
95
|
-
throw new
|
|
96
|
-
'Submit a restore footprint transaction first.');
|
|
106
|
+
throw new core_1.AugustSDKError('UNKNOWN', `Contract ledger state needs restoration before invoking ${method}. ` +
|
|
107
|
+
'Submit a restore footprint transaction first.', { context: { method, contractId } });
|
|
97
108
|
}
|
|
98
109
|
try {
|
|
99
110
|
const assembled = stellar_sdk_1.rpc.assembleTransaction(tx, simulated).build();
|
|
100
111
|
return assembled.toXDR();
|
|
101
112
|
}
|
|
102
113
|
catch (assemblyErr) {
|
|
103
|
-
throw new
|
|
114
|
+
throw new core_1.AugustSDKError('UNKNOWN', `Failed to assemble Soroban transaction for ${method}: ${String(assemblyErr)}`, { cause: assemblyErr, context: { method, contractId } });
|
|
104
115
|
}
|
|
105
116
|
}
|
|
106
117
|
//# sourceMappingURL=soroban.js.map
|
|
@@ -14,26 +14,34 @@ async function submitStellarTransaction(signedXdr, network) {
|
|
|
14
14
|
const detail = 'errorResult' in sendResult ? JSON.stringify(sendResult.errorResult) : '';
|
|
15
15
|
const msg = `Transaction submission failed: ${detail || sendResult.status}`;
|
|
16
16
|
core_1.Logger.log.error('submitStellarTransaction', msg, { network });
|
|
17
|
-
throw new
|
|
17
|
+
throw new core_1.AugustSDKError('UNKNOWN', msg, {
|
|
18
|
+
context: { network, status: sendResult.status },
|
|
19
|
+
});
|
|
18
20
|
}
|
|
19
21
|
if (sendResult.status !== 'PENDING' && sendResult.status !== 'DUPLICATE') {
|
|
20
22
|
const msg = `Transaction not accepted by RPC (status: ${sendResult.status}). ` +
|
|
21
23
|
'This may be retryable — the RPC node could be overloaded.';
|
|
22
24
|
core_1.Logger.log.error('submitStellarTransaction', msg, { network });
|
|
23
|
-
throw new
|
|
25
|
+
throw new core_1.AugustSDKError('UNKNOWN', msg, {
|
|
26
|
+
context: { network, status: sendResult.status },
|
|
27
|
+
});
|
|
24
28
|
}
|
|
25
29
|
let getResult = await server.getTransaction(sendResult.hash);
|
|
26
30
|
let polls = 0;
|
|
31
|
+
let nextDelay = constants_1.POLL_INTERVAL_MS;
|
|
27
32
|
while (getResult.status === 'NOT_FOUND') {
|
|
28
33
|
if (++polls >= constants_1.MAX_POLL_ATTEMPTS) {
|
|
29
|
-
const msg = `Transaction ${sendResult.hash} not confirmed after ${
|
|
34
|
+
const msg = `Transaction ${sendResult.hash} not confirmed after ${constants_1.MAX_POLL_ATTEMPTS} poll attempts`;
|
|
30
35
|
core_1.Logger.log.error('submitStellarTransaction', msg, {
|
|
31
36
|
hash: sendResult.hash,
|
|
32
37
|
network,
|
|
33
38
|
});
|
|
34
|
-
throw new
|
|
39
|
+
throw new core_1.AugustTimeoutError(msg, constants_1.POLL_INTERVAL_MAX_MS * polls, {
|
|
40
|
+
context: { hash: sendResult.hash, network },
|
|
41
|
+
});
|
|
35
42
|
}
|
|
36
|
-
await new Promise((r) => setTimeout(r,
|
|
43
|
+
await new Promise((r) => setTimeout(r, nextDelay));
|
|
44
|
+
nextDelay = Math.min(Math.round(nextDelay * constants_1.POLL_INTERVAL_BACKOFF), constants_1.POLL_INTERVAL_MAX_MS);
|
|
37
45
|
getResult = await server.getTransaction(sendResult.hash);
|
|
38
46
|
}
|
|
39
47
|
if (getResult.status === 'SUCCESS') {
|
|
@@ -45,6 +53,8 @@ async function submitStellarTransaction(signedXdr, network) {
|
|
|
45
53
|
hash: sendResult.hash,
|
|
46
54
|
network,
|
|
47
55
|
});
|
|
48
|
-
throw new
|
|
56
|
+
throw new core_1.AugustSDKError('UNKNOWN', msg, {
|
|
57
|
+
context: { hash: sendResult.hash, network, status: getResult.status },
|
|
58
|
+
});
|
|
49
59
|
}
|
|
50
60
|
//# sourceMappingURL=submit.js.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { IStellarNetwork } from './types';
|
|
2
|
-
|
|
2
|
+
import { isStellarAddress } from '../../core/helpers/chain-address';
|
|
3
|
+
export { isStellarAddress };
|
|
3
4
|
export declare function getExplorerLink({ id, type, network, }: {
|
|
4
5
|
id: string;
|
|
5
6
|
type?: 'contract' | 'account' | 'tx';
|
|
@@ -1,31 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.StellarUtils = void 0;
|
|
4
|
-
exports.isStellarAddress = isStellarAddress;
|
|
3
|
+
exports.StellarUtils = exports.isStellarAddress = void 0;
|
|
5
4
|
exports.getExplorerLink = getExplorerLink;
|
|
6
5
|
exports.assertNotStellar = assertNotStellar;
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
return false;
|
|
11
|
-
if (address.length !== 56)
|
|
12
|
-
return false;
|
|
13
|
-
if (address[0] !== 'G' && address[0] !== 'C')
|
|
14
|
-
return false;
|
|
15
|
-
return STELLAR_ADDRESS_RE.test(address);
|
|
16
|
-
}
|
|
6
|
+
const core_1 = require("../../core");
|
|
7
|
+
const chain_address_1 = require("../../core/helpers/chain-address");
|
|
8
|
+
Object.defineProperty(exports, "isStellarAddress", { enumerable: true, get: function () { return chain_address_1.isStellarAddress; } });
|
|
17
9
|
function getExplorerLink({ id, type = 'contract', network = 'mainnet', }) {
|
|
18
10
|
const baseUrl = 'https://stellar.expert/explorer';
|
|
19
11
|
const net = network === 'mainnet' ? 'public' : 'testnet';
|
|
20
12
|
return `${baseUrl}/${net}/${type}/${id}`;
|
|
21
13
|
}
|
|
22
14
|
function assertNotStellar(address, operation) {
|
|
23
|
-
if (isStellarAddress(address)) {
|
|
24
|
-
throw new
|
|
15
|
+
if ((0, chain_address_1.isStellarAddress)(address)) {
|
|
16
|
+
throw new core_1.AugustValidationError('INVALID_CHAIN', `${operation} is not yet supported for Stellar vaults: ${address}`);
|
|
25
17
|
}
|
|
26
18
|
}
|
|
27
19
|
exports.StellarUtils = {
|
|
28
|
-
isStellarAddress,
|
|
20
|
+
isStellarAddress: chain_address_1.isStellarAddress,
|
|
29
21
|
getExplorerLink,
|
|
30
22
|
assertNotStellar,
|
|
31
23
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export declare function convertFromE9(value: string | number): number;
|
|
2
2
|
export declare function calculateUtilization(current: string | number, maximum: string | number): number;
|
|
3
|
-
export
|
|
3
|
+
export { isSuiAddress } from '../../core/helpers/chain-address';
|
|
4
4
|
export declare function isSuiVault(chainId: number): boolean;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isSuiAddress = void 0;
|
|
3
4
|
exports.convertFromE9 = convertFromE9;
|
|
4
5
|
exports.calculateUtilization = calculateUtilization;
|
|
5
|
-
exports.isSuiAddress = isSuiAddress;
|
|
6
6
|
exports.isSuiVault = isSuiVault;
|
|
7
7
|
const constants_1 = require("./constants");
|
|
8
8
|
function convertFromE9(value) {
|
|
@@ -15,12 +15,8 @@ function calculateUtilization(current, maximum) {
|
|
|
15
15
|
return 0;
|
|
16
16
|
return Math.min((currentValue / maxValue) * 100, 100);
|
|
17
17
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return false;
|
|
21
|
-
const hexRegex = /^0x[a-fA-F0-9]{64}$/;
|
|
22
|
-
return hexRegex.test(address);
|
|
23
|
-
}
|
|
18
|
+
var chain_address_1 = require("../../core/helpers/chain-address");
|
|
19
|
+
Object.defineProperty(exports, "isSuiAddress", { enumerable: true, get: function () { return chain_address_1.isSuiAddress; } });
|
|
24
20
|
function isSuiVault(chainId) {
|
|
25
21
|
return chainId === constants_1.SUI_CHAIN_ID;
|
|
26
22
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function chainIdToTagValue(chainId: number | undefined): string;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.chainIdToTagValue = chainIdToTagValue;
|
|
4
|
+
const web3_1 = require("../constants/web3");
|
|
5
|
+
function chainIdToTagValue(chainId) {
|
|
6
|
+
if (chainId === undefined || chainId === null || Number.isNaN(chainId)) {
|
|
7
|
+
return 'unknown';
|
|
8
|
+
}
|
|
9
|
+
for (const entry of Object.values(web3_1.SPECIAL_CHAINS)) {
|
|
10
|
+
if (entry.chainId === chainId) {
|
|
11
|
+
return slugify(entry.name);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
const network = web3_1.NETWORKS[chainId];
|
|
15
|
+
if (network) {
|
|
16
|
+
return slugify(network.name);
|
|
17
|
+
}
|
|
18
|
+
return `unknown:${chainId}`;
|
|
19
|
+
}
|
|
20
|
+
function slugify(input) {
|
|
21
|
+
return input
|
|
22
|
+
.toLowerCase()
|
|
23
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
24
|
+
.replace(/^-+|-+$/g, '');
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=chain-name.js.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.readEnv = readEnv;
|
|
4
|
+
exports.isAnalyticsForcedOnViaEnv = isAnalyticsForcedOnViaEnv;
|
|
5
|
+
exports.isAnalyticsDisabledViaEnv = isAnalyticsDisabledViaEnv;
|
|
6
|
+
exports.isNodeDevOrTestEnv = isNodeDevOrTestEnv;
|
|
7
|
+
function readEnv(name) {
|
|
8
|
+
try {
|
|
9
|
+
if (typeof process !== 'undefined' && process.env) {
|
|
10
|
+
return process.env[name];
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
}
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
function isTruthyEnv(value) {
|
|
18
|
+
if (!value)
|
|
19
|
+
return false;
|
|
20
|
+
const v = value.toLowerCase();
|
|
21
|
+
return v === '1' || v === 'true' || v === 'yes' || v === 'on';
|
|
22
|
+
}
|
|
23
|
+
function isAnalyticsForcedOnViaEnv() {
|
|
24
|
+
return isTruthyEnv(readEnv('AUGUST_SDK_FORCE_ANALYTICS'));
|
|
25
|
+
}
|
|
26
|
+
function isAnalyticsDisabledViaEnv() {
|
|
27
|
+
return isTruthyEnv(readEnv('AUGUST_SDK_DISABLE_ANALYTICS'));
|
|
28
|
+
}
|
|
29
|
+
function isNodeDevOrTestEnv() {
|
|
30
|
+
const env = readEnv('NODE_ENV');
|
|
31
|
+
return env === 'development' || env === 'test';
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=env.js.map
|