@dynamic-labs-wallet/node-svm 1.1.51 → 1.1.53
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/index.cjs +343 -0
- package/index.esm.js +342 -1
- package/package.json +2 -2
- package/src/client/client.d.ts +13 -0
- package/src/client/client.d.ts.map +1 -1
- package/src/client/earn.client.d.ts +56 -0
- package/src/client/earn.client.d.ts.map +1 -0
- package/src/client/earn.constants.d.ts +9 -0
- package/src/client/earn.constants.d.ts.map +1 -0
- package/src/client/earn.types.d.ts +41 -0
- package/src/client/earn.types.d.ts.map +1 -0
- package/src/client/index.d.ts +3 -0
- package/src/client/index.d.ts.map +1 -1
package/index.cjs
CHANGED
|
@@ -84,6 +84,29 @@ function decodeBase58(str) {
|
|
|
84
84
|
return out;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
+
function _object_without_properties_loose(source, excluded) {
|
|
88
|
+
if (source == null) return {};
|
|
89
|
+
var target = {};
|
|
90
|
+
var sourceKeys = Object.keys(source);
|
|
91
|
+
var key, i;
|
|
92
|
+
for(i = 0; i < sourceKeys.length; i++){
|
|
93
|
+
key = sourceKeys[i];
|
|
94
|
+
if (excluded.indexOf(key) >= 0) continue;
|
|
95
|
+
target[key] = source[key];
|
|
96
|
+
}
|
|
97
|
+
return target;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const ERROR_EARN_NOT_SVM_WALLET = 'Wallet metadata is not for an SVM wallet';
|
|
101
|
+
const ERROR_EARN_MISSING_TRANSACTIONS = 'Earn signing payload is missing the Solana transaction sequence';
|
|
102
|
+
const ERROR_EARN_NON_CONTIGUOUS_ORDINALS = 'Earn signing payload transaction ordinals must be contiguous from zero';
|
|
103
|
+
/** Default RPC per Dynamic Solana chain id (101 mainnet, 103 devnet); `rpcUrl` overrides. */ const EARN_SOLANA_RPC_BY_CHAIN_ID = {
|
|
104
|
+
'101': 'https://api.mainnet-beta.solana.com',
|
|
105
|
+
'103': 'https://api.devnet.solana.com'
|
|
106
|
+
};
|
|
107
|
+
/** Blockhash checks run at `processed`, the commitment that sees new blockhashes first. */ const EARN_SOLANA_BLOCKHASH_COMMITMENT = 'processed';
|
|
108
|
+
const EARN_CONFIRMATION_POLL_INTERVAL_MS = 1000;
|
|
109
|
+
|
|
87
110
|
async function getBalance({ address, rpcUrl = node.SOLANA_RPC_URL }) {
|
|
88
111
|
const connection = new web3_js.Connection(rpcUrl != null ? rpcUrl : 'https://api.devnet.solana.com');
|
|
89
112
|
const balance = await connection.getBalance(new web3_js.PublicKey(address));
|
|
@@ -132,6 +155,300 @@ async function sendTransaction({ signedTransaction, rpcUrl = 'https://api.devnet
|
|
|
132
155
|
return txid;
|
|
133
156
|
}
|
|
134
157
|
|
|
158
|
+
/**
|
|
159
|
+
* A transaction in the sequence could not land. Transactions before `ordinal` already
|
|
160
|
+
* confirmed on-chain, so the action may be partially applied.
|
|
161
|
+
*/ class EarnSolanaStepError extends Error {
|
|
162
|
+
constructor({ cause, code, ordinal, reason, signature, total }){
|
|
163
|
+
const message = `Transaction ${ordinal + 1} of ${total} ${reason}.`;
|
|
164
|
+
const confirmed = ordinal === 1 ? 'transaction' : `${ordinal} transactions`;
|
|
165
|
+
super(ordinal === 0 ? message : `${message} The earlier ${confirmed} already confirmed on-chain, so the action is partially applied; check your position before retrying.`, {
|
|
166
|
+
cause
|
|
167
|
+
});
|
|
168
|
+
this.name = 'EarnSolanaStepError';
|
|
169
|
+
this.code = code;
|
|
170
|
+
this.ordinal = ordinal;
|
|
171
|
+
this.signature = signature;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
// Versioned transactions are marked by the high bit on the first message byte after the
|
|
175
|
+
// signatures; legacy transactions start the message header there instead.
|
|
176
|
+
const deserializeEarnTransaction = (payload)=>{
|
|
177
|
+
const bytes = new Uint8Array(Buffer.from(payload, 'base64'));
|
|
178
|
+
var _bytes_;
|
|
179
|
+
const signatureCount = (_bytes_ = bytes[0]) != null ? _bytes_ : 0;
|
|
180
|
+
var _bytes_1;
|
|
181
|
+
const firstMessageByte = (_bytes_1 = bytes[1 + signatureCount * 64]) != null ? _bytes_1 : 0;
|
|
182
|
+
return (firstMessageByte & 0x80) !== 0 ? web3_js.VersionedTransaction.deserialize(bytes) : web3_js.Transaction.from(bytes);
|
|
183
|
+
};
|
|
184
|
+
const isStepExpired = async ({ connection, expiryBlockHeight, transaction })=>{
|
|
185
|
+
if (expiryBlockHeight !== undefined) {
|
|
186
|
+
return await connection.getBlockHeight('confirmed') > expiryBlockHeight;
|
|
187
|
+
}
|
|
188
|
+
const recentBlockhash = transaction instanceof web3_js.VersionedTransaction ? transaction.message.recentBlockhash : transaction.recentBlockhash;
|
|
189
|
+
// A transaction with no blockhash cannot be judged; the network rejects it on send anyway.
|
|
190
|
+
if (!recentBlockhash) {
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
const { value: isBlockhashValid } = await connection.isBlockhashValid(recentBlockhash, {
|
|
194
|
+
commitment: EARN_SOLANA_BLOCKHASH_COMMITMENT
|
|
195
|
+
});
|
|
196
|
+
return !isBlockhashValid;
|
|
197
|
+
};
|
|
198
|
+
// Polls over HTTP rather than a websocket subscription, which some RPC providers refuse.
|
|
199
|
+
const waitForConfirmation = async ({ connection, isExpired, signature })=>{
|
|
200
|
+
const hasExpired = await isExpired();
|
|
201
|
+
// A missing status only means "never landed" once the blockhash lapsed, so the
|
|
202
|
+
// lookup then needs the full transaction history rather than the recent cache.
|
|
203
|
+
const { value: [status] } = await connection.getSignatureStatuses([
|
|
204
|
+
signature
|
|
205
|
+
], {
|
|
206
|
+
searchTransactionHistory: hasExpired
|
|
207
|
+
});
|
|
208
|
+
if (status == null ? void 0 : status.err) {
|
|
209
|
+
return {
|
|
210
|
+
error: status.err,
|
|
211
|
+
outcome: 'failed'
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
if ((status == null ? void 0 : status.confirmationStatus) === 'confirmed' || (status == null ? void 0 : status.confirmationStatus) === 'finalized') {
|
|
215
|
+
return {
|
|
216
|
+
outcome: 'confirmed'
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
if (hasExpired && !status) {
|
|
220
|
+
return {
|
|
221
|
+
outcome: 'expired'
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
await new Promise((resolve)=>{
|
|
225
|
+
setTimeout(resolve, EARN_CONFIRMATION_POLL_INTERVAL_MS);
|
|
226
|
+
});
|
|
227
|
+
return waitForConfirmation({
|
|
228
|
+
connection,
|
|
229
|
+
isExpired,
|
|
230
|
+
signature
|
|
231
|
+
});
|
|
232
|
+
};
|
|
233
|
+
const serializeSigned = (transaction)=>Buffer.from(transaction instanceof web3_js.VersionedTransaction ? transaction.serialize() : transaction.serialize({
|
|
234
|
+
verifySignatures: false
|
|
235
|
+
}));
|
|
236
|
+
// The transaction id is its first (fee payer) signature — for sponsored steps that is
|
|
237
|
+
// the sponsor's, not the wallet's — so the send result, not the signature
|
|
238
|
+
// `signTransaction` returned, is what must be confirmed.
|
|
239
|
+
const signAndSendStep = async ({ chainId, connection, context, externalServerKeyShares, ordinal, password, signTransaction, sponsored, total, transaction, walletMetadata })=>{
|
|
240
|
+
try {
|
|
241
|
+
const result = await signTransaction({
|
|
242
|
+
walletMetadata,
|
|
243
|
+
transaction,
|
|
244
|
+
password,
|
|
245
|
+
externalServerKeyShares,
|
|
246
|
+
sponsor: sponsored != null ? sponsored : false,
|
|
247
|
+
chainId,
|
|
248
|
+
context
|
|
249
|
+
});
|
|
250
|
+
const signedTransaction = typeof result === 'string' ? attachSignature({
|
|
251
|
+
transaction,
|
|
252
|
+
signatureBase58: result,
|
|
253
|
+
senderAddress: walletMetadata.accountAddress
|
|
254
|
+
}) : result.transaction;
|
|
255
|
+
return await connection.sendRawTransaction(serializeSigned(signedTransaction), {
|
|
256
|
+
preflightCommitment: EARN_SOLANA_BLOCKHASH_COMMITMENT
|
|
257
|
+
});
|
|
258
|
+
} catch (error) {
|
|
259
|
+
throw new EarnSolanaStepError({
|
|
260
|
+
cause: error instanceof Error ? error : undefined,
|
|
261
|
+
code: 'yield_step_send_failed',
|
|
262
|
+
ordinal,
|
|
263
|
+
reason: 'could not be signed or sent',
|
|
264
|
+
total
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
/**
|
|
269
|
+
* Builds a stateless Earn client for Solana vaults: it prepares vault actions through the
|
|
270
|
+
* Dynamic API and executes the returned ordered transaction sequence one transaction at a
|
|
271
|
+
* time — never in parallel, because a later transaction can depend on the state an earlier
|
|
272
|
+
* one wrote. If one fails, the sequence stops and the thrown {@link EarnSolanaStepError}
|
|
273
|
+
* reports how much of the action already landed.
|
|
274
|
+
*
|
|
275
|
+
* Gas sponsorship is opt-in (`sponsored: true`): vault transactions are built with the
|
|
276
|
+
* owner as fee payer, unlike the browser SDK which sponsors automatically.
|
|
277
|
+
*/ const createSvmEarnClient = ({ getEarnClient, signTransaction })=>{
|
|
278
|
+
const executeStep = async ({ connection, context, externalServerKeyShares, chainId, onStepChange, onTransactionStepChange, password, sponsored, step, total, walletMetadata })=>{
|
|
279
|
+
const transaction = deserializeEarnTransaction(step.payload);
|
|
280
|
+
const { ordinal } = step;
|
|
281
|
+
const isExpired = ()=>isStepExpired({
|
|
282
|
+
connection,
|
|
283
|
+
expiryBlockHeight: step.expiryBlockHeight,
|
|
284
|
+
transaction
|
|
285
|
+
});
|
|
286
|
+
// The blockhash was fixed when the payload was built, so earlier slow steps can
|
|
287
|
+
// leave later ones unsendable — check before spending a signature.
|
|
288
|
+
if (await isExpired()) {
|
|
289
|
+
throw new EarnSolanaStepError({
|
|
290
|
+
code: 'yield_step_expired',
|
|
291
|
+
ordinal,
|
|
292
|
+
reason: 'expired before it could be signed',
|
|
293
|
+
total
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
onStepChange == null ? void 0 : onStepChange('transaction');
|
|
297
|
+
const progress = {
|
|
298
|
+
ordinal,
|
|
299
|
+
total
|
|
300
|
+
};
|
|
301
|
+
if (step.label !== undefined) {
|
|
302
|
+
progress.label = step.label;
|
|
303
|
+
}
|
|
304
|
+
onTransactionStepChange == null ? void 0 : onTransactionStepChange(progress);
|
|
305
|
+
const signature = await signAndSendStep({
|
|
306
|
+
chainId,
|
|
307
|
+
connection,
|
|
308
|
+
context,
|
|
309
|
+
externalServerKeyShares,
|
|
310
|
+
ordinal,
|
|
311
|
+
password,
|
|
312
|
+
signTransaction,
|
|
313
|
+
sponsored,
|
|
314
|
+
total,
|
|
315
|
+
transaction,
|
|
316
|
+
walletMetadata
|
|
317
|
+
});
|
|
318
|
+
// A sent transaction may still land even when the poll itself fails, so wrap any RPC
|
|
319
|
+
// error and keep the send signature on it for reconciliation.
|
|
320
|
+
let confirmation;
|
|
321
|
+
try {
|
|
322
|
+
confirmation = await waitForConfirmation({
|
|
323
|
+
connection,
|
|
324
|
+
isExpired,
|
|
325
|
+
signature
|
|
326
|
+
});
|
|
327
|
+
} catch (error) {
|
|
328
|
+
throw new EarnSolanaStepError({
|
|
329
|
+
cause: error instanceof Error ? error : undefined,
|
|
330
|
+
code: 'yield_step_confirmation_unknown',
|
|
331
|
+
ordinal,
|
|
332
|
+
reason: 'was sent but its confirmation could not be checked',
|
|
333
|
+
signature,
|
|
334
|
+
total
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
if (confirmation.outcome === 'failed') {
|
|
338
|
+
throw new EarnSolanaStepError({
|
|
339
|
+
code: 'yield_step_failed',
|
|
340
|
+
ordinal,
|
|
341
|
+
reason: `failed on-chain: ${JSON.stringify(confirmation.error)}`,
|
|
342
|
+
signature,
|
|
343
|
+
total
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
if (confirmation.outcome === 'expired') {
|
|
347
|
+
throw new EarnSolanaStepError({
|
|
348
|
+
code: 'yield_step_expired',
|
|
349
|
+
ordinal,
|
|
350
|
+
reason: 'was not confirmed before its blockhash expired',
|
|
351
|
+
signature,
|
|
352
|
+
total
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
return signature;
|
|
356
|
+
};
|
|
357
|
+
const executeEarnTransaction = async ({ signingPayload, walletMetadata, password, externalServerKeyShares, sponsored, rpcUrl, chainId, context, onStepChange, onTransactionStepChange })=>{
|
|
358
|
+
if (walletMetadata.chainName !== 'SVM') {
|
|
359
|
+
throw new Error(ERROR_EARN_NOT_SVM_WALLET);
|
|
360
|
+
}
|
|
361
|
+
if (!walletMetadata.accountAddress) {
|
|
362
|
+
throw new Error('Account address is required');
|
|
363
|
+
}
|
|
364
|
+
var _signingPayload_transactions;
|
|
365
|
+
const steps = [
|
|
366
|
+
...(_signingPayload_transactions = signingPayload.transactions) != null ? _signingPayload_transactions : []
|
|
367
|
+
].sort((first, second)=>first.ordinal - second.ordinal);
|
|
368
|
+
if (steps.length === 0) {
|
|
369
|
+
throw new Error(ERROR_EARN_MISSING_TRANSACTIONS);
|
|
370
|
+
}
|
|
371
|
+
if (steps.some((step, index)=>step.ordinal !== index)) {
|
|
372
|
+
throw new Error(ERROR_EARN_NON_CONTIGUOUS_ORDINALS);
|
|
373
|
+
}
|
|
374
|
+
var _ref;
|
|
375
|
+
const connection = new web3_js.Connection((_ref = rpcUrl != null ? rpcUrl : EARN_SOLANA_RPC_BY_CHAIN_ID[chainId != null ? chainId : signingPayload.chainId]) != null ? _ref : node.SOLANA_RPC_URL);
|
|
376
|
+
// A rejection stops the sequence at the first failure; everything after it is skipped.
|
|
377
|
+
const transactionHash = await steps.reduce(async (previousStep, step)=>{
|
|
378
|
+
await previousStep;
|
|
379
|
+
return executeStep({
|
|
380
|
+
connection,
|
|
381
|
+
context,
|
|
382
|
+
externalServerKeyShares,
|
|
383
|
+
chainId: chainId != null ? chainId : signingPayload.chainId,
|
|
384
|
+
onStepChange,
|
|
385
|
+
onTransactionStepChange,
|
|
386
|
+
password,
|
|
387
|
+
sponsored,
|
|
388
|
+
step,
|
|
389
|
+
total: steps.length,
|
|
390
|
+
walletMetadata
|
|
391
|
+
});
|
|
392
|
+
}, Promise.resolve(''));
|
|
393
|
+
return {
|
|
394
|
+
transactionHash
|
|
395
|
+
};
|
|
396
|
+
};
|
|
397
|
+
return {
|
|
398
|
+
executeEarnTransaction,
|
|
399
|
+
depositToEarnVault: async (_param)=>{
|
|
400
|
+
var { vaultId, amount, receiverAddress, traceContext } = _param, walletParams = _object_without_properties_loose(_param, [
|
|
401
|
+
"vaultId",
|
|
402
|
+
"amount",
|
|
403
|
+
"receiverAddress",
|
|
404
|
+
"traceContext"
|
|
405
|
+
]);
|
|
406
|
+
const signingPayload = await getEarnClient().prepareDeposit({
|
|
407
|
+
vaultId,
|
|
408
|
+
ownerAddress: walletParams.walletMetadata.accountAddress,
|
|
409
|
+
amount,
|
|
410
|
+
receiverAddress,
|
|
411
|
+
traceContext
|
|
412
|
+
});
|
|
413
|
+
return executeEarnTransaction(_extends({
|
|
414
|
+
signingPayload
|
|
415
|
+
}, walletParams));
|
|
416
|
+
},
|
|
417
|
+
withdrawFromEarnVault: async (_param)=>{
|
|
418
|
+
var { vaultId, amount, receiverAddress, traceContext } = _param, walletParams = _object_without_properties_loose(_param, [
|
|
419
|
+
"vaultId",
|
|
420
|
+
"amount",
|
|
421
|
+
"receiverAddress",
|
|
422
|
+
"traceContext"
|
|
423
|
+
]);
|
|
424
|
+
const signingPayload = await getEarnClient().prepareWithdrawal({
|
|
425
|
+
vaultId,
|
|
426
|
+
ownerAddress: walletParams.walletMetadata.accountAddress,
|
|
427
|
+
amount,
|
|
428
|
+
receiverAddress,
|
|
429
|
+
traceContext
|
|
430
|
+
});
|
|
431
|
+
return executeEarnTransaction(_extends({
|
|
432
|
+
signingPayload
|
|
433
|
+
}, walletParams));
|
|
434
|
+
},
|
|
435
|
+
claimEarnRewards: async (_param)=>{
|
|
436
|
+
var { vaultId, traceContext } = _param, walletParams = _object_without_properties_loose(_param, [
|
|
437
|
+
"vaultId",
|
|
438
|
+
"traceContext"
|
|
439
|
+
]);
|
|
440
|
+
const signingPayload = await getEarnClient().prepareClaimRewards({
|
|
441
|
+
vaultId,
|
|
442
|
+
ownerAddress: walletParams.walletMetadata.accountAddress,
|
|
443
|
+
traceContext
|
|
444
|
+
});
|
|
445
|
+
return executeEarnTransaction(_extends({
|
|
446
|
+
signingPayload
|
|
447
|
+
}, walletParams));
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
};
|
|
451
|
+
|
|
135
452
|
const logError$1 = node.createLogError('node-svm');
|
|
136
453
|
// Helper: normalize bytes to hex without triggering Buffer.from(string, encoding) overload
|
|
137
454
|
const toHex = (bytes)=>(Buffer.isBuffer(bytes) ? bytes : Buffer.from(bytes)).toString('hex');
|
|
@@ -563,6 +880,30 @@ class DynamicSvmWalletClient extends node.DynamicWalletClient {
|
|
|
563
880
|
const svmWallets = wallets.filter((wallet)=>wallet.chainName === 'SVM');
|
|
564
881
|
return svmWallets;
|
|
565
882
|
}
|
|
883
|
+
// ---------------------------------------------------------------------------
|
|
884
|
+
// Earn (yield vaults)
|
|
885
|
+
// ---------------------------------------------------------------------------
|
|
886
|
+
get svmEarn() {
|
|
887
|
+
return createSvmEarnClient({
|
|
888
|
+
getEarnClient: ()=>this.earn,
|
|
889
|
+
signTransaction: (args)=>this.signTransaction(args)
|
|
890
|
+
});
|
|
891
|
+
}
|
|
892
|
+
/**
|
|
893
|
+
* Executes an Earn signing payload returned by the prepare* methods, signing and
|
|
894
|
+
* sending its ordered Solana transaction sequence one transaction at a time.
|
|
895
|
+
*/ async executeEarnTransaction(params) {
|
|
896
|
+
return this.svmEarn.executeEarnTransaction(params);
|
|
897
|
+
}
|
|
898
|
+
/** Prepares and executes a deposit into an Earn vault. */ async depositToEarnVault(params) {
|
|
899
|
+
return this.svmEarn.depositToEarnVault(params);
|
|
900
|
+
}
|
|
901
|
+
/** Prepares and executes a withdrawal from an Earn vault. */ async withdrawFromEarnVault(params) {
|
|
902
|
+
return this.svmEarn.withdrawFromEarnVault(params);
|
|
903
|
+
}
|
|
904
|
+
/** Prepares and executes a claim of accrued Earn vault rewards. */ async claimEarnRewards(params) {
|
|
905
|
+
return this.svmEarn.claimEarnRewards(params);
|
|
906
|
+
}
|
|
566
907
|
constructor({ environmentId, baseApiUrl, baseMPCRelayApiUrl, enableMPCAccelerator, logger, debug }){
|
|
567
908
|
super({
|
|
568
909
|
environmentId,
|
|
@@ -883,10 +1224,12 @@ exports.ERROR_DELEGATED_SIGN_TRANSACTION_CONTEXT_REQUIRED = ERROR_DELEGATED_SIGN
|
|
|
883
1224
|
exports.ERROR_SIGN_RAW_MESSAGE = ERROR_SIGN_RAW_MESSAGE;
|
|
884
1225
|
exports.ERROR_SIGN_TRANSACTION_CONTEXT_REQUIRED = ERROR_SIGN_TRANSACTION_CONTEXT_REQUIRED;
|
|
885
1226
|
exports.ERROR_SIGN_TRANSACTION_RAW_HEX_CONTEXT_REQUIRED = ERROR_SIGN_TRANSACTION_RAW_HEX_CONTEXT_REQUIRED;
|
|
1227
|
+
exports.EarnSolanaStepError = EarnSolanaStepError;
|
|
886
1228
|
exports.addSignatureToTransaction = addSignatureToTransaction;
|
|
887
1229
|
exports.attachSignature = attachSignature;
|
|
888
1230
|
exports.createDelegatedSvmWalletClient = createDelegatedSvmWalletClient;
|
|
889
1231
|
exports.createSolanaTransaction = createSolanaTransaction;
|
|
1232
|
+
exports.createSvmEarnClient = createSvmEarnClient;
|
|
890
1233
|
exports.decodeBase58 = decodeBase58;
|
|
891
1234
|
exports.delegatedSignMessage = delegatedSignMessage;
|
|
892
1235
|
exports.delegatedSignRawMessage = delegatedSignRawMessage;
|
package/index.esm.js
CHANGED
|
@@ -82,6 +82,29 @@ function decodeBase58(str) {
|
|
|
82
82
|
return out;
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
function _object_without_properties_loose(source, excluded) {
|
|
86
|
+
if (source == null) return {};
|
|
87
|
+
var target = {};
|
|
88
|
+
var sourceKeys = Object.keys(source);
|
|
89
|
+
var key, i;
|
|
90
|
+
for(i = 0; i < sourceKeys.length; i++){
|
|
91
|
+
key = sourceKeys[i];
|
|
92
|
+
if (excluded.indexOf(key) >= 0) continue;
|
|
93
|
+
target[key] = source[key];
|
|
94
|
+
}
|
|
95
|
+
return target;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const ERROR_EARN_NOT_SVM_WALLET = 'Wallet metadata is not for an SVM wallet';
|
|
99
|
+
const ERROR_EARN_MISSING_TRANSACTIONS = 'Earn signing payload is missing the Solana transaction sequence';
|
|
100
|
+
const ERROR_EARN_NON_CONTIGUOUS_ORDINALS = 'Earn signing payload transaction ordinals must be contiguous from zero';
|
|
101
|
+
/** Default RPC per Dynamic Solana chain id (101 mainnet, 103 devnet); `rpcUrl` overrides. */ const EARN_SOLANA_RPC_BY_CHAIN_ID = {
|
|
102
|
+
'101': 'https://api.mainnet-beta.solana.com',
|
|
103
|
+
'103': 'https://api.devnet.solana.com'
|
|
104
|
+
};
|
|
105
|
+
/** Blockhash checks run at `processed`, the commitment that sees new blockhashes first. */ const EARN_SOLANA_BLOCKHASH_COMMITMENT = 'processed';
|
|
106
|
+
const EARN_CONFIRMATION_POLL_INTERVAL_MS = 1000;
|
|
107
|
+
|
|
85
108
|
async function getBalance({ address, rpcUrl = SOLANA_RPC_URL }) {
|
|
86
109
|
const connection = new Connection(rpcUrl != null ? rpcUrl : 'https://api.devnet.solana.com');
|
|
87
110
|
const balance = await connection.getBalance(new PublicKey(address));
|
|
@@ -130,6 +153,300 @@ async function sendTransaction({ signedTransaction, rpcUrl = 'https://api.devnet
|
|
|
130
153
|
return txid;
|
|
131
154
|
}
|
|
132
155
|
|
|
156
|
+
/**
|
|
157
|
+
* A transaction in the sequence could not land. Transactions before `ordinal` already
|
|
158
|
+
* confirmed on-chain, so the action may be partially applied.
|
|
159
|
+
*/ class EarnSolanaStepError extends Error {
|
|
160
|
+
constructor({ cause, code, ordinal, reason, signature, total }){
|
|
161
|
+
const message = `Transaction ${ordinal + 1} of ${total} ${reason}.`;
|
|
162
|
+
const confirmed = ordinal === 1 ? 'transaction' : `${ordinal} transactions`;
|
|
163
|
+
super(ordinal === 0 ? message : `${message} The earlier ${confirmed} already confirmed on-chain, so the action is partially applied; check your position before retrying.`, {
|
|
164
|
+
cause
|
|
165
|
+
});
|
|
166
|
+
this.name = 'EarnSolanaStepError';
|
|
167
|
+
this.code = code;
|
|
168
|
+
this.ordinal = ordinal;
|
|
169
|
+
this.signature = signature;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// Versioned transactions are marked by the high bit on the first message byte after the
|
|
173
|
+
// signatures; legacy transactions start the message header there instead.
|
|
174
|
+
const deserializeEarnTransaction = (payload)=>{
|
|
175
|
+
const bytes = new Uint8Array(Buffer.from(payload, 'base64'));
|
|
176
|
+
var _bytes_;
|
|
177
|
+
const signatureCount = (_bytes_ = bytes[0]) != null ? _bytes_ : 0;
|
|
178
|
+
var _bytes_1;
|
|
179
|
+
const firstMessageByte = (_bytes_1 = bytes[1 + signatureCount * 64]) != null ? _bytes_1 : 0;
|
|
180
|
+
return (firstMessageByte & 0x80) !== 0 ? VersionedTransaction.deserialize(bytes) : Transaction.from(bytes);
|
|
181
|
+
};
|
|
182
|
+
const isStepExpired = async ({ connection, expiryBlockHeight, transaction })=>{
|
|
183
|
+
if (expiryBlockHeight !== undefined) {
|
|
184
|
+
return await connection.getBlockHeight('confirmed') > expiryBlockHeight;
|
|
185
|
+
}
|
|
186
|
+
const recentBlockhash = transaction instanceof VersionedTransaction ? transaction.message.recentBlockhash : transaction.recentBlockhash;
|
|
187
|
+
// A transaction with no blockhash cannot be judged; the network rejects it on send anyway.
|
|
188
|
+
if (!recentBlockhash) {
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
const { value: isBlockhashValid } = await connection.isBlockhashValid(recentBlockhash, {
|
|
192
|
+
commitment: EARN_SOLANA_BLOCKHASH_COMMITMENT
|
|
193
|
+
});
|
|
194
|
+
return !isBlockhashValid;
|
|
195
|
+
};
|
|
196
|
+
// Polls over HTTP rather than a websocket subscription, which some RPC providers refuse.
|
|
197
|
+
const waitForConfirmation = async ({ connection, isExpired, signature })=>{
|
|
198
|
+
const hasExpired = await isExpired();
|
|
199
|
+
// A missing status only means "never landed" once the blockhash lapsed, so the
|
|
200
|
+
// lookup then needs the full transaction history rather than the recent cache.
|
|
201
|
+
const { value: [status] } = await connection.getSignatureStatuses([
|
|
202
|
+
signature
|
|
203
|
+
], {
|
|
204
|
+
searchTransactionHistory: hasExpired
|
|
205
|
+
});
|
|
206
|
+
if (status == null ? void 0 : status.err) {
|
|
207
|
+
return {
|
|
208
|
+
error: status.err,
|
|
209
|
+
outcome: 'failed'
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
if ((status == null ? void 0 : status.confirmationStatus) === 'confirmed' || (status == null ? void 0 : status.confirmationStatus) === 'finalized') {
|
|
213
|
+
return {
|
|
214
|
+
outcome: 'confirmed'
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
if (hasExpired && !status) {
|
|
218
|
+
return {
|
|
219
|
+
outcome: 'expired'
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
await new Promise((resolve)=>{
|
|
223
|
+
setTimeout(resolve, EARN_CONFIRMATION_POLL_INTERVAL_MS);
|
|
224
|
+
});
|
|
225
|
+
return waitForConfirmation({
|
|
226
|
+
connection,
|
|
227
|
+
isExpired,
|
|
228
|
+
signature
|
|
229
|
+
});
|
|
230
|
+
};
|
|
231
|
+
const serializeSigned = (transaction)=>Buffer.from(transaction instanceof VersionedTransaction ? transaction.serialize() : transaction.serialize({
|
|
232
|
+
verifySignatures: false
|
|
233
|
+
}));
|
|
234
|
+
// The transaction id is its first (fee payer) signature — for sponsored steps that is
|
|
235
|
+
// the sponsor's, not the wallet's — so the send result, not the signature
|
|
236
|
+
// `signTransaction` returned, is what must be confirmed.
|
|
237
|
+
const signAndSendStep = async ({ chainId, connection, context, externalServerKeyShares, ordinal, password, signTransaction, sponsored, total, transaction, walletMetadata })=>{
|
|
238
|
+
try {
|
|
239
|
+
const result = await signTransaction({
|
|
240
|
+
walletMetadata,
|
|
241
|
+
transaction,
|
|
242
|
+
password,
|
|
243
|
+
externalServerKeyShares,
|
|
244
|
+
sponsor: sponsored != null ? sponsored : false,
|
|
245
|
+
chainId,
|
|
246
|
+
context
|
|
247
|
+
});
|
|
248
|
+
const signedTransaction = typeof result === 'string' ? attachSignature({
|
|
249
|
+
transaction,
|
|
250
|
+
signatureBase58: result,
|
|
251
|
+
senderAddress: walletMetadata.accountAddress
|
|
252
|
+
}) : result.transaction;
|
|
253
|
+
return await connection.sendRawTransaction(serializeSigned(signedTransaction), {
|
|
254
|
+
preflightCommitment: EARN_SOLANA_BLOCKHASH_COMMITMENT
|
|
255
|
+
});
|
|
256
|
+
} catch (error) {
|
|
257
|
+
throw new EarnSolanaStepError({
|
|
258
|
+
cause: error instanceof Error ? error : undefined,
|
|
259
|
+
code: 'yield_step_send_failed',
|
|
260
|
+
ordinal,
|
|
261
|
+
reason: 'could not be signed or sent',
|
|
262
|
+
total
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
/**
|
|
267
|
+
* Builds a stateless Earn client for Solana vaults: it prepares vault actions through the
|
|
268
|
+
* Dynamic API and executes the returned ordered transaction sequence one transaction at a
|
|
269
|
+
* time — never in parallel, because a later transaction can depend on the state an earlier
|
|
270
|
+
* one wrote. If one fails, the sequence stops and the thrown {@link EarnSolanaStepError}
|
|
271
|
+
* reports how much of the action already landed.
|
|
272
|
+
*
|
|
273
|
+
* Gas sponsorship is opt-in (`sponsored: true`): vault transactions are built with the
|
|
274
|
+
* owner as fee payer, unlike the browser SDK which sponsors automatically.
|
|
275
|
+
*/ const createSvmEarnClient = ({ getEarnClient, signTransaction })=>{
|
|
276
|
+
const executeStep = async ({ connection, context, externalServerKeyShares, chainId, onStepChange, onTransactionStepChange, password, sponsored, step, total, walletMetadata })=>{
|
|
277
|
+
const transaction = deserializeEarnTransaction(step.payload);
|
|
278
|
+
const { ordinal } = step;
|
|
279
|
+
const isExpired = ()=>isStepExpired({
|
|
280
|
+
connection,
|
|
281
|
+
expiryBlockHeight: step.expiryBlockHeight,
|
|
282
|
+
transaction
|
|
283
|
+
});
|
|
284
|
+
// The blockhash was fixed when the payload was built, so earlier slow steps can
|
|
285
|
+
// leave later ones unsendable — check before spending a signature.
|
|
286
|
+
if (await isExpired()) {
|
|
287
|
+
throw new EarnSolanaStepError({
|
|
288
|
+
code: 'yield_step_expired',
|
|
289
|
+
ordinal,
|
|
290
|
+
reason: 'expired before it could be signed',
|
|
291
|
+
total
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
onStepChange == null ? void 0 : onStepChange('transaction');
|
|
295
|
+
const progress = {
|
|
296
|
+
ordinal,
|
|
297
|
+
total
|
|
298
|
+
};
|
|
299
|
+
if (step.label !== undefined) {
|
|
300
|
+
progress.label = step.label;
|
|
301
|
+
}
|
|
302
|
+
onTransactionStepChange == null ? void 0 : onTransactionStepChange(progress);
|
|
303
|
+
const signature = await signAndSendStep({
|
|
304
|
+
chainId,
|
|
305
|
+
connection,
|
|
306
|
+
context,
|
|
307
|
+
externalServerKeyShares,
|
|
308
|
+
ordinal,
|
|
309
|
+
password,
|
|
310
|
+
signTransaction,
|
|
311
|
+
sponsored,
|
|
312
|
+
total,
|
|
313
|
+
transaction,
|
|
314
|
+
walletMetadata
|
|
315
|
+
});
|
|
316
|
+
// A sent transaction may still land even when the poll itself fails, so wrap any RPC
|
|
317
|
+
// error and keep the send signature on it for reconciliation.
|
|
318
|
+
let confirmation;
|
|
319
|
+
try {
|
|
320
|
+
confirmation = await waitForConfirmation({
|
|
321
|
+
connection,
|
|
322
|
+
isExpired,
|
|
323
|
+
signature
|
|
324
|
+
});
|
|
325
|
+
} catch (error) {
|
|
326
|
+
throw new EarnSolanaStepError({
|
|
327
|
+
cause: error instanceof Error ? error : undefined,
|
|
328
|
+
code: 'yield_step_confirmation_unknown',
|
|
329
|
+
ordinal,
|
|
330
|
+
reason: 'was sent but its confirmation could not be checked',
|
|
331
|
+
signature,
|
|
332
|
+
total
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
if (confirmation.outcome === 'failed') {
|
|
336
|
+
throw new EarnSolanaStepError({
|
|
337
|
+
code: 'yield_step_failed',
|
|
338
|
+
ordinal,
|
|
339
|
+
reason: `failed on-chain: ${JSON.stringify(confirmation.error)}`,
|
|
340
|
+
signature,
|
|
341
|
+
total
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
if (confirmation.outcome === 'expired') {
|
|
345
|
+
throw new EarnSolanaStepError({
|
|
346
|
+
code: 'yield_step_expired',
|
|
347
|
+
ordinal,
|
|
348
|
+
reason: 'was not confirmed before its blockhash expired',
|
|
349
|
+
signature,
|
|
350
|
+
total
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
return signature;
|
|
354
|
+
};
|
|
355
|
+
const executeEarnTransaction = async ({ signingPayload, walletMetadata, password, externalServerKeyShares, sponsored, rpcUrl, chainId, context, onStepChange, onTransactionStepChange })=>{
|
|
356
|
+
if (walletMetadata.chainName !== 'SVM') {
|
|
357
|
+
throw new Error(ERROR_EARN_NOT_SVM_WALLET);
|
|
358
|
+
}
|
|
359
|
+
if (!walletMetadata.accountAddress) {
|
|
360
|
+
throw new Error('Account address is required');
|
|
361
|
+
}
|
|
362
|
+
var _signingPayload_transactions;
|
|
363
|
+
const steps = [
|
|
364
|
+
...(_signingPayload_transactions = signingPayload.transactions) != null ? _signingPayload_transactions : []
|
|
365
|
+
].sort((first, second)=>first.ordinal - second.ordinal);
|
|
366
|
+
if (steps.length === 0) {
|
|
367
|
+
throw new Error(ERROR_EARN_MISSING_TRANSACTIONS);
|
|
368
|
+
}
|
|
369
|
+
if (steps.some((step, index)=>step.ordinal !== index)) {
|
|
370
|
+
throw new Error(ERROR_EARN_NON_CONTIGUOUS_ORDINALS);
|
|
371
|
+
}
|
|
372
|
+
var _ref;
|
|
373
|
+
const connection = new Connection((_ref = rpcUrl != null ? rpcUrl : EARN_SOLANA_RPC_BY_CHAIN_ID[chainId != null ? chainId : signingPayload.chainId]) != null ? _ref : SOLANA_RPC_URL);
|
|
374
|
+
// A rejection stops the sequence at the first failure; everything after it is skipped.
|
|
375
|
+
const transactionHash = await steps.reduce(async (previousStep, step)=>{
|
|
376
|
+
await previousStep;
|
|
377
|
+
return executeStep({
|
|
378
|
+
connection,
|
|
379
|
+
context,
|
|
380
|
+
externalServerKeyShares,
|
|
381
|
+
chainId: chainId != null ? chainId : signingPayload.chainId,
|
|
382
|
+
onStepChange,
|
|
383
|
+
onTransactionStepChange,
|
|
384
|
+
password,
|
|
385
|
+
sponsored,
|
|
386
|
+
step,
|
|
387
|
+
total: steps.length,
|
|
388
|
+
walletMetadata
|
|
389
|
+
});
|
|
390
|
+
}, Promise.resolve(''));
|
|
391
|
+
return {
|
|
392
|
+
transactionHash
|
|
393
|
+
};
|
|
394
|
+
};
|
|
395
|
+
return {
|
|
396
|
+
executeEarnTransaction,
|
|
397
|
+
depositToEarnVault: async (_param)=>{
|
|
398
|
+
var { vaultId, amount, receiverAddress, traceContext } = _param, walletParams = _object_without_properties_loose(_param, [
|
|
399
|
+
"vaultId",
|
|
400
|
+
"amount",
|
|
401
|
+
"receiverAddress",
|
|
402
|
+
"traceContext"
|
|
403
|
+
]);
|
|
404
|
+
const signingPayload = await getEarnClient().prepareDeposit({
|
|
405
|
+
vaultId,
|
|
406
|
+
ownerAddress: walletParams.walletMetadata.accountAddress,
|
|
407
|
+
amount,
|
|
408
|
+
receiverAddress,
|
|
409
|
+
traceContext
|
|
410
|
+
});
|
|
411
|
+
return executeEarnTransaction(_extends({
|
|
412
|
+
signingPayload
|
|
413
|
+
}, walletParams));
|
|
414
|
+
},
|
|
415
|
+
withdrawFromEarnVault: async (_param)=>{
|
|
416
|
+
var { vaultId, amount, receiverAddress, traceContext } = _param, walletParams = _object_without_properties_loose(_param, [
|
|
417
|
+
"vaultId",
|
|
418
|
+
"amount",
|
|
419
|
+
"receiverAddress",
|
|
420
|
+
"traceContext"
|
|
421
|
+
]);
|
|
422
|
+
const signingPayload = await getEarnClient().prepareWithdrawal({
|
|
423
|
+
vaultId,
|
|
424
|
+
ownerAddress: walletParams.walletMetadata.accountAddress,
|
|
425
|
+
amount,
|
|
426
|
+
receiverAddress,
|
|
427
|
+
traceContext
|
|
428
|
+
});
|
|
429
|
+
return executeEarnTransaction(_extends({
|
|
430
|
+
signingPayload
|
|
431
|
+
}, walletParams));
|
|
432
|
+
},
|
|
433
|
+
claimEarnRewards: async (_param)=>{
|
|
434
|
+
var { vaultId, traceContext } = _param, walletParams = _object_without_properties_loose(_param, [
|
|
435
|
+
"vaultId",
|
|
436
|
+
"traceContext"
|
|
437
|
+
]);
|
|
438
|
+
const signingPayload = await getEarnClient().prepareClaimRewards({
|
|
439
|
+
vaultId,
|
|
440
|
+
ownerAddress: walletParams.walletMetadata.accountAddress,
|
|
441
|
+
traceContext
|
|
442
|
+
});
|
|
443
|
+
return executeEarnTransaction(_extends({
|
|
444
|
+
signingPayload
|
|
445
|
+
}, walletParams));
|
|
446
|
+
}
|
|
447
|
+
};
|
|
448
|
+
};
|
|
449
|
+
|
|
133
450
|
const logError$1 = createLogError('node-svm');
|
|
134
451
|
// Helper: normalize bytes to hex without triggering Buffer.from(string, encoding) overload
|
|
135
452
|
const toHex = (bytes)=>(Buffer.isBuffer(bytes) ? bytes : Buffer.from(bytes)).toString('hex');
|
|
@@ -561,6 +878,30 @@ class DynamicSvmWalletClient extends DynamicWalletClient {
|
|
|
561
878
|
const svmWallets = wallets.filter((wallet)=>wallet.chainName === 'SVM');
|
|
562
879
|
return svmWallets;
|
|
563
880
|
}
|
|
881
|
+
// ---------------------------------------------------------------------------
|
|
882
|
+
// Earn (yield vaults)
|
|
883
|
+
// ---------------------------------------------------------------------------
|
|
884
|
+
get svmEarn() {
|
|
885
|
+
return createSvmEarnClient({
|
|
886
|
+
getEarnClient: ()=>this.earn,
|
|
887
|
+
signTransaction: (args)=>this.signTransaction(args)
|
|
888
|
+
});
|
|
889
|
+
}
|
|
890
|
+
/**
|
|
891
|
+
* Executes an Earn signing payload returned by the prepare* methods, signing and
|
|
892
|
+
* sending its ordered Solana transaction sequence one transaction at a time.
|
|
893
|
+
*/ async executeEarnTransaction(params) {
|
|
894
|
+
return this.svmEarn.executeEarnTransaction(params);
|
|
895
|
+
}
|
|
896
|
+
/** Prepares and executes a deposit into an Earn vault. */ async depositToEarnVault(params) {
|
|
897
|
+
return this.svmEarn.depositToEarnVault(params);
|
|
898
|
+
}
|
|
899
|
+
/** Prepares and executes a withdrawal from an Earn vault. */ async withdrawFromEarnVault(params) {
|
|
900
|
+
return this.svmEarn.withdrawFromEarnVault(params);
|
|
901
|
+
}
|
|
902
|
+
/** Prepares and executes a claim of accrued Earn vault rewards. */ async claimEarnRewards(params) {
|
|
903
|
+
return this.svmEarn.claimEarnRewards(params);
|
|
904
|
+
}
|
|
564
905
|
constructor({ environmentId, baseApiUrl, baseMPCRelayApiUrl, enableMPCAccelerator, logger, debug }){
|
|
565
906
|
super({
|
|
566
907
|
environmentId,
|
|
@@ -875,4 +1216,4 @@ const delegatedSignTransaction = async (client, { walletId, shareSetId, walletAp
|
|
|
875
1216
|
});
|
|
876
1217
|
};
|
|
877
1218
|
|
|
878
|
-
export { DynamicSvmWalletClient, ERROR_CREATE_WALLET_ACCOUNT, ERROR_DELEGATED_SIGN_TRANSACTION_CONTEXT_REQUIRED, ERROR_SIGN_RAW_MESSAGE, ERROR_SIGN_TRANSACTION_CONTEXT_REQUIRED, ERROR_SIGN_TRANSACTION_RAW_HEX_CONTEXT_REQUIRED, addSignatureToTransaction, attachSignature, createDelegatedSvmWalletClient, createSolanaTransaction, decodeBase58, delegatedSignMessage, delegatedSignRawMessage, delegatedSignTransaction, delegatedSponsorTransaction, encodeBase58, getBalance, revokeDelegation, sendTransaction };
|
|
1219
|
+
export { DynamicSvmWalletClient, ERROR_CREATE_WALLET_ACCOUNT, ERROR_DELEGATED_SIGN_TRANSACTION_CONTEXT_REQUIRED, ERROR_SIGN_RAW_MESSAGE, ERROR_SIGN_TRANSACTION_CONTEXT_REQUIRED, ERROR_SIGN_TRANSACTION_RAW_HEX_CONTEXT_REQUIRED, EarnSolanaStepError, addSignatureToTransaction, attachSignature, createDelegatedSvmWalletClient, createSolanaTransaction, createSvmEarnClient, decodeBase58, delegatedSignMessage, delegatedSignRawMessage, delegatedSignTransaction, delegatedSponsorTransaction, encodeBase58, getBalance, revokeDelegation, sendTransaction };
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamic-labs-wallet/node-svm",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.53",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@dynamic-labs-wallet/node": "1.1.
|
|
7
|
+
"@dynamic-labs-wallet/node": "1.1.53",
|
|
8
8
|
"@solana/web3.js": "^1.98.2"
|
|
9
9
|
},
|
|
10
10
|
"publishConfig": {
|
package/src/client/client.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type ServerKeyShare, DynamicWalletClient, type Ed25519KeygenResult, type ThresholdSignatureScheme, type TraceContext, type DynamicWalletClientProps, type WalletMetadata, type WalletApiKeyCreationResult, type RawSignPreImage, type SignMessageContext } from '@dynamic-labs-wallet/node';
|
|
2
2
|
import { type Transaction, VersionedTransaction } from '@solana/web3.js';
|
|
3
|
+
import type { ClaimEarnRewardsParams, DepositToEarnVaultParams, EarnTransactionResult, ExecuteEarnTransactionParams, WithdrawFromEarnVaultParams } from './earn.types.js';
|
|
3
4
|
type SvmSignableTransaction = VersionedTransaction | Transaction | string;
|
|
4
5
|
type SignTransactionResult = string | {
|
|
5
6
|
signature: string;
|
|
@@ -168,6 +169,18 @@ export declare class DynamicSvmWalletClient extends DynamicWalletClient {
|
|
|
168
169
|
derivationPath: string | undefined;
|
|
169
170
|
thresholdSignatureScheme: ThresholdSignatureScheme;
|
|
170
171
|
}[]>;
|
|
172
|
+
private get svmEarn();
|
|
173
|
+
/**
|
|
174
|
+
* Executes an Earn signing payload returned by the prepare* methods, signing and
|
|
175
|
+
* sending its ordered Solana transaction sequence one transaction at a time.
|
|
176
|
+
*/
|
|
177
|
+
executeEarnTransaction(params: ExecuteEarnTransactionParams): Promise<EarnTransactionResult>;
|
|
178
|
+
/** Prepares and executes a deposit into an Earn vault. */
|
|
179
|
+
depositToEarnVault(params: DepositToEarnVaultParams): Promise<EarnTransactionResult>;
|
|
180
|
+
/** Prepares and executes a withdrawal from an Earn vault. */
|
|
181
|
+
withdrawFromEarnVault(params: WithdrawFromEarnVaultParams): Promise<EarnTransactionResult>;
|
|
182
|
+
/** Prepares and executes a claim of accrued Earn vault rewards. */
|
|
183
|
+
claimEarnRewards(params: ClaimEarnRewardsParams): Promise<EarnTransactionResult>;
|
|
171
184
|
}
|
|
172
185
|
export {};
|
|
173
186
|
//# sourceMappingURL=client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EACnB,mBAAmB,EACnB,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,YAAY,EAGjB,KAAK,wBAAwB,EAC7B,KAAK,cAAc,EACnB,KAAK,0BAA0B,EAE/B,KAAK,eAAe,EAGpB,KAAK,kBAAkB,EACxB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAW,KAAK,WAAW,EAAE,oBAAoB,EAAa,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { EarnClient, ServerKeyShare, SignMessageContext, WalletMetadata } from '@dynamic-labs-wallet/node';
|
|
2
|
+
import { Transaction, VersionedTransaction } from '@solana/web3.js';
|
|
3
|
+
import type { ClaimEarnRewardsParams, DepositToEarnVaultParams, EarnTransactionResult, ExecuteEarnTransactionParams, WithdrawFromEarnVaultParams } from './earn.types.js';
|
|
4
|
+
type EarnStepErrorCode = 'yield_step_expired' | 'yield_step_failed' | 'yield_step_send_failed' | 'yield_step_confirmation_unknown';
|
|
5
|
+
/**
|
|
6
|
+
* A transaction in the sequence could not land. Transactions before `ordinal` already
|
|
7
|
+
* confirmed on-chain, so the action may be partially applied.
|
|
8
|
+
*/
|
|
9
|
+
export declare class EarnSolanaStepError extends Error {
|
|
10
|
+
readonly code: EarnStepErrorCode;
|
|
11
|
+
readonly ordinal: number;
|
|
12
|
+
readonly signature?: string;
|
|
13
|
+
constructor({ cause, code, ordinal, reason, signature, total, }: {
|
|
14
|
+
cause?: Error;
|
|
15
|
+
code: EarnStepErrorCode;
|
|
16
|
+
ordinal: number;
|
|
17
|
+
reason: string;
|
|
18
|
+
signature?: string;
|
|
19
|
+
total: number;
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
type SignEarnTransaction = (args: {
|
|
23
|
+
walletMetadata: WalletMetadata;
|
|
24
|
+
transaction: Transaction | VersionedTransaction;
|
|
25
|
+
password?: string;
|
|
26
|
+
externalServerKeyShares?: ServerKeyShare[];
|
|
27
|
+
sponsor?: boolean;
|
|
28
|
+
chainId?: string;
|
|
29
|
+
context?: SignMessageContext;
|
|
30
|
+
}) => Promise<string | {
|
|
31
|
+
signature: string;
|
|
32
|
+
transaction: Transaction | VersionedTransaction;
|
|
33
|
+
}>;
|
|
34
|
+
/** Primitives the Earn client borrows from whoever owns the wallet. */
|
|
35
|
+
export type SvmEarnClientDeps = {
|
|
36
|
+
getEarnClient: () => EarnClient;
|
|
37
|
+
signTransaction: SignEarnTransaction;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Builds a stateless Earn client for Solana vaults: it prepares vault actions through the
|
|
41
|
+
* Dynamic API and executes the returned ordered transaction sequence one transaction at a
|
|
42
|
+
* time — never in parallel, because a later transaction can depend on the state an earlier
|
|
43
|
+
* one wrote. If one fails, the sequence stops and the thrown {@link EarnSolanaStepError}
|
|
44
|
+
* reports how much of the action already landed.
|
|
45
|
+
*
|
|
46
|
+
* Gas sponsorship is opt-in (`sponsored: true`): vault transactions are built with the
|
|
47
|
+
* owner as fee payer, unlike the browser SDK which sponsors automatically.
|
|
48
|
+
*/
|
|
49
|
+
export declare const createSvmEarnClient: ({ getEarnClient, signTransaction }: SvmEarnClientDeps) => {
|
|
50
|
+
executeEarnTransaction: ({ signingPayload, walletMetadata, password, externalServerKeyShares, sponsored, rpcUrl, chainId, context, onStepChange, onTransactionStepChange, }: ExecuteEarnTransactionParams) => Promise<EarnTransactionResult>;
|
|
51
|
+
depositToEarnVault: ({ vaultId, amount, receiverAddress, traceContext, ...walletParams }: DepositToEarnVaultParams) => Promise<EarnTransactionResult>;
|
|
52
|
+
withdrawFromEarnVault: ({ vaultId, amount, receiverAddress, traceContext, ...walletParams }: WithdrawFromEarnVaultParams) => Promise<EarnTransactionResult>;
|
|
53
|
+
claimEarnRewards: ({ vaultId, traceContext, ...walletParams }: ClaimEarnRewardsParams) => Promise<EarnTransactionResult>;
|
|
54
|
+
};
|
|
55
|
+
export {};
|
|
56
|
+
//# sourceMappingURL=earn.client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"earn.client.d.ts","sourceRoot":"","sources":["../../src/client/earn.client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EAEV,cAAc,EACd,kBAAkB,EAClB,cAAc,EACf,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAc,WAAW,EAAE,oBAAoB,EAAyB,MAAM,iBAAiB,CAAC;AASvG,OAAO,KAAK,EACV,sBAAsB,EACtB,wBAAwB,EACxB,qBAAqB,EAErB,4BAA4B,EAC5B,2BAA2B,EAC5B,MAAM,iBAAiB,CAAC;AAGzB,KAAK,iBAAiB,GAClB,oBAAoB,GACpB,mBAAmB,GACnB,wBAAwB,GACxB,iCAAiC,CAAC;AAEtC;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;gBAEhB,EACV,KAAK,EACL,IAAI,EACJ,OAAO,EACP,MAAM,EACN,SAAS,EACT,KAAK,GACN,EAAE;QACD,KAAK,CAAC,EAAE,KAAK,CAAC;QACd,IAAI,EAAE,iBAAiB,CAAC;QACxB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;KACf;CAcF;AAED,KAAK,mBAAmB,GAAG,CAAC,IAAI,EAAE;IAChC,cAAc,EAAE,cAAc,CAAC;IAC/B,WAAW,EAAE,WAAW,GAAG,oBAAoB,CAAC;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uBAAuB,CAAC,EAAE,cAAc,EAAE,CAAC;IAC3C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,kBAAkB,CAAC;CAC9B,KAAK,OAAO,CAAC,MAAM,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,WAAW,GAAG,oBAAoB,CAAA;CAAE,CAAC,CAAC;AAE/F,uEAAuE;AACvE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,aAAa,EAAE,MAAM,UAAU,CAAC;IAChC,eAAe,EAAE,mBAAmB,CAAC;CACtC,CAAC;AAsJF;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,uCAAwC,iBAAiB;iLAmHpF,4BAA4B,KAAG,OAAO,CAAC,qBAAqB,CAAC;8FAsD3D,wBAAwB,KAAG,OAAO,CAAC,qBAAqB,CAAC;iGAiBzD,2BAA2B,KAAG,OAAO,CAAC,qBAAqB,CAAC;mEAe5D,sBAAsB,KAAG,OAAO,CAAC,qBAAqB,CAAC;CAS7D,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const ERROR_EARN_NOT_SVM_WALLET = "Wallet metadata is not for an SVM wallet";
|
|
2
|
+
export declare const ERROR_EARN_MISSING_TRANSACTIONS = "Earn signing payload is missing the Solana transaction sequence";
|
|
3
|
+
export declare const ERROR_EARN_NON_CONTIGUOUS_ORDINALS = "Earn signing payload transaction ordinals must be contiguous from zero";
|
|
4
|
+
/** Default RPC per Dynamic Solana chain id (101 mainnet, 103 devnet); `rpcUrl` overrides. */
|
|
5
|
+
export declare const EARN_SOLANA_RPC_BY_CHAIN_ID: Record<string, string>;
|
|
6
|
+
/** Blockhash checks run at `processed`, the commitment that sees new blockhashes first. */
|
|
7
|
+
export declare const EARN_SOLANA_BLOCKHASH_COMMITMENT: "processed";
|
|
8
|
+
export declare const EARN_CONFIRMATION_POLL_INTERVAL_MS = 1000;
|
|
9
|
+
//# sourceMappingURL=earn.constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"earn.constants.d.ts","sourceRoot":"","sources":["../../src/client/earn.constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,yBAAyB,6CAA6C,CAAC;AAEpF,eAAO,MAAM,+BAA+B,oEAAoE,CAAC;AAEjH,eAAO,MAAM,kCAAkC,2EAC2B,CAAC;AAE3E,6FAA6F;AAC7F,eAAO,MAAM,2BAA2B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAG9D,CAAC;AAEF,2FAA2F;AAC3F,eAAO,MAAM,gCAAgC,aAAuB,CAAC;AAErE,eAAO,MAAM,kCAAkC,OAAO,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { EarnExecutionStep, EarnSigningPayload, ServerKeyShare, SignMessageContext, TraceContext, WalletMetadata } from '@dynamic-labs-wallet/node';
|
|
2
|
+
export type { EarnExecutionStep, EarnTransactionResult } from '@dynamic-labs-wallet/node';
|
|
3
|
+
/** Position of the transaction about to be signed within the ordered sequence. */
|
|
4
|
+
export type EarnTransactionStepProgress = {
|
|
5
|
+
label?: string;
|
|
6
|
+
ordinal: number;
|
|
7
|
+
total: number;
|
|
8
|
+
};
|
|
9
|
+
/** Wallet context and chain access every Earn write action needs. */
|
|
10
|
+
export type SvmEarnWalletParams = {
|
|
11
|
+
walletMetadata: WalletMetadata;
|
|
12
|
+
password?: string;
|
|
13
|
+
externalServerKeyShares?: ServerKeyShare[];
|
|
14
|
+
/** Opt in to Dynamic gas sponsorship for every transaction in the sequence. */
|
|
15
|
+
sponsored?: boolean;
|
|
16
|
+
/** Solana RPC endpoint; defaults to the public cluster for the payload's `chainId` (101 mainnet, 103 devnet). */
|
|
17
|
+
rpcUrl?: string;
|
|
18
|
+
chainId?: string;
|
|
19
|
+
context?: SignMessageContext;
|
|
20
|
+
onStepChange?: (step: EarnExecutionStep) => void;
|
|
21
|
+
/** Invoked as each transaction in the sequence is about to be signed. */
|
|
22
|
+
onTransactionStepChange?: (step: EarnTransactionStepProgress) => void;
|
|
23
|
+
traceContext?: TraceContext;
|
|
24
|
+
};
|
|
25
|
+
export type ExecuteEarnTransactionParams = Omit<SvmEarnWalletParams, 'traceContext'> & {
|
|
26
|
+
signingPayload: EarnSigningPayload;
|
|
27
|
+
};
|
|
28
|
+
export type DepositToEarnVaultParams = SvmEarnWalletParams & {
|
|
29
|
+
vaultId: string;
|
|
30
|
+
amount: string;
|
|
31
|
+
receiverAddress?: string;
|
|
32
|
+
};
|
|
33
|
+
export type WithdrawFromEarnVaultParams = SvmEarnWalletParams & {
|
|
34
|
+
vaultId: string;
|
|
35
|
+
amount: string;
|
|
36
|
+
receiverAddress?: string;
|
|
37
|
+
};
|
|
38
|
+
export type ClaimEarnRewardsParams = SvmEarnWalletParams & {
|
|
39
|
+
vaultId: string;
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=earn.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"earn.types.d.ts","sourceRoot":"","sources":["../../src/client/earn.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,cAAc,EACf,MAAM,2BAA2B,CAAC;AAEnC,YAAY,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAE1F,kFAAkF;AAClF,MAAM,MAAM,2BAA2B,GAAG;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,qEAAqE;AACrE,MAAM,MAAM,mBAAmB,GAAG;IAChC,cAAc,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uBAAuB,CAAC,EAAE,cAAc,EAAE,CAAC;IAC3C,+EAA+E;IAC/E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iHAAiH;IACjH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACjD,yEAAyE;IACzE,uBAAuB,CAAC,EAAE,CAAC,IAAI,EAAE,2BAA2B,KAAK,IAAI,CAAC;IACtE,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG,IAAI,CAAC,mBAAmB,EAAE,cAAc,CAAC,GAAG;IACrF,cAAc,EAAE,kBAAkB,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,mBAAmB,GAAG;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG,mBAAmB,GAAG;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,mBAAmB,GAAG;IACzD,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC"}
|
package/src/client/index.d.ts
CHANGED
|
@@ -2,4 +2,7 @@ export * from './client.js';
|
|
|
2
2
|
export * from './utils.js';
|
|
3
3
|
export * from './base58.js';
|
|
4
4
|
export * from './constants.js';
|
|
5
|
+
export { createSvmEarnClient, EarnSolanaStepError } from './earn.client.js';
|
|
6
|
+
export type { SvmEarnClientDeps } from './earn.client.js';
|
|
7
|
+
export type { ClaimEarnRewardsParams, DepositToEarnVaultParams, EarnTransactionStepProgress, ExecuteEarnTransactionParams, SvmEarnWalletParams, WithdrawFromEarnVaultParams, } from './earn.types.js';
|
|
5
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5E,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,YAAY,EACV,sBAAsB,EACtB,wBAAwB,EACxB,2BAA2B,EAC3B,4BAA4B,EAC5B,mBAAmB,EACnB,2BAA2B,GAC5B,MAAM,iBAAiB,CAAC"}
|