@zebec-network/zebec-vault-sdk 2.0.0 → 3.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/README.md +219 -219
- package/dist/artifacts/index.d.ts +7 -3
- package/dist/artifacts/index.js +9 -3
- package/dist/artifacts/zebec_instant_card.d.ts +1690 -0
- package/dist/artifacts/zebec_instant_card.js +2 -0
- package/dist/artifacts/zebec_instant_card.json +1444 -0
- package/dist/artifacts/zebec_stream.d.ts +1897 -0
- package/dist/artifacts/zebec_stream.js +2 -0
- package/dist/artifacts/zebec_stream.json +1591 -0
- package/dist/artifacts/zebec_vault.d.ts +1442 -169
- package/dist/artifacts/zebec_vault.json +1178 -891
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +3 -1
- package/dist/pda.d.ts +6 -0
- package/dist/pda.js +40 -3
- package/dist/service.d.ts +126 -7
- package/dist/service.js +329 -34
- package/dist/types.d.ts +1 -1
- package/package.json +7 -6
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
|
-
|
|
19
|
+
vaultV1Program;
|
|
20
|
+
cardV2Program;
|
|
21
|
+
streamProgram;
|
|
17
22
|
network;
|
|
18
|
-
constructor(provider,
|
|
23
|
+
constructor(provider, vaultV1Program, cardV2Program, streamProgram, network) {
|
|
19
24
|
this.provider = provider;
|
|
20
|
-
this.
|
|
25
|
+
this.vaultV1Program = vaultV1Program;
|
|
26
|
+
this.cardV2Program = cardV2Program;
|
|
27
|
+
this.streamProgram = streamProgram;
|
|
21
28
|
this.network = network;
|
|
22
29
|
}
|
|
23
|
-
static
|
|
24
|
-
|
|
25
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
142
|
-
const [, signerBump] = (0, pda_1.deriveVaultSigner)(vault, this.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
283
|
-
const [vaultSigner] = (0, pda_1.deriveVaultSigner)(vault, this.
|
|
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,206 @@ 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 streamNameBuffer = Buffer.alloc(STREAM_NAME_BUFFER_SIZE);
|
|
584
|
+
streamNameBuffer.fill(anchor_1.utils.bytes.utf8.encode(params.streamName), 0);
|
|
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: streamNameBuffer,
|
|
600
|
+
transferableByRecipient: params.transferableByRecipient,
|
|
601
|
+
transferableBySender: params.transferableBySender,
|
|
602
|
+
});
|
|
603
|
+
return this._createTransactionPayload(vaultOwner, [ix], [streamMetatdataKeypair]);
|
|
604
|
+
}
|
|
316
605
|
async _createTransactionPayload(payerKey, instructions, signers, addressLookupTableAccounts) {
|
|
317
606
|
const errorMap = new Map();
|
|
318
|
-
this.
|
|
607
|
+
this.vaultV1Program.idl.errors.forEach((error) => errorMap.set(error.code, error.msg));
|
|
319
608
|
let signTransaction = undefined;
|
|
320
609
|
const provider = this.provider;
|
|
321
610
|
if (provider instanceof anchor_1.AnchorProvider) {
|
|
@@ -330,8 +619,8 @@ class ZebecVaultService {
|
|
|
330
619
|
if (!user) {
|
|
331
620
|
throw new Error("Either provide a user or use AnchorProvider for provider in the service");
|
|
332
621
|
}
|
|
333
|
-
const [vault] = (0, pda_1.deriveUserVault)(user, this.
|
|
334
|
-
const vaultAccount = await this.
|
|
622
|
+
const [vault] = (0, pda_1.deriveUserVault)(user, this.vaultV1ProgramId);
|
|
623
|
+
const vaultAccount = await this.vaultV1Program.account.vault.fetchNullable(vault, this.connection.commitment);
|
|
335
624
|
if (!vaultAccount) {
|
|
336
625
|
return null;
|
|
337
626
|
}
|
|
@@ -343,20 +632,20 @@ class ZebecVaultService {
|
|
|
343
632
|
};
|
|
344
633
|
}
|
|
345
634
|
async getAllVaultsInfo() {
|
|
346
|
-
const accountInfos = await this.connection.getProgramAccounts(this.
|
|
635
|
+
const accountInfos = await this.connection.getProgramAccounts(this.vaultV1ProgramId, {
|
|
347
636
|
commitment: this.connection.commitment,
|
|
348
637
|
filters: [
|
|
349
638
|
{
|
|
350
639
|
memcmp: {
|
|
351
640
|
offset: 0, // offset for discriminator in Vault
|
|
352
|
-
bytes: anchor_1.utils.bytes.bs58.encode(this.
|
|
641
|
+
bytes: anchor_1.utils.bytes.bs58.encode(this.vaultV1Program.idl.accounts[1].discriminator),
|
|
353
642
|
encoding: "base58",
|
|
354
643
|
},
|
|
355
644
|
},
|
|
356
645
|
],
|
|
357
646
|
});
|
|
358
647
|
const vaults = accountInfos.map((accountInfo) => {
|
|
359
|
-
const vaultAccount = this.
|
|
648
|
+
const vaultAccount = this.vaultV1Program.coder.accounts.decode(this.vaultV1Program.idl.accounts[1].name, accountInfo.account.data);
|
|
360
649
|
return {
|
|
361
650
|
vault: accountInfo.pubkey,
|
|
362
651
|
owner: vaultAccount.owner,
|
|
@@ -368,13 +657,13 @@ class ZebecVaultService {
|
|
|
368
657
|
}
|
|
369
658
|
async getProposalsInfoOfVault(vault) {
|
|
370
659
|
const _vault = (0, anchor_1.translateAddress)(vault);
|
|
371
|
-
const accountInfos = await this.connection.getProgramAccounts(this.
|
|
660
|
+
const accountInfos = await this.connection.getProgramAccounts(this.vaultV1ProgramId, {
|
|
372
661
|
commitment: this.connection.commitment,
|
|
373
662
|
filters: [
|
|
374
663
|
{
|
|
375
664
|
memcmp: {
|
|
376
665
|
offset: 0, // offset for discriminator in Proposal
|
|
377
|
-
bytes: anchor_1.utils.bytes.bs58.encode(this.
|
|
666
|
+
bytes: anchor_1.utils.bytes.bs58.encode(this.vaultV1Program.idl.accounts[0].discriminator),
|
|
378
667
|
encoding: "base58",
|
|
379
668
|
},
|
|
380
669
|
},
|
|
@@ -388,7 +677,7 @@ class ZebecVaultService {
|
|
|
388
677
|
],
|
|
389
678
|
});
|
|
390
679
|
const proposals = accountInfos.map((accountInfo) => {
|
|
391
|
-
const proposalAccount = this.
|
|
680
|
+
const proposalAccount = this.vaultV1Program.coder.accounts.decode(this.vaultV1Program.idl.accounts[0].name, accountInfo.account.data);
|
|
392
681
|
return {
|
|
393
682
|
proposal: accountInfo.pubkey,
|
|
394
683
|
vault: proposalAccount.vault,
|
|
@@ -402,8 +691,14 @@ class ZebecVaultService {
|
|
|
402
691
|
});
|
|
403
692
|
return proposals;
|
|
404
693
|
}
|
|
405
|
-
get
|
|
406
|
-
return this.
|
|
694
|
+
get vaultV1ProgramId() {
|
|
695
|
+
return this.vaultV1Program.programId;
|
|
696
|
+
}
|
|
697
|
+
get cardV2ProgramId() {
|
|
698
|
+
return this.cardV2Program.programId;
|
|
699
|
+
}
|
|
700
|
+
get streamProgramId() {
|
|
701
|
+
return this.streamProgram.programId;
|
|
407
702
|
}
|
|
408
703
|
get connection() {
|
|
409
704
|
return this.provider.connection;
|
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zebec-network/zebec-vault-sdk",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "An SDK for zebec vault solana program",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/mocha": "^10.0.10",
|
|
29
29
|
"@types/node": "^24.0.1",
|
|
30
|
-
"@zebec-network/
|
|
31
|
-
"@zebec-network/zebec-
|
|
32
|
-
"@zebec-network/zebec-
|
|
33
|
-
"dotenv": "^
|
|
30
|
+
"@zebec-network/zebec-card-v2-sdk": "^2.0.1",
|
|
31
|
+
"@zebec-network/zebec-stake-sdk": "^1.1.1",
|
|
32
|
+
"@zebec-network/zebec-stream-sdk": "^1.4.0",
|
|
33
|
+
"dotenv": "^17.2.0",
|
|
34
34
|
"mocha": "^11.6.0",
|
|
35
35
|
"prettier": "^3.5.3",
|
|
36
36
|
"rimraf": "^6.0.1",
|
|
@@ -42,7 +42,8 @@
|
|
|
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/
|
|
45
|
+
"@zebec-network/core-utils": "^1.1.0",
|
|
46
|
+
"@zebec-network/solana-common": "^1.7.0",
|
|
46
47
|
"bignumber.js": "^9.3.0",
|
|
47
48
|
"buffer": "^6.0.3"
|
|
48
49
|
}
|