@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/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 +1902 -0
- package/dist/artifacts/zebec_stream.js +2 -0
- package/dist/artifacts/zebec_stream.json +1596 -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 +152 -8
- package/dist/service.js +396 -35
- package/dist/types.d.ts +1 -1
- package/package.json +12 -11
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,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.
|
|
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.
|
|
334
|
-
const vaultAccount = await this.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
406
|
-
return this.
|
|
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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zebec-network/zebec-vault-sdk",
|
|
3
|
-
"version": "
|
|
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.
|
|
30
|
-
"@zebec-network/
|
|
31
|
-
"@zebec-network/zebec-
|
|
32
|
-
"@zebec-network/zebec-
|
|
33
|
-
"dotenv": "^
|
|
34
|
-
"mocha": "^11.
|
|
35
|
-
"prettier": "^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.
|
|
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/
|
|
46
|
-
"
|
|
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
|
}
|