@zebec-network/zebec-vault-sdk 1.1.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 +1 -1
- 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 +1540 -142
- package/dist/artifacts/zebec_vault.json +1276 -691
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +3 -1
- package/dist/pda.d.ts +7 -0
- package/dist/pda.js +45 -3
- package/dist/service.d.ts +134 -22
- package/dist/service.js +354 -89
- package/dist/types.d.ts +1 -1
- package/package.json +7 -4
package/dist/service.js
CHANGED
|
@@ -5,101 +5,104 @@ 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
|
-
async getCreateVaultInstruction(payer,
|
|
28
|
-
return this.
|
|
36
|
+
async getCreateVaultInstruction(payer, owner, signerBump) {
|
|
37
|
+
return this.vaultV1Program.methods
|
|
29
38
|
.createVault({
|
|
30
39
|
owner,
|
|
31
40
|
signerBump,
|
|
32
41
|
})
|
|
33
42
|
.accounts({
|
|
34
43
|
payer,
|
|
35
|
-
vault,
|
|
36
44
|
})
|
|
37
45
|
.instruction();
|
|
38
46
|
}
|
|
39
|
-
async getDepositSolInstruction(depositor,
|
|
40
|
-
return this.
|
|
47
|
+
async getDepositSolInstruction(depositor, amount) {
|
|
48
|
+
return this.vaultV1Program.methods
|
|
41
49
|
.depositSol({
|
|
42
50
|
amount,
|
|
43
51
|
})
|
|
44
52
|
.accounts({
|
|
45
|
-
vault,
|
|
46
53
|
depositor,
|
|
47
54
|
})
|
|
48
55
|
.instruction();
|
|
49
56
|
}
|
|
50
|
-
async getWithdrawSolInstruction(withdrawer,
|
|
51
|
-
return this.
|
|
57
|
+
async getWithdrawSolInstruction(withdrawer, amount) {
|
|
58
|
+
return this.vaultV1Program.methods
|
|
52
59
|
.withdrawSol({
|
|
53
60
|
amount,
|
|
54
61
|
})
|
|
55
62
|
.accounts({
|
|
56
|
-
vault,
|
|
57
63
|
withdrawer,
|
|
58
64
|
})
|
|
59
65
|
.instruction();
|
|
60
66
|
}
|
|
61
|
-
async getDepositTokenInstruction(depositor,
|
|
62
|
-
return this.
|
|
67
|
+
async getDepositTokenInstruction(depositor, tokenMint, amount, decimals) {
|
|
68
|
+
return this.vaultV1Program.methods
|
|
63
69
|
.depositToken({
|
|
64
70
|
amount,
|
|
65
71
|
decimals,
|
|
66
72
|
})
|
|
67
73
|
.accounts({
|
|
68
|
-
vault,
|
|
69
74
|
depositor,
|
|
70
75
|
tokenMint,
|
|
71
76
|
})
|
|
72
77
|
.instruction();
|
|
73
78
|
}
|
|
74
|
-
async getWithdrawTokenInstruction(withdrawer,
|
|
75
|
-
return this.
|
|
79
|
+
async getWithdrawTokenInstruction(withdrawer, tokenMint, amount, decimals) {
|
|
80
|
+
return this.vaultV1Program.methods
|
|
76
81
|
.withdrawToken({
|
|
77
82
|
amount,
|
|
78
83
|
decimals,
|
|
79
84
|
})
|
|
80
85
|
.accounts({
|
|
81
|
-
vault,
|
|
82
86
|
withdrawer,
|
|
83
87
|
tokenMint,
|
|
84
88
|
})
|
|
85
89
|
.instruction();
|
|
86
90
|
}
|
|
87
|
-
async getCreateProposalInstruction(proposer,
|
|
88
|
-
return this.
|
|
91
|
+
async getCreateProposalInstruction(proposer, proposal, name, actions, proposalAccountSize) {
|
|
92
|
+
return this.vaultV1Program.methods
|
|
89
93
|
.createProposal({
|
|
90
94
|
actions,
|
|
91
95
|
name,
|
|
92
96
|
proposalAccountSize,
|
|
93
97
|
})
|
|
94
98
|
.accounts({
|
|
95
|
-
vault,
|
|
96
99
|
proposal,
|
|
97
100
|
proposer,
|
|
98
101
|
})
|
|
99
102
|
.instruction();
|
|
100
103
|
}
|
|
101
104
|
async getAppendActionInstruction(proposer, proposal, actions, newProposalAccountSize) {
|
|
102
|
-
return this.
|
|
105
|
+
return this.vaultV1Program.methods
|
|
103
106
|
.appendActions({
|
|
104
107
|
actions,
|
|
105
108
|
proposalAccountSize: newProposalAccountSize,
|
|
@@ -111,7 +114,7 @@ class ZebecVaultService {
|
|
|
111
114
|
.instruction();
|
|
112
115
|
}
|
|
113
116
|
async getDeleteProposalInstruction(proposal) {
|
|
114
|
-
return this.
|
|
117
|
+
return this.vaultV1Program.methods
|
|
115
118
|
.deleteProposal()
|
|
116
119
|
.accounts({
|
|
117
120
|
proposal,
|
|
@@ -119,7 +122,7 @@ class ZebecVaultService {
|
|
|
119
122
|
.instruction();
|
|
120
123
|
}
|
|
121
124
|
async getExecuteProposalInstruction(caller, proposal, remainingAccounts) {
|
|
122
|
-
return this.
|
|
125
|
+
return this.vaultV1Program.methods
|
|
123
126
|
.executeProposal()
|
|
124
127
|
.accounts({
|
|
125
128
|
proposal,
|
|
@@ -128,36 +131,117 @@ class ZebecVaultService {
|
|
|
128
131
|
.remainingAccounts(remainingAccounts)
|
|
129
132
|
.instruction();
|
|
130
133
|
}
|
|
131
|
-
async getExecuteProposalDirectInstruction(
|
|
132
|
-
return this.
|
|
134
|
+
async getExecuteProposalDirectInstruction(proposer, actions, remainingAccounts) {
|
|
135
|
+
return this.vaultV1Program.methods
|
|
133
136
|
.executeProposalDirect({
|
|
134
137
|
actions,
|
|
135
138
|
})
|
|
136
139
|
.accounts({
|
|
137
|
-
vault,
|
|
138
140
|
proposer,
|
|
139
141
|
})
|
|
140
142
|
.remainingAccounts(remainingAccounts)
|
|
141
143
|
.instruction();
|
|
142
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
|
+
}
|
|
143
228
|
async createVault(params) {
|
|
144
229
|
const payer = params.payer ? (0, anchor_1.translateAddress)(params.payer) : this.provider.publicKey;
|
|
145
230
|
if (!payer) {
|
|
146
231
|
throw new Error("Either provide a payer or use AnchorProvider for provider in the service");
|
|
147
232
|
}
|
|
148
|
-
const
|
|
149
|
-
const [, signerBump] = (0, pda_1.deriveVaultSigner)(
|
|
150
|
-
const ix = await this.getCreateVaultInstruction(payer,
|
|
151
|
-
return this._createTransactionPayload(payer, [ix]
|
|
233
|
+
const [vault] = (0, pda_1.deriveUserVault)(payer, this.vaultV1ProgramId);
|
|
234
|
+
const [, signerBump] = (0, pda_1.deriveVaultSigner)(vault, this.vaultV1ProgramId);
|
|
235
|
+
const ix = await this.getCreateVaultInstruction(payer, payer, signerBump);
|
|
236
|
+
return this._createTransactionPayload(payer, [ix]);
|
|
152
237
|
}
|
|
153
238
|
async depositSol(params) {
|
|
154
239
|
const depositor = params.depositor ? (0, anchor_1.translateAddress)(params.depositor) : this.provider.publicKey;
|
|
155
240
|
if (!depositor) {
|
|
156
241
|
throw new Error("Either provide a depositor or use AnchorProvider for provider in the service");
|
|
157
242
|
}
|
|
158
|
-
const vault = (0, anchor_1.translateAddress)(params.vault);
|
|
159
243
|
const amount = new anchor_1.BN((0, solana_common_1.parseSol)(params.amount).toString());
|
|
160
|
-
const ix = await this.getDepositSolInstruction(depositor,
|
|
244
|
+
const ix = await this.getDepositSolInstruction(depositor, amount);
|
|
161
245
|
return this._createTransactionPayload(depositor, [ix]);
|
|
162
246
|
}
|
|
163
247
|
async withdrawSol(params) {
|
|
@@ -165,9 +249,8 @@ class ZebecVaultService {
|
|
|
165
249
|
if (!withdrawer) {
|
|
166
250
|
throw new Error("Either provide a withdrawer or use AnchorProvider for provider in the service");
|
|
167
251
|
}
|
|
168
|
-
const vault = (0, anchor_1.translateAddress)(params.vault);
|
|
169
252
|
const amount = new anchor_1.BN((0, solana_common_1.parseSol)(params.amount).toString());
|
|
170
|
-
const ix = await this.getWithdrawSolInstruction(withdrawer,
|
|
253
|
+
const ix = await this.getWithdrawSolInstruction(withdrawer, amount);
|
|
171
254
|
return this._createTransactionPayload(withdrawer, [ix]);
|
|
172
255
|
}
|
|
173
256
|
async depositToken(params) {
|
|
@@ -175,11 +258,10 @@ class ZebecVaultService {
|
|
|
175
258
|
if (!depositor) {
|
|
176
259
|
throw new Error("Either provide a depositor or use AnchorProvider for provider in the service");
|
|
177
260
|
}
|
|
178
|
-
const vault = (0, anchor_1.translateAddress)(params.vault);
|
|
179
261
|
const tokenMint = (0, anchor_1.translateAddress)(params.tokenMint);
|
|
180
262
|
const decimals = await (0, solana_common_1.getMintDecimals)(this.provider.connection, tokenMint);
|
|
181
263
|
const amount = new anchor_1.BN((0, solana_common_1.parseToken)(params.amount, decimals).toString());
|
|
182
|
-
const ix = await this.getDepositTokenInstruction(depositor,
|
|
264
|
+
const ix = await this.getDepositTokenInstruction(depositor, tokenMint, amount, decimals);
|
|
183
265
|
return this._createTransactionPayload(depositor, [ix]);
|
|
184
266
|
}
|
|
185
267
|
async withdrawToken(params) {
|
|
@@ -187,11 +269,10 @@ class ZebecVaultService {
|
|
|
187
269
|
if (!withdrawer) {
|
|
188
270
|
throw new Error("Either provide a withdrawer or use AnchorProvider for provider in the service");
|
|
189
271
|
}
|
|
190
|
-
const vault = (0, anchor_1.translateAddress)(params.vault);
|
|
191
272
|
const tokenMint = (0, anchor_1.translateAddress)(params.tokenMint);
|
|
192
273
|
const decimals = await (0, solana_common_1.getMintDecimals)(this.provider.connection, tokenMint);
|
|
193
274
|
const amount = new anchor_1.BN((0, solana_common_1.parseToken)(params.amount, decimals).toString());
|
|
194
|
-
const ix = await this.getWithdrawTokenInstruction(withdrawer,
|
|
275
|
+
const ix = await this.getWithdrawTokenInstruction(withdrawer, tokenMint, amount, decimals);
|
|
195
276
|
return this._createTransactionPayload(withdrawer, [ix]);
|
|
196
277
|
}
|
|
197
278
|
async createProposal(params) {
|
|
@@ -199,7 +280,6 @@ class ZebecVaultService {
|
|
|
199
280
|
if (!proposer) {
|
|
200
281
|
throw new Error("Either provide a proposer or use AnchorProvider for provider in the service");
|
|
201
282
|
}
|
|
202
|
-
const vault = (0, anchor_1.translateAddress)(params.vault);
|
|
203
283
|
const proposalKeypair = params.proposalKeypair ?? web3_js_1.Keypair.generate();
|
|
204
284
|
const actions = params.actions.map((ix) => ({
|
|
205
285
|
accountSpecs: ix.keys,
|
|
@@ -210,7 +290,7 @@ class ZebecVaultService {
|
|
|
210
290
|
if (proposalAccountSize > 10_000) {
|
|
211
291
|
throw new Error("Proposal size exceeds maximum allowed size of 10,000 bytes");
|
|
212
292
|
}
|
|
213
|
-
const ix = await this.getCreateProposalInstruction(proposer,
|
|
293
|
+
const ix = await this.getCreateProposalInstruction(proposer, proposalKeypair.publicKey, params.name, actions, proposalAccountSize);
|
|
214
294
|
return this._createTransactionPayload(proposer, [ix], [proposalKeypair]);
|
|
215
295
|
}
|
|
216
296
|
async appendActions(params) {
|
|
@@ -219,7 +299,7 @@ class ZebecVaultService {
|
|
|
219
299
|
throw new Error("Either provide a proposer or use AnchorProvider for provider in the service");
|
|
220
300
|
}
|
|
221
301
|
const proposal = (0, anchor_1.translateAddress)(params.proposal);
|
|
222
|
-
const proposalAccount = await this.
|
|
302
|
+
const proposalAccount = await this.vaultV1Program.account.proposal.fetchNullable(proposal, this.connection.commitment);
|
|
223
303
|
if (!proposalAccount) {
|
|
224
304
|
throw new Error("Proposal account not found");
|
|
225
305
|
}
|
|
@@ -252,12 +332,12 @@ class ZebecVaultService {
|
|
|
252
332
|
throw new Error("Either provide a caller or use AnchorProvider for provider in the service");
|
|
253
333
|
}
|
|
254
334
|
const proposal = (0, anchor_1.translateAddress)(params.proposal);
|
|
255
|
-
const proposalAccount = await this.
|
|
335
|
+
const proposalAccount = await this.vaultV1Program.account.proposal.fetchNullable(proposal, this.connection.commitment);
|
|
256
336
|
if (!proposalAccount) {
|
|
257
337
|
throw new Error("Proposal account not found");
|
|
258
338
|
}
|
|
259
339
|
const vault = proposalAccount.vault;
|
|
260
|
-
const [vaultSigner] = (0, pda_1.deriveVaultSigner)(vault, this.
|
|
340
|
+
const [vaultSigner] = (0, pda_1.deriveVaultSigner)(vault, this.vaultV1ProgramId);
|
|
261
341
|
const remainingAccounts = proposalAccount.actions.reduce((acc, current) => {
|
|
262
342
|
const accounts = current.accountSpecs.map((spec) => ({
|
|
263
343
|
pubkey: spec.pubkey,
|
|
@@ -291,8 +371,8 @@ class ZebecVaultService {
|
|
|
291
371
|
if (!proposer) {
|
|
292
372
|
throw new Error("Either provide a caller or use AnchorProvider for provider in the service");
|
|
293
373
|
}
|
|
294
|
-
const vault = (0,
|
|
295
|
-
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);
|
|
296
376
|
const actions = params.actions.map((ix) => ({
|
|
297
377
|
accountSpecs: ix.keys,
|
|
298
378
|
data: ix.data,
|
|
@@ -311,7 +391,7 @@ class ZebecVaultService {
|
|
|
311
391
|
});
|
|
312
392
|
return acc;
|
|
313
393
|
}, []);
|
|
314
|
-
const ix = await this.getExecuteProposalDirectInstruction(
|
|
394
|
+
const ix = await this.getExecuteProposalDirectInstruction(proposer, actions, remainingAccounts);
|
|
315
395
|
const addressLookupTableAccounts = [];
|
|
316
396
|
if (params.addressLookupTables) {
|
|
317
397
|
const promises = params.addressLookupTables.map(async (lookupTable) => {
|
|
@@ -325,9 +405,206 @@ class ZebecVaultService {
|
|
|
325
405
|
}
|
|
326
406
|
return this._createTransactionPayload(proposer, [ix], params.partialSigners, addressLookupTableAccounts);
|
|
327
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
|
+
}
|
|
328
605
|
async _createTransactionPayload(payerKey, instructions, signers, addressLookupTableAccounts) {
|
|
329
606
|
const errorMap = new Map();
|
|
330
|
-
this.
|
|
607
|
+
this.vaultV1Program.idl.errors.forEach((error) => errorMap.set(error.code, error.msg));
|
|
331
608
|
let signTransaction = undefined;
|
|
332
609
|
const provider = this.provider;
|
|
333
610
|
if (provider instanceof anchor_1.AnchorProvider) {
|
|
@@ -337,56 +614,38 @@ class ZebecVaultService {
|
|
|
337
614
|
}
|
|
338
615
|
return new solana_common_1.TransactionPayload(this.provider.connection, errorMap, instructions, payerKey, signers, addressLookupTableAccounts, signTransaction);
|
|
339
616
|
}
|
|
340
|
-
async
|
|
617
|
+
async getVaultInfoOfUser(user) {
|
|
341
618
|
user = user ? (0, anchor_1.translateAddress)(user) : this.provider.publicKey;
|
|
342
619
|
if (!user) {
|
|
343
620
|
throw new Error("Either provide a user or use AnchorProvider for provider in the service");
|
|
344
621
|
}
|
|
345
|
-
const
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
memcmp: {
|
|
357
|
-
offset: 8, // offset for owner field in Vault
|
|
358
|
-
bytes: user.toBase58(),
|
|
359
|
-
encoding: "base58",
|
|
360
|
-
},
|
|
361
|
-
},
|
|
362
|
-
],
|
|
363
|
-
});
|
|
364
|
-
const vaults = accountInfos.map((accountInfo) => {
|
|
365
|
-
const vaultAccount = this.program.coder.accounts.decode(this.program.idl.accounts[1].name, accountInfo.account.data);
|
|
366
|
-
return {
|
|
367
|
-
vault: accountInfo.pubkey,
|
|
368
|
-
owner: vaultAccount.owner,
|
|
369
|
-
createdDate: vaultAccount.createdDate.toNumber(),
|
|
370
|
-
signerBump: vaultAccount.signerBump,
|
|
371
|
-
};
|
|
372
|
-
});
|
|
373
|
-
return vaults;
|
|
622
|
+
const [vault] = (0, pda_1.deriveUserVault)(user, this.vaultV1ProgramId);
|
|
623
|
+
const vaultAccount = await this.vaultV1Program.account.vault.fetchNullable(vault, this.connection.commitment);
|
|
624
|
+
if (!vaultAccount) {
|
|
625
|
+
return null;
|
|
626
|
+
}
|
|
627
|
+
return {
|
|
628
|
+
createdDate: vaultAccount.createdDate.toNumber(),
|
|
629
|
+
owner: vaultAccount.owner,
|
|
630
|
+
signerBump: vaultAccount.signerBump,
|
|
631
|
+
vault,
|
|
632
|
+
};
|
|
374
633
|
}
|
|
375
634
|
async getAllVaultsInfo() {
|
|
376
|
-
const accountInfos = await this.connection.getProgramAccounts(this.
|
|
635
|
+
const accountInfos = await this.connection.getProgramAccounts(this.vaultV1ProgramId, {
|
|
377
636
|
commitment: this.connection.commitment,
|
|
378
637
|
filters: [
|
|
379
638
|
{
|
|
380
639
|
memcmp: {
|
|
381
640
|
offset: 0, // offset for discriminator in Vault
|
|
382
|
-
bytes: anchor_1.utils.bytes.bs58.encode(this.
|
|
641
|
+
bytes: anchor_1.utils.bytes.bs58.encode(this.vaultV1Program.idl.accounts[1].discriminator),
|
|
383
642
|
encoding: "base58",
|
|
384
643
|
},
|
|
385
644
|
},
|
|
386
645
|
],
|
|
387
646
|
});
|
|
388
647
|
const vaults = accountInfos.map((accountInfo) => {
|
|
389
|
-
const vaultAccount = this.
|
|
648
|
+
const vaultAccount = this.vaultV1Program.coder.accounts.decode(this.vaultV1Program.idl.accounts[1].name, accountInfo.account.data);
|
|
390
649
|
return {
|
|
391
650
|
vault: accountInfo.pubkey,
|
|
392
651
|
owner: vaultAccount.owner,
|
|
@@ -398,13 +657,13 @@ class ZebecVaultService {
|
|
|
398
657
|
}
|
|
399
658
|
async getProposalsInfoOfVault(vault) {
|
|
400
659
|
const _vault = (0, anchor_1.translateAddress)(vault);
|
|
401
|
-
const accountInfos = await this.connection.getProgramAccounts(this.
|
|
660
|
+
const accountInfos = await this.connection.getProgramAccounts(this.vaultV1ProgramId, {
|
|
402
661
|
commitment: this.connection.commitment,
|
|
403
662
|
filters: [
|
|
404
663
|
{
|
|
405
664
|
memcmp: {
|
|
406
665
|
offset: 0, // offset for discriminator in Proposal
|
|
407
|
-
bytes: anchor_1.utils.bytes.bs58.encode(this.
|
|
666
|
+
bytes: anchor_1.utils.bytes.bs58.encode(this.vaultV1Program.idl.accounts[0].discriminator),
|
|
408
667
|
encoding: "base58",
|
|
409
668
|
},
|
|
410
669
|
},
|
|
@@ -418,7 +677,7 @@ class ZebecVaultService {
|
|
|
418
677
|
],
|
|
419
678
|
});
|
|
420
679
|
const proposals = accountInfos.map((accountInfo) => {
|
|
421
|
-
const proposalAccount = this.
|
|
680
|
+
const proposalAccount = this.vaultV1Program.coder.accounts.decode(this.vaultV1Program.idl.accounts[0].name, accountInfo.account.data);
|
|
422
681
|
return {
|
|
423
682
|
proposal: accountInfo.pubkey,
|
|
424
683
|
vault: proposalAccount.vault,
|
|
@@ -432,8 +691,14 @@ class ZebecVaultService {
|
|
|
432
691
|
});
|
|
433
692
|
return proposals;
|
|
434
693
|
}
|
|
435
|
-
get
|
|
436
|
-
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;
|
|
437
702
|
}
|
|
438
703
|
get connection() {
|
|
439
704
|
return this.provider.connection;
|