@zebec-network/zebec-vault-sdk 2.0.0 → 3.1.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/dist/service.js CHANGED
@@ -5,27 +5,36 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.ZebecVaultService = void 0;
7
7
  const assert_1 = __importDefault(require("assert"));
8
+ const bignumber_js_1 = require("bignumber.js");
8
9
  const anchor_1 = require("@coral-xyz/anchor");
9
10
  const web3_js_1 = require("@solana/web3.js");
11
+ const core_utils_1 = require("@zebec-network/core-utils");
10
12
  const solana_common_1 = require("@zebec-network/solana-common");
11
13
  const artifacts_1 = require("./artifacts");
14
+ const constants_1 = require("./constants");
12
15
  const pda_1 = require("./pda");
13
16
  const utils_1 = require("./utils");
14
17
  class ZebecVaultService {
15
18
  provider;
16
- program;
19
+ vaultV1Program;
20
+ cardV2Program;
21
+ streamProgram;
17
22
  network;
18
- constructor(provider, program, network) {
23
+ constructor(provider, vaultV1Program, cardV2Program, streamProgram, network) {
19
24
  this.provider = provider;
20
- this.program = program;
25
+ this.vaultV1Program = vaultV1Program;
26
+ this.cardV2Program = cardV2Program;
27
+ this.streamProgram = streamProgram;
21
28
  this.network = network;
22
29
  }
23
- static async create(provider, network, program) {
24
- program = program ?? new anchor_1.Program(artifacts_1.ZEBEC_VAULT_IDL_V1, provider);
25
- return new ZebecVaultService(provider, program, network);
30
+ static create(provider, network) {
31
+ const vaultV1Program = new anchor_1.Program(artifacts_1.ZEBEC_VAULT_V1_IDL, provider);
32
+ const cardV2Program = new anchor_1.Program(artifacts_1.ZEBEC_CARD_V2_IDL, provider);
33
+ const streamProgram = new anchor_1.Program(artifacts_1.ZEBEC_STREAM_IDL, provider);
34
+ return new ZebecVaultService(provider, vaultV1Program, cardV2Program, streamProgram, network);
26
35
  }
27
36
  async getCreateVaultInstruction(payer, owner, signerBump) {
28
- return this.program.methods
37
+ return this.vaultV1Program.methods
29
38
  .createVault({
30
39
  owner,
31
40
  signerBump,
@@ -36,7 +45,7 @@ class ZebecVaultService {
36
45
  .instruction();
37
46
  }
38
47
  async getDepositSolInstruction(depositor, amount) {
39
- return this.program.methods
48
+ return this.vaultV1Program.methods
40
49
  .depositSol({
41
50
  amount,
42
51
  })
@@ -46,7 +55,7 @@ class ZebecVaultService {
46
55
  .instruction();
47
56
  }
48
57
  async getWithdrawSolInstruction(withdrawer, amount) {
49
- return this.program.methods
58
+ return this.vaultV1Program.methods
50
59
  .withdrawSol({
51
60
  amount,
52
61
  })
@@ -56,7 +65,7 @@ class ZebecVaultService {
56
65
  .instruction();
57
66
  }
58
67
  async getDepositTokenInstruction(depositor, tokenMint, amount, decimals) {
59
- return this.program.methods
68
+ return this.vaultV1Program.methods
60
69
  .depositToken({
61
70
  amount,
62
71
  decimals,
@@ -68,7 +77,7 @@ class ZebecVaultService {
68
77
  .instruction();
69
78
  }
70
79
  async getWithdrawTokenInstruction(withdrawer, tokenMint, amount, decimals) {
71
- return this.program.methods
80
+ return this.vaultV1Program.methods
72
81
  .withdrawToken({
73
82
  amount,
74
83
  decimals,
@@ -80,7 +89,7 @@ class ZebecVaultService {
80
89
  .instruction();
81
90
  }
82
91
  async getCreateProposalInstruction(proposer, proposal, name, actions, proposalAccountSize) {
83
- return this.program.methods
92
+ return this.vaultV1Program.methods
84
93
  .createProposal({
85
94
  actions,
86
95
  name,
@@ -93,7 +102,7 @@ class ZebecVaultService {
93
102
  .instruction();
94
103
  }
95
104
  async getAppendActionInstruction(proposer, proposal, actions, newProposalAccountSize) {
96
- return this.program.methods
105
+ return this.vaultV1Program.methods
97
106
  .appendActions({
98
107
  actions,
99
108
  proposalAccountSize: newProposalAccountSize,
@@ -105,7 +114,7 @@ class ZebecVaultService {
105
114
  .instruction();
106
115
  }
107
116
  async getDeleteProposalInstruction(proposal) {
108
- return this.program.methods
117
+ return this.vaultV1Program.methods
109
118
  .deleteProposal()
110
119
  .accounts({
111
120
  proposal,
@@ -113,7 +122,7 @@ class ZebecVaultService {
113
122
  .instruction();
114
123
  }
115
124
  async getExecuteProposalInstruction(caller, proposal, remainingAccounts) {
116
- return this.program.methods
125
+ return this.vaultV1Program.methods
117
126
  .executeProposal()
118
127
  .accounts({
119
128
  proposal,
@@ -123,7 +132,7 @@ class ZebecVaultService {
123
132
  .instruction();
124
133
  }
125
134
  async getExecuteProposalDirectInstruction(proposer, actions, remainingAccounts) {
126
- return this.program.methods
135
+ return this.vaultV1Program.methods
127
136
  .executeProposalDirect({
128
137
  actions,
129
138
  })
@@ -133,13 +142,96 @@ class ZebecVaultService {
133
142
  .remainingAccounts(remainingAccounts)
134
143
  .instruction();
135
144
  }
145
+ async getSwapAndCreateSilverCardInstruction(cardVault, cardVaultAta, inputMint, inputMintProgram, outputMint, revenueVault, revenueVaultAta, vaultOwner, data, remainingAccounts) {
146
+ const { currency, emailHash, index, swapData } = data;
147
+ return this.vaultV1Program.methods
148
+ .swapAndCreateSilverCard({
149
+ currency,
150
+ emailHash,
151
+ index,
152
+ swapData,
153
+ })
154
+ .accounts({
155
+ cardVault,
156
+ cardVaultAta,
157
+ inputMint,
158
+ inputMintProgram,
159
+ outputMint,
160
+ outputMintProgram: solana_common_1.TOKEN_PROGRAM_ID,
161
+ revenueVault,
162
+ revenueVaultAta,
163
+ vaultOwner,
164
+ })
165
+ .remainingAccounts(remainingAccounts)
166
+ .instruction();
167
+ }
168
+ async getSwapAndLoadCarbonCardInstruction(cardVault, cardVaultAta, inputMint, inputMintProgram, outputMint, revenueVault, revenueVaultAta, vaultOwner, data, remainingAccounts) {
169
+ const { currency, emailHash, index, swapData, reloadCardId } = data;
170
+ return this.vaultV1Program.methods
171
+ .swapAndLoadCarbonCard({
172
+ currency,
173
+ emailHash,
174
+ index,
175
+ reloadCardId,
176
+ swapData,
177
+ })
178
+ .accounts({
179
+ cardVault,
180
+ cardVaultAta,
181
+ inputMint,
182
+ inputMintProgram,
183
+ outputMint,
184
+ outputMintProgram: solana_common_1.TOKEN_PROGRAM_ID,
185
+ revenueVault,
186
+ revenueVaultAta,
187
+ vaultOwner,
188
+ })
189
+ .remainingAccounts(remainingAccounts)
190
+ .instruction();
191
+ }
192
+ async getCreateStreamFromVaultInstruction(vaultOwner, vault, vaultSigner, vaultSignerAta, receiver, receiverAta, streamToken, streamMetadata, streamConfig, withdrawAccount, streamVault, streamVaultAta, zebecStreamProgram, streamData) {
193
+ return this.vaultV1Program.methods
194
+ .createStream({
195
+ amount: streamData.amount,
196
+ automaticWithdrawal: Number(streamData.automaticWithdrawal),
197
+ cancelableByRecipient: Number(streamData.cancelableByRecipient),
198
+ cancelableBySender: Number(streamData.cancelableBySender),
199
+ canTopup: Number(streamData.canTopup),
200
+ cliffPercentage: streamData.cliffPercentage,
201
+ duration: streamData.duration,
202
+ isPausable: Number(streamData.isPausable),
203
+ rateUpdatable: Number(streamData.rateUpdatable),
204
+ startNow: Number(streamData.startNow),
205
+ startTime: streamData.startTime,
206
+ streamFrequency: streamData.autoWithdrawFrequency,
207
+ streamName: Array.from(streamData.streamName),
208
+ transferableByRecipient: Number(streamData.transferableByRecipient),
209
+ transferableBySender: Number(streamData.transferableBySender),
210
+ })
211
+ .accountsPartial({
212
+ receiver,
213
+ streamToken,
214
+ vaultSignerAta,
215
+ withdrawAccount,
216
+ streamMetadata,
217
+ vaultOwner,
218
+ vault,
219
+ vaultSigner,
220
+ receiverAta,
221
+ streamConfig,
222
+ streamVault,
223
+ streamVaultAta,
224
+ zebecStreamProgram,
225
+ })
226
+ .instruction();
227
+ }
136
228
  async createVault(params) {
137
229
  const payer = params.payer ? (0, anchor_1.translateAddress)(params.payer) : this.provider.publicKey;
138
230
  if (!payer) {
139
231
  throw new Error("Either provide a payer or use AnchorProvider for provider in the service");
140
232
  }
141
- const [vault] = (0, pda_1.deriveUserVault)(payer, this.programId);
142
- const [, signerBump] = (0, pda_1.deriveVaultSigner)(vault, this.programId);
233
+ const [vault] = (0, pda_1.deriveUserVault)(payer, this.vaultV1ProgramId);
234
+ const [, signerBump] = (0, pda_1.deriveVaultSigner)(vault, this.vaultV1ProgramId);
143
235
  const ix = await this.getCreateVaultInstruction(payer, payer, signerBump);
144
236
  return this._createTransactionPayload(payer, [ix]);
145
237
  }
@@ -207,7 +299,7 @@ class ZebecVaultService {
207
299
  throw new Error("Either provide a proposer or use AnchorProvider for provider in the service");
208
300
  }
209
301
  const proposal = (0, anchor_1.translateAddress)(params.proposal);
210
- const proposalAccount = await this.program.account.proposal.fetchNullable(proposal, this.connection.commitment);
302
+ const proposalAccount = await this.vaultV1Program.account.proposal.fetchNullable(proposal, this.connection.commitment);
211
303
  if (!proposalAccount) {
212
304
  throw new Error("Proposal account not found");
213
305
  }
@@ -240,12 +332,12 @@ class ZebecVaultService {
240
332
  throw new Error("Either provide a caller or use AnchorProvider for provider in the service");
241
333
  }
242
334
  const proposal = (0, anchor_1.translateAddress)(params.proposal);
243
- const proposalAccount = await this.program.account.proposal.fetchNullable(proposal, this.connection.commitment);
335
+ const proposalAccount = await this.vaultV1Program.account.proposal.fetchNullable(proposal, this.connection.commitment);
244
336
  if (!proposalAccount) {
245
337
  throw new Error("Proposal account not found");
246
338
  }
247
339
  const vault = proposalAccount.vault;
248
- const [vaultSigner] = (0, pda_1.deriveVaultSigner)(vault, this.programId);
340
+ const [vaultSigner] = (0, pda_1.deriveVaultSigner)(vault, this.vaultV1ProgramId);
249
341
  const remainingAccounts = proposalAccount.actions.reduce((acc, current) => {
250
342
  const accounts = current.accountSpecs.map((spec) => ({
251
343
  pubkey: spec.pubkey,
@@ -279,8 +371,8 @@ class ZebecVaultService {
279
371
  if (!proposer) {
280
372
  throw new Error("Either provide a caller or use AnchorProvider for provider in the service");
281
373
  }
282
- const [vault] = (0, pda_1.deriveUserVault)(proposer, this.programId);
283
- const [vaultSigner] = (0, pda_1.deriveVaultSigner)(vault, this.programId);
374
+ const [vault] = (0, pda_1.deriveUserVault)(proposer, this.vaultV1ProgramId);
375
+ const [vaultSigner] = (0, pda_1.deriveVaultSigner)(vault, this.vaultV1ProgramId);
284
376
  const actions = params.actions.map((ix) => ({
285
377
  accountSpecs: ix.keys,
286
378
  data: ix.data,
@@ -313,9 +405,255 @@ class ZebecVaultService {
313
405
  }
314
406
  return this._createTransactionPayload(proposer, [ix], params.partialSigners, addressLookupTableAccounts);
315
407
  }
408
+ async swapAndCreateSilverCard(params) {
409
+ const { vaultOwnerAddress, quoteInfo, emailHash, wrapAndUnwrapSol } = params;
410
+ if ("error" in quoteInfo) {
411
+ throw new Error(quoteInfo.error);
412
+ }
413
+ (0, core_utils_1.assertBufferSize)(emailHash, 32);
414
+ // const [cardConfig] = deriveCardConfigPda(this.cardV2ProgramId);
415
+ // console.log("cardConfig:", cardConfig.toString());
416
+ // const cardConfigInfo = await this.cardV2Program.account.card.fetch(cardConfig, this.connection.commitment);
417
+ const vaultOwner = (0, anchor_1.translateAddress)(vaultOwnerAddress);
418
+ const [vault] = (0, pda_1.deriveUserVault)(vaultOwner, this.vaultV1ProgramId);
419
+ const [vaultSigner] = (0, pda_1.deriveVaultSigner)(vault, this.vaultV1ProgramId);
420
+ const inputMint = (0, anchor_1.translateAddress)(quoteInfo.inputMint);
421
+ const usdc = (0, anchor_1.translateAddress)(quoteInfo.outputMint);
422
+ // const [userPurchaseRecord] = deriveUserPurchaseRecordPda(user, this.vaultV1ProgramId);
423
+ // const revenueVault = cardConfigInfo.revenueVault;
424
+ const revenueVault = web3_js_1.Keypair.generate().publicKey;
425
+ // const cardVault = cardConfigInfo.cardVault;
426
+ const cardVault = web3_js_1.Keypair.generate().publicKey;
427
+ const cardVaultAta = (0, solana_common_1.getAssociatedTokenAddressSync)(usdc, cardVault, true);
428
+ const revenueVaultAta = (0, solana_common_1.getAssociatedTokenAddressSync)(usdc, revenueVault, true);
429
+ // const amount =
430
+ // quoteInfo.swapMode === "ExactIn"
431
+ // ? new BigNumber(quoteInfo.otherAmountThreshold)
432
+ // : new BigNumber(quoteInfo.outAmount);
433
+ // if (!usdc.equals(cardConfigInfo.usdcMint)) {
434
+ // throw new Error(`Invalid usdc: ${usdc.toString()}`);
435
+ // }
436
+ // const userInputMintAta = getAssociatedTokenAddressSync(inputMint, user);
437
+ const { swapTransaction } = await (await fetch("https://lite-api.jup.ag/swap/v1/swap", {
438
+ method: "POST",
439
+ headers: {
440
+ "Content-Type": "application/json",
441
+ },
442
+ body: JSON.stringify({
443
+ // quoteResponse from /quote api
444
+ quoteResponse: quoteInfo,
445
+ // user public key to be used for the swap
446
+ userPublicKey: vaultSigner.toString(),
447
+ // auto wrap and unwrap SOL. default is true
448
+ wrapAndUnwrapSol: wrapAndUnwrapSol ?? false,
449
+ // feeAccount is optional. Use if you want to charge a fee. feeBps must have been passed in /quote API.
450
+ // feeAccount: "fee_account_public_key"
451
+ }),
452
+ })).json();
453
+ // deserialize the transaction
454
+ const swapTransactionBuf = Buffer.from(swapTransaction, "base64");
455
+ const transaction = web3_js_1.VersionedTransaction.deserialize(swapTransactionBuf);
456
+ // get address lookup table accounts
457
+ const addressLookupTableAccounts = await Promise.all(transaction.message.addressTableLookups.map(async (lookup) => {
458
+ const data = await this.connection.getAccountInfo(lookup.accountKey).then((res) => res.data);
459
+ return new web3_js_1.AddressLookupTableAccount({
460
+ key: lookup.accountKey,
461
+ state: web3_js_1.AddressLookupTableAccount.deserialize(data),
462
+ });
463
+ }));
464
+ const lookupTableData = await new web3_js_1.Connection((0, web3_js_1.clusterApiUrl)("devnet"))
465
+ .getAccountInfo((0, anchor_1.translateAddress)(constants_1.CARD_LOOKUP_TABLE_ADDRESS))
466
+ .then((res) => res.data);
467
+ addressLookupTableAccounts.push(new web3_js_1.AddressLookupTableAccount({
468
+ key: (0, anchor_1.translateAddress)(constants_1.CARD_LOOKUP_TABLE_ADDRESS),
469
+ state: web3_js_1.AddressLookupTableAccount.deserialize(lookupTableData),
470
+ }));
471
+ // console.log("address lookup table:\n", addressLookupTableAccounts);
472
+ // decompile transaction message and add transfer instruction
473
+ const message = web3_js_1.TransactionMessage.decompile(transaction.message, {
474
+ addressLookupTableAccounts: addressLookupTableAccounts,
475
+ });
476
+ const swapInstruction = message.instructions.find((ix) => ix.programId.equals((0, anchor_1.translateAddress)(constants_1.JUPITER_AGGREGATOR_PROGRAM_ID)));
477
+ (0, assert_1.default)(swapInstruction, "Swap instruction not found in the transaction message");
478
+ const otherIxs = message.instructions.filter((ix) => !ix.programId.equals((0, anchor_1.translateAddress)(constants_1.JUPITER_AGGREGATOR_PROGRAM_ID)));
479
+ const index = new anchor_1.BN(params.nextCardCounter.toString());
480
+ const swapAndCreateSilverCardIx = await this.getSwapAndCreateSilverCardInstruction(cardVault, cardVaultAta, inputMint, solana_common_1.TOKEN_PROGRAM_ID, usdc, revenueVault, revenueVaultAta, vaultOwner, {
481
+ index,
482
+ currency: params.currency,
483
+ emailHash: Array.from(emailHash),
484
+ swapData: swapInstruction.data,
485
+ }, swapInstruction.keys);
486
+ otherIxs.push(swapAndCreateSilverCardIx);
487
+ return this._createTransactionPayload(vaultOwner, otherIxs, [], addressLookupTableAccounts);
488
+ }
489
+ async swapAndLoadCarbonCard(params) {
490
+ const { vaultOwnerAddress, quoteInfo, emailHash, reloadCardId } = params;
491
+ if ("error" in quoteInfo) {
492
+ throw new Error(quoteInfo.error);
493
+ }
494
+ (0, core_utils_1.assertBufferSize)(emailHash, 32);
495
+ const [cardConfig] = (0, pda_1.deriveCardConfigPda)(this.cardV2ProgramId);
496
+ console.log("cardConfig:", cardConfig.toString());
497
+ const cardConfigInfo = await this.cardV2Program.account.card.fetch(cardConfig, this.connection.commitment);
498
+ const vaultOwner = (0, anchor_1.translateAddress)(vaultOwnerAddress);
499
+ const [vault] = (0, pda_1.deriveUserVault)(vaultOwner, this.vaultV1ProgramId);
500
+ const [vaultSigner] = (0, pda_1.deriveVaultSigner)(vault, this.vaultV1ProgramId);
501
+ // const feePayer = user;
502
+ const inputMint = (0, anchor_1.translateAddress)(quoteInfo.inputMint);
503
+ const usdc = (0, anchor_1.translateAddress)(quoteInfo.outputMint);
504
+ // const [userPurchaseRecord] = deriveUserPurchaseRecordPda(user, this.vaultV1ProgramId);
505
+ const revenueVault = cardConfigInfo.revenueVault;
506
+ const cardVault = cardConfigInfo.cardVault;
507
+ const cardVaultAta = (0, solana_common_1.getAssociatedTokenAddressSync)(usdc, cardVault, true);
508
+ const revenueVaultAta = (0, solana_common_1.getAssociatedTokenAddressSync)(usdc, revenueVault, true);
509
+ const { swapTransaction } = await (await fetch("https://lite-api.jup.ag/swap/v1/swap", {
510
+ method: "POST",
511
+ headers: {
512
+ "Content-Type": "application/json",
513
+ },
514
+ body: JSON.stringify({
515
+ // quoteResponse from /quote api
516
+ quoteResponse: quoteInfo,
517
+ // user public key to be used for the swap
518
+ userPublicKey: vaultSigner.toString(),
519
+ // auto wrap and unwrap SOL. default is true
520
+ wrapAndUnwrapSol: false,
521
+ // feeAccount is optional. Use if you want to charge a fee. feeBps must have been passed in /quote API.
522
+ // feeAccount: "fee_account_public_key"
523
+ }),
524
+ })).json();
525
+ // deserialize the transaction
526
+ const swapTransactionBuf = Buffer.from(swapTransaction, "base64");
527
+ const transaction = web3_js_1.VersionedTransaction.deserialize(swapTransactionBuf);
528
+ // get address lookup table accounts
529
+ const addressLookupTableAccounts = await Promise.all(transaction.message.addressTableLookups.map(async (lookup) => {
530
+ const data = await this.connection.getAccountInfo(lookup.accountKey).then((res) => res.data);
531
+ return new web3_js_1.AddressLookupTableAccount({
532
+ key: lookup.accountKey,
533
+ state: web3_js_1.AddressLookupTableAccount.deserialize(data),
534
+ });
535
+ }));
536
+ const lookupTableData = await new web3_js_1.Connection((0, web3_js_1.clusterApiUrl)("devnet"))
537
+ .getAccountInfo((0, anchor_1.translateAddress)(constants_1.CARD_LOOKUP_TABLE_ADDRESS))
538
+ .then((res) => res.data);
539
+ addressLookupTableAccounts.push(new web3_js_1.AddressLookupTableAccount({
540
+ key: (0, anchor_1.translateAddress)(constants_1.CARD_LOOKUP_TABLE_ADDRESS),
541
+ state: web3_js_1.AddressLookupTableAccount.deserialize(lookupTableData),
542
+ }));
543
+ // console.log("address lookup table:\n", addressLookupTableAccounts);
544
+ // decompile transaction message and add transfer instruction
545
+ const message = web3_js_1.TransactionMessage.decompile(transaction.message, {
546
+ addressLookupTableAccounts: addressLookupTableAccounts,
547
+ });
548
+ const swapInstruction = message.instructions.find((ix) => ix.programId.equals((0, anchor_1.translateAddress)(constants_1.JUPITER_AGGREGATOR_PROGRAM_ID)));
549
+ (0, assert_1.default)(swapInstruction, "Swap instruction not found in the transaction message");
550
+ const otherIxs = message.instructions.filter((ix) => !ix.programId.equals((0, anchor_1.translateAddress)(constants_1.JUPITER_AGGREGATOR_PROGRAM_ID)));
551
+ const index = new anchor_1.BN(params.nextCardCounter.toString());
552
+ const swapAndCreateSilverCardIx = await this.getSwapAndLoadCarbonCardInstruction(cardVault, cardVaultAta, inputMint, solana_common_1.TOKEN_PROGRAM_ID, usdc, revenueVault, revenueVaultAta, vaultOwner, {
553
+ index,
554
+ currency: params.currency,
555
+ emailHash: Array.from(emailHash),
556
+ swapData: swapInstruction.data,
557
+ reloadCardId,
558
+ }, swapInstruction.keys);
559
+ otherIxs.push(swapAndCreateSilverCardIx);
560
+ return this._createTransactionPayload(vaultOwner, otherIxs, [], addressLookupTableAccounts);
561
+ }
562
+ async createStreamFromVault(params) {
563
+ const vaultOwner = (0, anchor_1.translateAddress)(params.sender);
564
+ const [vault] = (0, pda_1.deriveUserVault)(vaultOwner, this.vaultV1ProgramId);
565
+ const [vaultSigner] = (0, pda_1.deriveVaultSigner)(vault, this.vaultV1ProgramId);
566
+ const receiver = (0, anchor_1.translateAddress)(params.receiver);
567
+ const [receiverVault] = (0, pda_1.deriveUserVault)(receiver, this.vaultV1ProgramId);
568
+ const [receiverVaultSigner] = (0, pda_1.deriveVaultSigner)(receiverVault, this.vaultV1ProgramId);
569
+ const streamToken = (0, anchor_1.translateAddress)(params.streamToken);
570
+ const vaultSignerAta = (0, solana_common_1.getAssociatedTokenAddressSync)(streamToken, vaultSigner, true);
571
+ const receiverVaultSignerAta = (0, solana_common_1.getAssociatedTokenAddressSync)(streamToken, receiverVaultSigner, true);
572
+ const [streamConfig] = (0, pda_1.deriveStreamConfigPda)(this.streamProgramId);
573
+ const streamConfigInfo = await this.streamProgram.account.streamConfig.fetch(streamConfig, this.connection.commitment);
574
+ const withdrawAccount = streamConfigInfo.withdrawAccount;
575
+ const streamMetatdataKeypair = params.streamMetadataKeypair ?? web3_js_1.Keypair.generate();
576
+ const streamMetadata = streamMetatdataKeypair.publicKey;
577
+ const [streamVault] = (0, pda_1.deriveStreamVaultPda)(streamMetadata, this.streamProgramId);
578
+ const streamVaultAta = (0, solana_common_1.getAssociatedTokenAddressSync)(streamToken, streamVault, true);
579
+ const streamTokenDecimals = await (0, solana_common_1.getMintDecimals)(this.connection, streamToken);
580
+ const amount = new anchor_1.BN((0, bignumber_js_1.BigNumber)(params.amount).times(constants_1.TEN_BIGNUM.pow(streamTokenDecimals)).toFixed(0));
581
+ const cliffPercentage = new anchor_1.BN((0, core_utils_1.percentToBps)(params.cliffPercentage));
582
+ const STREAM_NAME_BUFFER_SIZE = 128;
583
+ const streamNameArray = new Uint8Array(STREAM_NAME_BUFFER_SIZE);
584
+ streamNameArray.set(anchor_1.utils.bytes.utf8.encode(params.streamName));
585
+ const ix = await this.getCreateStreamFromVaultInstruction(vaultOwner, vault, vaultSigner, vaultSignerAta, receiverVaultSigner, receiverVaultSignerAta, streamToken, streamMetadata, streamConfig, withdrawAccount, streamVault, streamVaultAta, this.streamProgramId, {
586
+ amount,
587
+ automaticWithdrawal: params.automaticWithdrawal,
588
+ autoWithdrawFrequency: new anchor_1.BN(params.autoWithdrawFrequency),
589
+ cancelableByRecipient: params.cancelableByRecipient,
590
+ cancelableBySender: params.cancelableBySender,
591
+ canTopup: params.canTopup,
592
+ cliffPercentage,
593
+ duration: new anchor_1.BN(params.duration),
594
+ isPausable: params.isPausable,
595
+ numberOfWithdrawls: new anchor_1.BN(Math.floor(params.duration / params.autoWithdrawFrequency)),
596
+ rateUpdatable: params.rateUpdatable,
597
+ startNow: params.startNow,
598
+ startTime: new anchor_1.BN(params.startTime),
599
+ streamName: streamNameArray,
600
+ transferableByRecipient: params.transferableByRecipient,
601
+ transferableBySender: params.transferableBySender,
602
+ });
603
+ return this._createTransactionPayload(vaultOwner, [ix], [streamMetatdataKeypair]);
604
+ }
605
+ async createMultipleStreamFromVault(params) {
606
+ const vaultOwner = (0, anchor_1.translateAddress)(params.sender);
607
+ const [vault] = (0, pda_1.deriveUserVault)(vaultOwner, this.vaultV1ProgramId);
608
+ const [vaultSigner] = (0, pda_1.deriveVaultSigner)(vault, this.vaultV1ProgramId);
609
+ const transactionArtifacts = await Promise.all(params.streamInfo.map(async (info) => {
610
+ const receiver = (0, anchor_1.translateAddress)(info.receiver);
611
+ const [receiverVault] = (0, pda_1.deriveUserVault)(receiver, this.vaultV1ProgramId);
612
+ const [receiverVaultSigner] = (0, pda_1.deriveVaultSigner)(receiverVault, this.vaultV1ProgramId);
613
+ const streamToken = (0, anchor_1.translateAddress)(info.streamToken);
614
+ const vaultSignerAta = (0, solana_common_1.getAssociatedTokenAddressSync)(streamToken, vaultSigner, true);
615
+ const receiverVaultSignerAta = (0, solana_common_1.getAssociatedTokenAddressSync)(streamToken, receiverVaultSigner, true);
616
+ const [streamConfig] = (0, pda_1.deriveStreamConfigPda)(this.streamProgramId);
617
+ const streamConfigInfo = await this.streamProgram.account.streamConfig.fetch(streamConfig, this.connection.commitment);
618
+ const withdrawAccount = streamConfigInfo.withdrawAccount;
619
+ const streamMetatdataKeypair = info.streamMetadataKeypair ?? web3_js_1.Keypair.generate();
620
+ const streamMetadata = streamMetatdataKeypair.publicKey;
621
+ const [streamVault] = (0, pda_1.deriveStreamVaultPda)(streamMetadata, this.streamProgramId);
622
+ const streamVaultAta = (0, solana_common_1.getAssociatedTokenAddressSync)(streamToken, streamVault, true);
623
+ const streamTokenDecimals = await (0, solana_common_1.getMintDecimals)(this.connection, streamToken);
624
+ const amount = new anchor_1.BN((0, bignumber_js_1.BigNumber)(info.amount).times(constants_1.TEN_BIGNUM.pow(streamTokenDecimals)).toFixed(0));
625
+ const cliffPercentage = new anchor_1.BN((0, core_utils_1.percentToBps)(info.cliffPercentage));
626
+ const STREAM_NAME_BUFFER_SIZE = 128;
627
+ const streamNameArray = new Uint8Array(STREAM_NAME_BUFFER_SIZE);
628
+ streamNameArray.set(anchor_1.utils.bytes.utf8.encode(info.streamName), 0);
629
+ const ix = await this.getCreateStreamFromVaultInstruction(vaultOwner, vault, vaultSigner, vaultSignerAta, receiverVaultSigner, receiverVaultSignerAta, streamToken, streamMetadata, streamConfig, withdrawAccount, streamVault, streamVaultAta, this.streamProgramId, {
630
+ amount,
631
+ automaticWithdrawal: info.automaticWithdrawal,
632
+ autoWithdrawFrequency: new anchor_1.BN(info.autoWithdrawFrequency),
633
+ cancelableByRecipient: info.cancelableByRecipient,
634
+ cancelableBySender: info.cancelableBySender,
635
+ canTopup: info.canTopup,
636
+ cliffPercentage,
637
+ duration: new anchor_1.BN(info.duration),
638
+ isPausable: info.isPausable,
639
+ numberOfWithdrawls: new anchor_1.BN(Math.floor(info.duration / info.autoWithdrawFrequency)),
640
+ rateUpdatable: info.rateUpdatable,
641
+ startNow: info.startNow,
642
+ startTime: new anchor_1.BN(info.startTime),
643
+ streamName: streamNameArray,
644
+ transferableByRecipient: info.transferableByRecipient,
645
+ transferableBySender: info.transferableBySender,
646
+ });
647
+ return {
648
+ instructions: [ix],
649
+ signers: [streamMetatdataKeypair],
650
+ };
651
+ }));
652
+ return this._createMultiTransactionPayload(vaultOwner, transactionArtifacts);
653
+ }
316
654
  async _createTransactionPayload(payerKey, instructions, signers, addressLookupTableAccounts) {
317
655
  const errorMap = new Map();
318
- this.program.idl.errors.forEach((error) => errorMap.set(error.code, error.msg));
656
+ this.vaultV1Program.idl.errors.forEach((error) => errorMap.set(error.code, error.msg));
319
657
  let signTransaction = undefined;
320
658
  const provider = this.provider;
321
659
  if (provider instanceof anchor_1.AnchorProvider) {
@@ -323,15 +661,32 @@ class ZebecVaultService {
323
661
  return provider.wallet.signTransaction(tx);
324
662
  };
325
663
  }
326
- return new solana_common_1.TransactionPayload(this.provider.connection, errorMap, instructions, payerKey, signers, addressLookupTableAccounts, signTransaction);
664
+ return new solana_common_1.TransactionPayload(this.provider.connection, errorMap, { instructions, feePayer: payerKey, signers, addressLookupTableAccounts }, signTransaction);
665
+ }
666
+ async _createMultiTransactionPayload(payerKey, transactionArtifacts) {
667
+ const errorMap = new Map();
668
+ this.vaultV1Program.idl.errors.forEach((error) => errorMap.set(error.code, error.msg));
669
+ let signAllTransactions = undefined;
670
+ const provider = this.provider;
671
+ if (provider instanceof anchor_1.AnchorProvider) {
672
+ signAllTransactions = async (txns) => {
673
+ return provider.wallet.signAllTransactions(txns);
674
+ };
675
+ }
676
+ const transactionData = transactionArtifacts.map((data) => ({
677
+ instructions: data.instructions,
678
+ feePayer: payerKey,
679
+ signers: data.signers,
680
+ }));
681
+ return new solana_common_1.MultiTransactionPayload(this.connection, errorMap, transactionData, signAllTransactions);
327
682
  }
328
683
  async getVaultInfoOfUser(user) {
329
684
  user = user ? (0, anchor_1.translateAddress)(user) : this.provider.publicKey;
330
685
  if (!user) {
331
686
  throw new Error("Either provide a user or use AnchorProvider for provider in the service");
332
687
  }
333
- const [vault] = (0, pda_1.deriveUserVault)(user, this.programId);
334
- const vaultAccount = await this.program.account.vault.fetchNullable(vault, this.connection.commitment);
688
+ const [vault] = (0, pda_1.deriveUserVault)(user, this.vaultV1ProgramId);
689
+ const vaultAccount = await this.vaultV1Program.account.vault.fetchNullable(vault, this.connection.commitment);
335
690
  if (!vaultAccount) {
336
691
  return null;
337
692
  }
@@ -343,20 +698,20 @@ class ZebecVaultService {
343
698
  };
344
699
  }
345
700
  async getAllVaultsInfo() {
346
- const accountInfos = await this.connection.getProgramAccounts(this.programId, {
701
+ const accountInfos = await this.connection.getProgramAccounts(this.vaultV1ProgramId, {
347
702
  commitment: this.connection.commitment,
348
703
  filters: [
349
704
  {
350
705
  memcmp: {
351
706
  offset: 0, // offset for discriminator in Vault
352
- bytes: anchor_1.utils.bytes.bs58.encode(this.program.idl.accounts[1].discriminator),
707
+ bytes: anchor_1.utils.bytes.bs58.encode(this.vaultV1Program.idl.accounts[1].discriminator),
353
708
  encoding: "base58",
354
709
  },
355
710
  },
356
711
  ],
357
712
  });
358
713
  const vaults = accountInfos.map((accountInfo) => {
359
- const vaultAccount = this.program.coder.accounts.decode(this.program.idl.accounts[1].name, accountInfo.account.data);
714
+ const vaultAccount = this.vaultV1Program.coder.accounts.decode(this.vaultV1Program.idl.accounts[1].name, accountInfo.account.data);
360
715
  return {
361
716
  vault: accountInfo.pubkey,
362
717
  owner: vaultAccount.owner,
@@ -368,13 +723,13 @@ class ZebecVaultService {
368
723
  }
369
724
  async getProposalsInfoOfVault(vault) {
370
725
  const _vault = (0, anchor_1.translateAddress)(vault);
371
- const accountInfos = await this.connection.getProgramAccounts(this.programId, {
726
+ const accountInfos = await this.connection.getProgramAccounts(this.vaultV1ProgramId, {
372
727
  commitment: this.connection.commitment,
373
728
  filters: [
374
729
  {
375
730
  memcmp: {
376
731
  offset: 0, // offset for discriminator in Proposal
377
- bytes: anchor_1.utils.bytes.bs58.encode(this.program.idl.accounts[0].discriminator),
732
+ bytes: anchor_1.utils.bytes.bs58.encode(this.vaultV1Program.idl.accounts[0].discriminator),
378
733
  encoding: "base58",
379
734
  },
380
735
  },
@@ -388,7 +743,7 @@ class ZebecVaultService {
388
743
  ],
389
744
  });
390
745
  const proposals = accountInfos.map((accountInfo) => {
391
- const proposalAccount = this.program.coder.accounts.decode(this.program.idl.accounts[0].name, accountInfo.account.data);
746
+ const proposalAccount = this.vaultV1Program.coder.accounts.decode(this.vaultV1Program.idl.accounts[0].name, accountInfo.account.data);
392
747
  return {
393
748
  proposal: accountInfo.pubkey,
394
749
  vault: proposalAccount.vault,
@@ -402,8 +757,14 @@ class ZebecVaultService {
402
757
  });
403
758
  return proposals;
404
759
  }
405
- get programId() {
406
- return this.program.programId;
760
+ get vaultV1ProgramId() {
761
+ return this.vaultV1Program.programId;
762
+ }
763
+ get cardV2ProgramId() {
764
+ return this.cardV2Program.programId;
765
+ }
766
+ get streamProgramId() {
767
+ return this.streamProgram.programId;
407
768
  }
408
769
  get connection() {
409
770
  return this.provider.connection;
package/dist/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { PublicKey } from "@solana/web3.js";
2
- export type Numeric = number | string | bigint;
2
+ export type Numeric = number | string;
3
3
  export type ProposalAction = {
4
4
  programId: PublicKey;
5
5
  accountSpecs: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zebec-network/zebec-vault-sdk",
3
- "version": "2.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "An SDK for zebec vault solana program",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -26,24 +26,25 @@
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/mocha": "^10.0.10",
29
- "@types/node": "^24.0.1",
30
- "@zebec-network/core-utils": "^1.0.4",
31
- "@zebec-network/zebec-card-v2-sdk": "^1.1.0",
32
- "@zebec-network/zebec-stake-sdk": "^1.0.10",
33
- "dotenv": "^16.5.0",
34
- "mocha": "^11.6.0",
35
- "prettier": "^3.5.3",
29
+ "@types/node": "^24.3.1",
30
+ "@zebec-network/zebec-card-v2-sdk": "^2.1.2",
31
+ "@zebec-network/zebec-stake-sdk": "^1.1.3",
32
+ "@zebec-network/zebec-stream-sdk": "^1.7.0",
33
+ "dotenv": "^17.2.2",
34
+ "mocha": "^11.7.2",
35
+ "prettier": "^3.6.2",
36
36
  "rimraf": "^6.0.1",
37
37
  "ts-mocha": "^11.1.0",
38
38
  "ts-node": "^10.9.2",
39
- "typescript": "^5.8.3"
39
+ "typescript": "^5.9.2"
40
40
  },
41
41
  "dependencies": {
42
42
  "@coral-xyz/anchor": "^0.31.1",
43
43
  "@solana/web3.js": "^1.98.2",
44
44
  "@types/bn.js": "^5.2.0",
45
- "@zebec-network/solana-common": "^1.5.1",
46
- "bignumber.js": "^9.3.0",
45
+ "@zebec-network/core-utils": "^1.1.1",
46
+ "@zebec-network/solana-common": "^2.1.1",
47
+ "bignumber.js": "^9.3.1",
47
48
  "buffer": "^6.0.3"
48
49
  }
49
50
  }