@zebec-network/solana-payroll-sdk 2.5.0 → 2.6.0-dev.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constants.d.ts +7 -0
- package/dist/constants.js +10 -0
- package/dist/instructions.d.ts +46 -1
- package/dist/instructions.js +58 -0
- package/dist/pda.d.ts +4 -0
- package/dist/pda.js +33 -2
- package/dist/services.d.ts +12 -3
- package/dist/services.js +339 -55
- package/dist/types.d.ts +84 -0
- package/dist/utils.d.ts +12 -1
- package/dist/utils.js +40 -1
- package/package.json +7 -5
package/dist/constants.d.ts
CHANGED
|
@@ -2,3 +2,10 @@ import type { RpcNetwork } from "./types.js";
|
|
|
2
2
|
export declare const PAYROLL_NAME_BUFFER_SIZE = 128;
|
|
3
3
|
export declare const PAYROLL_PROGRAM_ID: Record<RpcNetwork, string>;
|
|
4
4
|
export declare const USX_DECIMALS = 6;
|
|
5
|
+
export declare const DEFAULT_FEE_RATE_IN_BPS = 500;
|
|
6
|
+
export declare const BPS_DENOMINATOR = 10000;
|
|
7
|
+
export declare const JUPITER_SWAP_API = "https://lite-api.jup.ag/swap/v1/swap";
|
|
8
|
+
export declare const CARD_LOOKUP_TABLE_ADDRESS: Record<"mainnet-beta" | "devnet", string>;
|
|
9
|
+
export declare const JUPITER_AGGREGATOR_PROGRAM_ID = "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4";
|
|
10
|
+
export declare const PAYROLL_TOKEN_PRICE_MESSAGE_SIZE = 48;
|
|
11
|
+
export declare const ED25519_SIGNATURE_SIZE = 64;
|
package/dist/constants.js
CHANGED
|
@@ -4,3 +4,13 @@ export const PAYROLL_PROGRAM_ID = {
|
|
|
4
4
|
devnet: "zPAY457TttFCcaCoA3imYyEHc2sPvLMTQgVxjAfodSM",
|
|
5
5
|
};
|
|
6
6
|
export const USX_DECIMALS = 6;
|
|
7
|
+
export const DEFAULT_FEE_RATE_IN_BPS = 500;
|
|
8
|
+
export const BPS_DENOMINATOR = 10000;
|
|
9
|
+
export const JUPITER_SWAP_API = "https://lite-api.jup.ag/swap/v1/swap";
|
|
10
|
+
export const CARD_LOOKUP_TABLE_ADDRESS = {
|
|
11
|
+
"mainnet-beta": "9BSK7XgPgAZJK6BEdiFDV8WKGye31uffvGjhQ1Zxob7F",
|
|
12
|
+
devnet: "CgPARkLEbygMJ8C9Z1u6MP57gvdnUERCxdhmR9bTFUSJ",
|
|
13
|
+
};
|
|
14
|
+
export const JUPITER_AGGREGATOR_PROGRAM_ID = "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4";
|
|
15
|
+
export const PAYROLL_TOKEN_PRICE_MESSAGE_SIZE = 48;
|
|
16
|
+
export const ED25519_SIGNATURE_SIZE = 64;
|
package/dist/instructions.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { BN, Program } from "@coral-xyz/anchor";
|
|
2
|
-
import type
|
|
2
|
+
import { type AccountMeta, type PublicKey, type TransactionInstruction } from "@solana/web3.js";
|
|
3
3
|
import type { ZebecPayroll as ZebecPayrollIdl } from "@zebec-network/zebec_payroll";
|
|
4
4
|
export declare function createCreatePayrollInstruction(program: Program<ZebecPayrollIdl>, accounts: {
|
|
5
5
|
sender: PublicKey;
|
|
@@ -13,6 +13,8 @@ export declare function createCreatePayrollInstruction(program: Program<ZebecPay
|
|
|
13
13
|
payrollConfig: PublicKey;
|
|
14
14
|
withdrawAccount: PublicKey;
|
|
15
15
|
payrollToken: PublicKey;
|
|
16
|
+
feeVault: PublicKey;
|
|
17
|
+
feeVaultTokenAccount: PublicKey;
|
|
16
18
|
}, data: {
|
|
17
19
|
amount: BN;
|
|
18
20
|
startTime: BN;
|
|
@@ -33,6 +35,8 @@ export declare function createCreatePayrollInstruction(program: Program<ZebecPay
|
|
|
33
35
|
autoTopupDelegate: number;
|
|
34
36
|
senderId: number[];
|
|
35
37
|
receiverId: number[];
|
|
38
|
+
priceExpiry: BN;
|
|
39
|
+
tokenPrice: BN;
|
|
36
40
|
}): Promise<TransactionInstruction>;
|
|
37
41
|
export declare function createCancelPayrollInstruction(program: Program<ZebecPayrollIdl>, accounts: {
|
|
38
42
|
signer: PublicKey;
|
|
@@ -156,3 +160,44 @@ export declare function createDistributeRewardsInstruction(program: Program<Zebe
|
|
|
156
160
|
}[];
|
|
157
161
|
checkId: number[];
|
|
158
162
|
}, remainingAccounts: AccountMeta[]): Promise<TransactionInstruction>;
|
|
163
|
+
export declare function createCreateCardInstruction(payrollProgram: Program<ZebecPayrollIdl>, accounts: {
|
|
164
|
+
cardPurchasePda: PublicKey;
|
|
165
|
+
cardVault: PublicKey;
|
|
166
|
+
cardVaultAta: PublicKey;
|
|
167
|
+
enterpriseCardConfig: PublicKey;
|
|
168
|
+
enterpriseCardIndex: PublicKey;
|
|
169
|
+
feePayer: PublicKey;
|
|
170
|
+
revenueVault: PublicKey;
|
|
171
|
+
revenueVaultAta: PublicKey;
|
|
172
|
+
usdcMint: PublicKey;
|
|
173
|
+
user: PublicKey;
|
|
174
|
+
userAta: PublicKey;
|
|
175
|
+
userPurchaseRecordPda: PublicKey;
|
|
176
|
+
}, data: {
|
|
177
|
+
amount: BN;
|
|
178
|
+
currency: string;
|
|
179
|
+
emailHash: number[];
|
|
180
|
+
index: BN;
|
|
181
|
+
reloadCardId: string;
|
|
182
|
+
}): Promise<TransactionInstruction>;
|
|
183
|
+
export declare function createSwapAndCreateCardInstruction(payrollProgram: Program<ZebecPayrollIdl>, accounts: {
|
|
184
|
+
cardPurchasePda: PublicKey;
|
|
185
|
+
cardVault: PublicKey;
|
|
186
|
+
cardVaultAta: PublicKey;
|
|
187
|
+
enterpriseCardConfig: PublicKey;
|
|
188
|
+
enterpriseCardIndex: PublicKey;
|
|
189
|
+
feePayer: PublicKey;
|
|
190
|
+
revenueVault: PublicKey;
|
|
191
|
+
revenueVaultAta: PublicKey;
|
|
192
|
+
sourceToken: PublicKey;
|
|
193
|
+
usdcMint: PublicKey;
|
|
194
|
+
user: PublicKey;
|
|
195
|
+
userAta: PublicKey;
|
|
196
|
+
userPurchaseRecordPda: PublicKey;
|
|
197
|
+
}, data: {
|
|
198
|
+
currency: string;
|
|
199
|
+
emailHash: number[];
|
|
200
|
+
index: BN;
|
|
201
|
+
reloadCardId: string;
|
|
202
|
+
swapData: Buffer;
|
|
203
|
+
}, remainingAccounts: AccountMeta[]): Promise<TransactionInstruction>;
|
package/dist/instructions.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import { SYSVAR_INSTRUCTIONS_PUBKEY, } from "@solana/web3.js";
|
|
1
2
|
export async function createCreatePayrollInstruction(program, accounts, data) {
|
|
2
3
|
return program.methods
|
|
3
4
|
.createStream({
|
|
5
|
+
priceExpiry: data.priceExpiry,
|
|
6
|
+
tokenPrice: data.tokenPrice,
|
|
4
7
|
amount: data.amount,
|
|
5
8
|
startTime: data.startTime,
|
|
6
9
|
duration: data.duration,
|
|
@@ -33,6 +36,9 @@ export async function createCreatePayrollInstruction(program, accounts, data) {
|
|
|
33
36
|
payrollConfig: accounts.payrollConfig,
|
|
34
37
|
withdrawAccount: accounts.withdrawAccount,
|
|
35
38
|
streamToken: accounts.payrollToken,
|
|
39
|
+
feeVault: accounts.feeVault,
|
|
40
|
+
feeVaultTokenAccount: accounts.feeVaultTokenAccount,
|
|
41
|
+
instructionsSysvar: SYSVAR_INSTRUCTIONS_PUBKEY,
|
|
36
42
|
})
|
|
37
43
|
.instruction();
|
|
38
44
|
}
|
|
@@ -195,3 +201,55 @@ export async function createDistributeRewardsInstruction(program, accounts, data
|
|
|
195
201
|
.remainingAccounts(remainingAccounts)
|
|
196
202
|
.instruction();
|
|
197
203
|
}
|
|
204
|
+
export async function createCreateCardInstruction(payrollProgram, accounts, data) {
|
|
205
|
+
return payrollProgram.methods
|
|
206
|
+
.enterpriseCreateCard({
|
|
207
|
+
amount: data.amount,
|
|
208
|
+
currency: data.currency,
|
|
209
|
+
emailHash: data.emailHash,
|
|
210
|
+
index: data.index,
|
|
211
|
+
reloadCardId: data.reloadCardId,
|
|
212
|
+
})
|
|
213
|
+
.accountsPartial({
|
|
214
|
+
cardPurchasePda: accounts.cardPurchasePda,
|
|
215
|
+
cardVault: accounts.cardVault,
|
|
216
|
+
cardVaultAta: accounts.cardVaultAta,
|
|
217
|
+
enterpriseCardConfig: accounts.enterpriseCardConfig,
|
|
218
|
+
enterpriseCardIndex: accounts.enterpriseCardIndex,
|
|
219
|
+
feePayer: accounts.feePayer,
|
|
220
|
+
revenueVault: accounts.revenueVault,
|
|
221
|
+
revenueVaultAta: accounts.revenueVaultAta,
|
|
222
|
+
usdcMint: accounts.usdcMint,
|
|
223
|
+
user: accounts.user,
|
|
224
|
+
userAta: accounts.userAta,
|
|
225
|
+
userPurchaseRecordPda: accounts.userPurchaseRecordPda,
|
|
226
|
+
})
|
|
227
|
+
.instruction();
|
|
228
|
+
}
|
|
229
|
+
export async function createSwapAndCreateCardInstruction(payrollProgram, accounts, data, remainingAccounts) {
|
|
230
|
+
return payrollProgram.methods
|
|
231
|
+
.swapAndCreateCard({
|
|
232
|
+
currency: data.currency,
|
|
233
|
+
emailHash: data.emailHash,
|
|
234
|
+
index: data.index,
|
|
235
|
+
reloadCardId: data.reloadCardId,
|
|
236
|
+
swapData: data.swapData,
|
|
237
|
+
})
|
|
238
|
+
.accountsPartial({
|
|
239
|
+
cardPurchasePda: accounts.cardPurchasePda,
|
|
240
|
+
cardVault: accounts.cardVault,
|
|
241
|
+
cardVaultAta: accounts.cardVaultAta,
|
|
242
|
+
enterpriseCardConfig: accounts.enterpriseCardConfig,
|
|
243
|
+
enterpriseCardIndex: accounts.enterpriseCardIndex,
|
|
244
|
+
feePayer: accounts.feePayer,
|
|
245
|
+
revenueVault: accounts.revenueVault,
|
|
246
|
+
revenueVaultAta: accounts.revenueVaultAta,
|
|
247
|
+
sourceToken: accounts.sourceToken,
|
|
248
|
+
usdcMint: accounts.usdcMint,
|
|
249
|
+
user: accounts.user,
|
|
250
|
+
userAta: accounts.userAta,
|
|
251
|
+
userPurchaseRecordPda: accounts.userPurchaseRecordPda,
|
|
252
|
+
})
|
|
253
|
+
.remainingAccounts(remainingAccounts)
|
|
254
|
+
.instruction();
|
|
255
|
+
}
|
package/dist/pda.d.ts
CHANGED
|
@@ -6,3 +6,7 @@ export declare function deriveYieldConfigPda(configProgramId: Address): [PublicK
|
|
|
6
6
|
export declare function deriveCompanyDepositPda(companyId: Buffer, nonce: bigint, payrollProgramId: Address): [PublicKey, number];
|
|
7
7
|
export declare function deriveCompanyNoncePda(companyId: Buffer, payrollProgramId: Address): [PublicKey, number];
|
|
8
8
|
export declare function deriveCheckAccountPda(checkId: Buffer | Uint8Array, payrollProgramId: Address): [PublicKey, number];
|
|
9
|
+
export declare function deriveEnterpriseCardIndexPda(entCardConfigName: string, payrollProgramId: Address): [PublicKey, number];
|
|
10
|
+
export declare function deriveEnterpriseCardPurchasePda(userAddress: Address, entCardConfigName: string, cardIndex: bigint, payrollProgramId: Address): [PublicKey, number];
|
|
11
|
+
export declare function deriveEnterpriseUserPurchaseRecordPda(userAddress: Address, entCardConfigName: string, payrollProgramId: Address): [PublicKey, number];
|
|
12
|
+
export declare function deriveEnterpriseCardConfigPda(entCardConfigName: string, zebecConfigProgramId: Address): [PublicKey, number];
|
package/dist/pda.js
CHANGED
|
@@ -4,9 +4,13 @@ import BN from "bn.js";
|
|
|
4
4
|
const ZEBEC_CONFIG_PROGRAM_SEEDS = {
|
|
5
5
|
PAYROLL_CONFIG: utils.bytes.utf8.encode("payroll_config"),
|
|
6
6
|
YIELD_CONFIG: utils.bytes.utf8.encode("yield_config"),
|
|
7
|
+
ENTERPRISE_CARD_CONFIG: utils.bytes.utf8.encode("enterprise_card_config"),
|
|
7
8
|
};
|
|
8
9
|
const PAYROLL_PROGRAM_SEEDS = {
|
|
9
|
-
|
|
10
|
+
YIELD_COMPANY_DEPOSIT: utils.bytes.utf8.encode("Yield"),
|
|
11
|
+
ENT_USER_PURCHASE_RECORD: utils.bytes.utf8.encode("UserPurchaseRecord"),
|
|
12
|
+
ENT_USER_CARD_PURCHASE: utils.bytes.utf8.encode("CardPurchase"),
|
|
13
|
+
ENT_CARD_INDEX: utils.bytes.utf8.encode("EnterpriseCardIndex"),
|
|
10
14
|
};
|
|
11
15
|
export function derivePayrollConfigPda(configName, configProgramId) {
|
|
12
16
|
return PublicKey.findProgramAddressSync([
|
|
@@ -24,7 +28,7 @@ export function deriveCompanyDepositPda(companyId, nonce, payrollProgramId) {
|
|
|
24
28
|
return PublicKey.findProgramAddressSync([
|
|
25
29
|
companyId,
|
|
26
30
|
new BN(nonce).toArrayLike(Buffer, "le", 8),
|
|
27
|
-
PAYROLL_PROGRAM_SEEDS.
|
|
31
|
+
PAYROLL_PROGRAM_SEEDS.YIELD_COMPANY_DEPOSIT,
|
|
28
32
|
], translateAddress(payrollProgramId));
|
|
29
33
|
}
|
|
30
34
|
export function deriveCompanyNoncePda(companyId, payrollProgramId) {
|
|
@@ -33,3 +37,30 @@ export function deriveCompanyNoncePda(companyId, payrollProgramId) {
|
|
|
33
37
|
export function deriveCheckAccountPda(checkId, payrollProgramId) {
|
|
34
38
|
return PublicKey.findProgramAddressSync([checkId], translateAddress(payrollProgramId));
|
|
35
39
|
}
|
|
40
|
+
export function deriveEnterpriseCardIndexPda(entCardConfigName, payrollProgramId) {
|
|
41
|
+
return PublicKey.findProgramAddressSync([
|
|
42
|
+
PAYROLL_PROGRAM_SEEDS.ENT_CARD_INDEX,
|
|
43
|
+
utils.bytes.utf8.encode(entCardConfigName),
|
|
44
|
+
], translateAddress(payrollProgramId));
|
|
45
|
+
}
|
|
46
|
+
export function deriveEnterpriseCardPurchasePda(userAddress, entCardConfigName, cardIndex, payrollProgramId) {
|
|
47
|
+
return PublicKey.findProgramAddressSync([
|
|
48
|
+
PAYROLL_PROGRAM_SEEDS.ENT_USER_CARD_PURCHASE,
|
|
49
|
+
translateAddress(userAddress).toBuffer(),
|
|
50
|
+
utils.bytes.utf8.encode(entCardConfigName),
|
|
51
|
+
new BN(cardIndex).toArrayLike(Buffer, "le", 8),
|
|
52
|
+
], translateAddress(payrollProgramId));
|
|
53
|
+
}
|
|
54
|
+
export function deriveEnterpriseUserPurchaseRecordPda(userAddress, entCardConfigName, payrollProgramId) {
|
|
55
|
+
return PublicKey.findProgramAddressSync([
|
|
56
|
+
PAYROLL_PROGRAM_SEEDS.ENT_USER_PURCHASE_RECORD,
|
|
57
|
+
translateAddress(userAddress).toBuffer(),
|
|
58
|
+
utils.bytes.utf8.encode(entCardConfigName),
|
|
59
|
+
], translateAddress(payrollProgramId));
|
|
60
|
+
}
|
|
61
|
+
export function deriveEnterpriseCardConfigPda(entCardConfigName, zebecConfigProgramId) {
|
|
62
|
+
return PublicKey.findProgramAddressSync([
|
|
63
|
+
ZEBEC_CONFIG_PROGRAM_SEEDS.ENTERPRISE_CARD_CONFIG,
|
|
64
|
+
utils.bytes.utf8.encode(entCardConfigName),
|
|
65
|
+
], translateAddress(zebecConfigProgramId));
|
|
66
|
+
}
|
package/dist/services.d.ts
CHANGED
|
@@ -3,12 +3,12 @@ import { type Commitment } from "@solana/web3.js";
|
|
|
3
3
|
import { MultiTransactionPayload, TransactionPayload } from "@zebec-network/solana-common";
|
|
4
4
|
import type { ZebecConfigs as ZebecConfigsIdl } from "@zebec-network/zebec_configs";
|
|
5
5
|
import type { ZebecPayroll as ZebecPayrollIdl } from "@zebec-network/zebec_payroll";
|
|
6
|
-
import type { CancelMultiplePayrollParams, CancelPayrollParams, CancelUnlockParams, ChangePayrollReceiverParams, CompanyDepositInfo, CompanyNonceInfo, CompleteUnlockParams, CreateMultiplePayrollParams, CreatePayrollParams, DistributeRewardsParams, PauseResumeMultiplePayrollParams, PauseResumePayrollParams, PayrollConfigInfo, PayrollMetadataInfo, RequestUnlockParams, SetMultipleTopupDelegateParams, SetTopupDelegateParams, TokenMetadata, TopupMultiplePayrollParams, TopupPayrollParams, WithdrawMultiplePayrollParams, WithdrawPayrollParams, YieldDepositParams } from "./types.js";
|
|
6
|
+
import type { CancelMultiplePayrollParams, CancelPayrollParams, CancelUnlockParams, CardPurchaseInfo, ChangePayrollReceiverParams, CompanyDepositInfo, CompanyNonceInfo, CompleteUnlockParams, CreateCardParams, CreateMultiplePayrollParams, CreatePayrollParams, DistributeRewardsParams, PauseResumeMultiplePayrollParams, PauseResumePayrollParams, PayrollConfigInfo, PayrollMetadataInfo, RequestUnlockParams, SetMultipleTopupDelegateParams, SetTopupDelegateParams, SwapAndCreateCardParams, TokenMetadata, TopupMultiplePayrollParams, TopupPayrollParams, UserPurchaseRecordInfo, WithdrawMultiplePayrollParams, WithdrawPayrollParams, YieldDepositParams } from "./types.js";
|
|
7
7
|
export declare function getPayrollConfig(configProgram: Program<ZebecConfigsIdl>, configName: string): Promise<PayrollConfigInfo>;
|
|
8
8
|
export declare function getWhitelistedTokens(configProgram: Program<ZebecConfigsIdl>, configName: string, commitment?: "processed" | "confirmed" | "finalized"): Promise<TokenMetadata[]>;
|
|
9
9
|
export declare function getPayrollMetadataInfo(program: Program<ZebecPayrollIdl>, payrollMetadata: Address, commitment?: Commitment): Promise<PayrollMetadataInfo>;
|
|
10
|
-
export declare function createPayroll(payrollProgram: Program<ZebecPayrollIdl>, configProgram: Program<ZebecConfigsIdl>, params: CreatePayrollParams
|
|
11
|
-
export declare function createMultiplePayroll(payrollProgram: Program<ZebecPayrollIdl>, configProgram: Program<ZebecConfigsIdl>, params: CreateMultiplePayrollParams
|
|
10
|
+
export declare function createPayroll(payrollProgram: Program<ZebecPayrollIdl>, configProgram: Program<ZebecConfigsIdl>, params: CreatePayrollParams): Promise<TransactionPayload>;
|
|
11
|
+
export declare function createMultiplePayroll(payrollProgram: Program<ZebecPayrollIdl>, configProgram: Program<ZebecConfigsIdl>, params: CreateMultiplePayrollParams): Promise<MultiTransactionPayload>;
|
|
12
12
|
export declare function cancelPayroll(program: Program<ZebecPayrollIdl>, params: CancelPayrollParams): Promise<TransactionPayload>;
|
|
13
13
|
export declare function cancelMultiplePayroll(program: Program<ZebecPayrollIdl>, params: CancelMultiplePayrollParams): Promise<MultiTransactionPayload>;
|
|
14
14
|
export declare function pauseResumePayroll(program: Program<ZebecPayrollIdl>, params: PauseResumePayrollParams): Promise<TransactionPayload>;
|
|
@@ -27,3 +27,12 @@ export declare function cancelUnlock(payrollProgram: Program<ZebecPayrollIdl>, p
|
|
|
27
27
|
export declare function completeUnlock(payrollProgram: Program<ZebecPayrollIdl>, configsProgram: Program<ZebecConfigsIdl>, params: CompleteUnlockParams, commitment?: Commitment): Promise<TransactionPayload>;
|
|
28
28
|
export declare function distributeRewards(payrollProgram: Program<ZebecPayrollIdl>, configsProgram: Program<ZebecConfigsIdl>, params: DistributeRewardsParams): Promise<TransactionPayload>;
|
|
29
29
|
export declare function getCompanyDeposit(payrollProgram: Program<ZebecPayrollIdl>, company: Address): Promise<CompanyDepositInfo | null>;
|
|
30
|
+
export declare function createCard(payrollProgram: Program<ZebecPayrollIdl>, configsProgram: Program<ZebecConfigsIdl>, params: CreateCardParams): Promise<TransactionPayload>;
|
|
31
|
+
export declare function swapAndCreateCard(payrollProgram: Program<ZebecPayrollIdl>, configsProgram: Program<ZebecConfigsIdl>, params: SwapAndCreateCardParams): Promise<TransactionPayload>;
|
|
32
|
+
export declare function getCardIndexInfo(payrollProgram: Program<ZebecPayrollIdl>, entCardConfigName: string, commitment?: Commitment): Promise<{
|
|
33
|
+
index: bigint;
|
|
34
|
+
totoalCardSold: string;
|
|
35
|
+
} | null>;
|
|
36
|
+
export declare function getNextCardIndex(payrollProgram: Program<ZebecPayrollIdl>, entCardConfigName: string, commitment?: Commitment): Promise<bigint>;
|
|
37
|
+
export declare function getUserPurchaseRecordInfo(payrollProgram: Program<ZebecPayrollIdl>, entCardConfigName: string, user: Address, commitment?: Commitment): Promise<UserPurchaseRecordInfo | null>;
|
|
38
|
+
export declare function getCardPurchaseInfo(payrollProgram: Program<ZebecPayrollIdl>, entCardConfigName: string, user: Address, cardIndex: bigint, commitment?: Commitment): Promise<CardPurchaseInfo | null>;
|
package/dist/services.js
CHANGED
|
@@ -2,15 +2,18 @@ import { AnchorProvider, translateAddress, utils, } from "@coral-xyz/anchor";
|
|
|
2
2
|
import { fetchMetadata, MPL_TOKEN_METADATA_PROGRAM_ID, } from "@metaplex-foundation/mpl-token-metadata";
|
|
3
3
|
import { createUmi } from "@metaplex-foundation/umi-bundle-defaults";
|
|
4
4
|
import { fromWeb3JsPublicKey, toWeb3JsPublicKey, } from "@metaplex-foundation/umi-web3js-adapters";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
5
|
+
import { createCloseAccountInstruction, createSyncNativeInstruction, } from "@solana/spl-token";
|
|
6
|
+
import { AddressLookupTableAccount, ComputeBudgetProgram, Ed25519Program, Keypair, PublicKey, SystemProgram, TransactionMessage, VersionedTransaction, } from "@solana/web3.js";
|
|
7
|
+
import { assertBufferSize, bpsToPercent, percentToBps, } from "@zebec-network/core-utils";
|
|
8
|
+
import { createAssociatedTokenAccountInstruction, getAssociatedTokenAddressSync, getMintDecimals, MultiTransactionPayload, TEN_BIGNUM, TransactionPayload, UNITS_PER_USDC, USDC_DECIMALS, WSOL, } from "@zebec-network/solana-common";
|
|
8
9
|
import { BigNumber } from "bignumber.js";
|
|
9
10
|
import { BN } from "bn.js";
|
|
10
|
-
import { PAYROLL_NAME_BUFFER_SIZE, USX_DECIMALS } from "./constants.js";
|
|
11
|
-
import { createCancelPayrollInstruction, createCancelUnlockInstruction, createChangeRecipientInstruction, createCompleteUnlockInstruction, createCreatePayrollInstruction, createDistributeRewardsInstruction, createPauseResumePayrollInstruction, createRequestUnlockInstruction, createSetTopupDelegateInstruction,
|
|
12
|
-
import { deriveCheckAccountPda, deriveCompanyDepositPda, deriveCompanyNoncePda, derivePayrollConfigPda, derivePayrollVaultPda, deriveYieldConfigPda, } from "./pda.js";
|
|
13
|
-
import {
|
|
11
|
+
import { CARD_LOOKUP_TABLE_ADDRESS, ED25519_SIGNATURE_SIZE, JUPITER_AGGREGATOR_PROGRAM_ID, JUPITER_SWAP_API, PAYROLL_NAME_BUFFER_SIZE, PAYROLL_TOKEN_PRICE_MESSAGE_SIZE, USX_DECIMALS, } from "./constants.js";
|
|
12
|
+
import { createCancelPayrollInstruction, createCancelUnlockInstruction, createChangeRecipientInstruction, createCompleteUnlockInstruction, createCreateCardInstruction, createCreatePayrollInstruction, createDistributeRewardsInstruction, createPauseResumePayrollInstruction, createRequestUnlockInstruction, createSetTopupDelegateInstruction, createSwapAndCreateCardInstruction, createTopupPayrollInstruction, createWithdrawPayrollInstruction, createYieldDepositInstruction, } from "./instructions.js";
|
|
13
|
+
import { deriveCheckAccountPda, deriveCompanyDepositPda, deriveCompanyNoncePda, deriveEnterpriseCardConfigPda, deriveEnterpriseCardIndexPda, deriveEnterpriseCardPurchasePda, deriveEnterpriseUserPurchaseRecordPda, derivePayrollConfigPda, derivePayrollVaultPda, deriveYieldConfigPda, } from "./pda.js";
|
|
14
|
+
import { deductFeeFromAmount, getConnectionFromProgram,
|
|
15
|
+
// getFeeInfoForPayroll,
|
|
16
|
+
getFeeRateForMint, isAmountWithInProviderCardPurchaseRange, isAmountWithinDailyCardLimit, } from "./utils.js";
|
|
14
17
|
export async function getPayrollConfig(configProgram, configName) {
|
|
15
18
|
const [payrollConfigPda] = derivePayrollConfigPda(configName, configProgram.programId);
|
|
16
19
|
const payrollConfig = await configProgram.account.payrollConfig.fetchNullable(payrollConfigPda);
|
|
@@ -202,7 +205,7 @@ function createMultiTransactionPayload(program, feePayer, transactionData) {
|
|
|
202
205
|
feePayer,
|
|
203
206
|
})), signAllTransactions);
|
|
204
207
|
}
|
|
205
|
-
export async function createPayroll(payrollProgram, configProgram, params
|
|
208
|
+
export async function createPayroll(payrollProgram, configProgram, params) {
|
|
206
209
|
const receiver = translateAddress(params.receiver);
|
|
207
210
|
const sender = translateAddress(params.sender);
|
|
208
211
|
const feePayer = params.feePayer ? translateAddress(params.feePayer) : sender;
|
|
@@ -233,32 +236,21 @@ export async function createPayroll(payrollProgram, configProgram, params, payro
|
|
|
233
236
|
const cliffPercentage = new BN(percentToBps(params.cliffPercentage));
|
|
234
237
|
const payrollRunId = new Uint8Array(PAYROLL_NAME_BUFFER_SIZE);
|
|
235
238
|
payrollRunId.set(utils.bytes.utf8.encode(params.payrollRunId));
|
|
236
|
-
const feeInfo = await getFeeInfoForPayroll(payrollFeeBaseUrl, payrollToken, amount);
|
|
237
|
-
const feeTokenDecimals = await getMintDecimals(payrollProgram.provider.connection, payrollConfigAccount.feeToken);
|
|
238
|
-
const parsedFeeAmount = feeInfo.feeAmountRaw;
|
|
239
239
|
const feeVault = payrollConfigAccount.feeVault;
|
|
240
|
-
const
|
|
241
|
-
const
|
|
242
|
-
const
|
|
240
|
+
const feeVaultTokenAccount = getAssociatedTokenAddressSync(payrollToken, feeVault, true);
|
|
241
|
+
const priceExpiry = new BN(params.priceData.priceExpiryUnixTimestamp);
|
|
242
|
+
const tokenPrice = new BN(params.priceData.tokenPrice);
|
|
243
|
+
assertBufferSize(params.priceData.signature, ED25519_SIGNATURE_SIZE);
|
|
244
|
+
assertBufferSize(params.priceData.message, PAYROLL_TOKEN_PRICE_MESSAGE_SIZE);
|
|
245
|
+
const message = Uint8Array.from(params.priceData.message);
|
|
246
|
+
const signature = Uint8Array.from(params.priceData.signature);
|
|
243
247
|
const ixs = [];
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
}
|
|
249
|
-
// add instruction to transfer fee to fee vault
|
|
250
|
-
const transferFeeIx = await createTransferFeesInstruction(payrollProgram, {
|
|
251
|
-
feeVault,
|
|
252
|
-
feeVaultTokenAccount: feeVaultAta,
|
|
253
|
-
payrollConfig,
|
|
254
|
-
sender,
|
|
255
|
-
senderTokenAccount: senderFeeTokenAta,
|
|
256
|
-
tokenMint: payrollConfigAccount.feeToken,
|
|
257
|
-
}, {
|
|
258
|
-
decimals: feeTokenDecimals,
|
|
259
|
-
feeAmount: new BN(parsedFeeAmount),
|
|
248
|
+
const ed25519Ix = Ed25519Program.createInstructionWithPublicKey({
|
|
249
|
+
publicKey: payrollConfigAccount.admin.toBytes(), // admin pubkey (32 bytes)
|
|
250
|
+
signature, // backend signature (64 bytes),
|
|
251
|
+
message, // 48-byte price message
|
|
260
252
|
});
|
|
261
|
-
ixs.push(
|
|
253
|
+
ixs.push(ed25519Ix);
|
|
262
254
|
const createpayrollIx = await createCreatePayrollInstruction(payrollProgram, {
|
|
263
255
|
payrollConfig,
|
|
264
256
|
feePayer,
|
|
@@ -271,6 +263,8 @@ export async function createPayroll(payrollProgram, configProgram, params, payro
|
|
|
271
263
|
payrollVault,
|
|
272
264
|
payrollVaultAta,
|
|
273
265
|
withdrawAccount: withdrawer,
|
|
266
|
+
feeVault,
|
|
267
|
+
feeVaultTokenAccount,
|
|
274
268
|
}, {
|
|
275
269
|
autoTopupDelegate: Number(params.delegateAutoTopup),
|
|
276
270
|
initialBufferAmount: new BN(initialBufferAmount),
|
|
@@ -291,13 +285,15 @@ export async function createPayroll(payrollProgram, configProgram, params, payro
|
|
|
291
285
|
transferableBySender: Number(params.transferableBySender),
|
|
292
286
|
receiverId: Array.from(params.receiverId),
|
|
293
287
|
senderId: Array.from(params.senderId),
|
|
288
|
+
priceExpiry,
|
|
289
|
+
tokenPrice,
|
|
294
290
|
});
|
|
295
291
|
ixs.push(createpayrollIx);
|
|
296
292
|
return createTransactionPayload(payrollProgram, feePayer, ixs, [
|
|
297
293
|
payrollMetadataKeypair,
|
|
298
294
|
]);
|
|
299
295
|
}
|
|
300
|
-
export async function createMultiplePayroll(payrollProgram, configProgram, params
|
|
296
|
+
export async function createMultiplePayroll(payrollProgram, configProgram, params) {
|
|
301
297
|
const sender = translateAddress(params.sender);
|
|
302
298
|
const feePayer = params.feePayer ? translateAddress(params.feePayer) : sender;
|
|
303
299
|
const senderId = Array.from(params.senderId);
|
|
@@ -330,32 +326,21 @@ export async function createMultiplePayroll(payrollProgram, configProgram, param
|
|
|
330
326
|
const cliffPercentage = new BN(percentToBps(payroll.cliffPercentage));
|
|
331
327
|
const payrollRunId = new Uint8Array(PAYROLL_NAME_BUFFER_SIZE);
|
|
332
328
|
payrollRunId.set(utils.bytes.utf8.encode(payroll.payrollRunId));
|
|
333
|
-
const feeInfo = await getFeeInfoForPayroll(payrollFeeBaseUrl, payrollToken, amount);
|
|
334
|
-
const feeTokenDecimals = await getMintDecimals(payrollProgram.provider.connection, payrollConfigAccount.feeToken);
|
|
335
|
-
const parsedFeeAmount = feeInfo.feeAmountRaw;
|
|
336
329
|
const feeVault = payrollConfigAccount.feeVault;
|
|
337
|
-
const
|
|
338
|
-
const
|
|
339
|
-
const
|
|
330
|
+
const feeVaultTokenAccount = getAssociatedTokenAddressSync(payrollToken, feeVault, true);
|
|
331
|
+
const priceExpiry = new BN(payroll.priceData.priceExpiryUnixTimestamp);
|
|
332
|
+
const tokenPrice = new BN(payroll.priceData.tokenPrice);
|
|
333
|
+
const message = Uint8Array.from(payroll.priceData.message);
|
|
334
|
+
const signature = Uint8Array.from(payroll.priceData.signature);
|
|
335
|
+
assertBufferSize(payroll.priceData.signature, ED25519_SIGNATURE_SIZE);
|
|
336
|
+
assertBufferSize(payroll.priceData.message, PAYROLL_TOKEN_PRICE_MESSAGE_SIZE);
|
|
340
337
|
const instructions = [];
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
}
|
|
346
|
-
// add instruction to transfer fee to fee vault
|
|
347
|
-
const transferFeeIx = await createTransferFeesInstruction(payrollProgram, {
|
|
348
|
-
feeVault,
|
|
349
|
-
feeVaultTokenAccount: feeVaultAta,
|
|
350
|
-
payrollConfig,
|
|
351
|
-
sender,
|
|
352
|
-
senderTokenAccount: senderFeeTokenAta,
|
|
353
|
-
tokenMint: payrollConfigAccount.feeToken,
|
|
354
|
-
}, {
|
|
355
|
-
decimals: feeTokenDecimals,
|
|
356
|
-
feeAmount: new BN(parsedFeeAmount),
|
|
338
|
+
const ed25519Ix = Ed25519Program.createInstructionWithPublicKey({
|
|
339
|
+
publicKey: payrollConfigAccount.admin.toBytes(), // admin pubkey (32 bytes)
|
|
340
|
+
signature, // backend signature (64 bytes),
|
|
341
|
+
message, // 48-byte price message
|
|
357
342
|
});
|
|
358
|
-
instructions.push(
|
|
343
|
+
instructions.push(ed25519Ix);
|
|
359
344
|
const createpayrollIx = await createCreatePayrollInstruction(payrollProgram, {
|
|
360
345
|
payrollConfig,
|
|
361
346
|
feePayer,
|
|
@@ -368,6 +353,8 @@ export async function createMultiplePayroll(payrollProgram, configProgram, param
|
|
|
368
353
|
payrollVault,
|
|
369
354
|
payrollVaultAta,
|
|
370
355
|
withdrawAccount: withdrawer,
|
|
356
|
+
feeVault,
|
|
357
|
+
feeVaultTokenAccount,
|
|
371
358
|
}, {
|
|
372
359
|
autoTopupDelegate: Number(payroll.delegateAutoTopup),
|
|
373
360
|
initialBufferAmount: new BN(initialBufferAmount),
|
|
@@ -388,6 +375,8 @@ export async function createMultiplePayroll(payrollProgram, configProgram, param
|
|
|
388
375
|
transferableBySender: Number(payroll.transferableBySender),
|
|
389
376
|
receiverId: Array.from(payroll.receiverId),
|
|
390
377
|
senderId,
|
|
378
|
+
priceExpiry,
|
|
379
|
+
tokenPrice,
|
|
391
380
|
});
|
|
392
381
|
instructions.push(createpayrollIx);
|
|
393
382
|
return {
|
|
@@ -868,3 +857,298 @@ export async function getCompanyDeposit(payrollProgram, company) {
|
|
|
868
857
|
: null,
|
|
869
858
|
};
|
|
870
859
|
}
|
|
860
|
+
export async function createCard(payrollProgram, configsProgram, params) {
|
|
861
|
+
const connection = getConnectionFromProgram(payrollProgram);
|
|
862
|
+
const user = translateAddress(params.user);
|
|
863
|
+
const feePayer = translateAddress(params.feePayer);
|
|
864
|
+
assertBufferSize(params.emailHash, 32);
|
|
865
|
+
const [enterpriseCardConfig] = deriveEnterpriseCardConfigPda(params.entCardConfigName, configsProgram.programId);
|
|
866
|
+
const cardConfigAccount = await configsProgram.account.enterpriseCardConfig.fetchNullable(enterpriseCardConfig, connection.commitment);
|
|
867
|
+
if (!cardConfigAccount) {
|
|
868
|
+
throw new Error(`CardConfigAccountNotFound: Enterprise Card Config Account does not exits for config name: ${params.entCardConfigName}`);
|
|
869
|
+
}
|
|
870
|
+
const usdcMint = cardConfigAccount.usdcMint;
|
|
871
|
+
const cardVault = cardConfigAccount.cardVault;
|
|
872
|
+
const revenueVault = cardConfigAccount.revenueVault;
|
|
873
|
+
const userAta = getAssociatedTokenAddressSync(usdcMint, user, true);
|
|
874
|
+
const cardVaultAta = getAssociatedTokenAddressSync(usdcMint, cardVault, true);
|
|
875
|
+
const revenueVaultAta = getAssociatedTokenAddressSync(usdcMint, revenueVault, true);
|
|
876
|
+
const [enterpriseCardIndex] = deriveEnterpriseCardIndexPda(params.entCardConfigName, payrollProgram.programId);
|
|
877
|
+
const [cardPurchasePda] = deriveEnterpriseCardPurchasePda(user, params.entCardConfigName, params.nextCardIndex, payrollProgram.programId);
|
|
878
|
+
const [userPurchaseRecordPda] = deriveEnterpriseUserPurchaseRecordPda(user, params.entCardConfigName, payrollProgram.programId);
|
|
879
|
+
const unitsPerUSDC = BigNumber(10).pow(USDC_DECIMALS);
|
|
880
|
+
const amount = BigNumber(params.amount)
|
|
881
|
+
.times(unitsPerUSDC)
|
|
882
|
+
.toFixed(0, BigNumber.ROUND_FLOOR);
|
|
883
|
+
const feeRateInBps = BigNumber(getFeeRateForMint(cardConfigAccount.customFees.feeMap, usdcMint));
|
|
884
|
+
const amountWithoutFee = deductFeeFromAmount(amount, feeRateInBps);
|
|
885
|
+
const userPurchaseRecord = await payrollProgram.account.userPurchaseRecord.fetchNullable(userPurchaseRecordPda, "confirmed");
|
|
886
|
+
if (userPurchaseRecord &&
|
|
887
|
+
!isAmountWithinDailyCardLimit(userPurchaseRecord.dateTimeInUnix.toNumber(), userPurchaseRecord.totalBoughtPerDay.toString(), cardConfigAccount.dailyCardBuyLimit.toString(), amountWithoutFee)) {
|
|
888
|
+
throw new Error("DailyCardLimitReachedError: " +
|
|
889
|
+
"Daily card limit reached. Limit: " +
|
|
890
|
+
BigNumber(cardConfigAccount.dailyCardBuyLimit.toString())
|
|
891
|
+
.div(unitsPerUSDC)
|
|
892
|
+
.toFixed() +
|
|
893
|
+
" Requested (Fee Deducted): " +
|
|
894
|
+
BigNumber(amountWithoutFee).div(unitsPerUSDC).toFixed());
|
|
895
|
+
}
|
|
896
|
+
if (!isAmountWithInProviderCardPurchaseRange(cardConfigAccount.providerConfig.minCardAmount.toString(), cardConfigAccount.providerConfig.maxCardAmount.toString(), amountWithoutFee)) {
|
|
897
|
+
throw new Error("AmountOfProviderCardPurchaseRange:" +
|
|
898
|
+
"Amount out of range: " +
|
|
899
|
+
BigNumber(amountWithoutFee).div(unitsPerUSDC).toFixed() +
|
|
900
|
+
"(Fee Deducted); Must be within " +
|
|
901
|
+
BigNumber(cardConfigAccount.providerConfig.minCardAmount.toString())
|
|
902
|
+
.div(unitsPerUSDC)
|
|
903
|
+
.toFixed() +
|
|
904
|
+
"-" +
|
|
905
|
+
BigNumber(cardConfigAccount.providerConfig.maxCardAmount.toString())
|
|
906
|
+
.div(unitsPerUSDC)
|
|
907
|
+
.toFixed());
|
|
908
|
+
}
|
|
909
|
+
const instruction = await createCreateCardInstruction(payrollProgram, {
|
|
910
|
+
cardPurchasePda,
|
|
911
|
+
cardVault,
|
|
912
|
+
cardVaultAta,
|
|
913
|
+
enterpriseCardConfig,
|
|
914
|
+
enterpriseCardIndex,
|
|
915
|
+
feePayer,
|
|
916
|
+
revenueVault,
|
|
917
|
+
revenueVaultAta,
|
|
918
|
+
usdcMint,
|
|
919
|
+
user,
|
|
920
|
+
userAta,
|
|
921
|
+
userPurchaseRecordPda,
|
|
922
|
+
}, {
|
|
923
|
+
amount: new BN(amount),
|
|
924
|
+
currency: params.currency,
|
|
925
|
+
emailHash: Array.from(params.emailHash),
|
|
926
|
+
index: new BN(params.nextCardIndex),
|
|
927
|
+
reloadCardId: params.reloadCardId,
|
|
928
|
+
});
|
|
929
|
+
return createTransactionPayload(payrollProgram, feePayer, [instruction]);
|
|
930
|
+
}
|
|
931
|
+
export async function swapAndCreateCard(payrollProgram, configsProgram, params) {
|
|
932
|
+
const connection = getConnectionFromProgram(payrollProgram);
|
|
933
|
+
const user = translateAddress(params.user);
|
|
934
|
+
const feePayer = translateAddress(params.feePayer);
|
|
935
|
+
const quoteInfo = params.quoteInfo;
|
|
936
|
+
if ("error" in quoteInfo) {
|
|
937
|
+
throw new Error(quoteInfo.error);
|
|
938
|
+
}
|
|
939
|
+
assertBufferSize(params.emailHash, 32);
|
|
940
|
+
const [enterpriseCardConfig] = deriveEnterpriseCardConfigPda(params.entCardConfigName, configsProgram.programId);
|
|
941
|
+
const cardConfigAccount = await configsProgram.account.enterpriseCardConfig.fetchNullable(enterpriseCardConfig, connection.commitment);
|
|
942
|
+
if (!cardConfigAccount) {
|
|
943
|
+
throw new Error(`CardConfigAccountNotFound: Enterprise Card Config Account does not exits for config name: ${params.entCardConfigName}`);
|
|
944
|
+
}
|
|
945
|
+
const inputMint = translateAddress(quoteInfo.inputMint);
|
|
946
|
+
const usdcMint = translateAddress(quoteInfo.outputMint);
|
|
947
|
+
if (!usdcMint.equals(cardConfigAccount.usdcMint)) {
|
|
948
|
+
throw new Error("InvalidUSDCMint: Output mint in quoteInfo in is not a usdc");
|
|
949
|
+
}
|
|
950
|
+
const revenueVault = cardConfigAccount.revenueVault;
|
|
951
|
+
const cardVault = cardConfigAccount.cardVault;
|
|
952
|
+
const userAta = getAssociatedTokenAddressSync(usdcMint, user, true);
|
|
953
|
+
const cardVaultAta = getAssociatedTokenAddressSync(usdcMint, cardVault, true);
|
|
954
|
+
const revenueVaultAta = getAssociatedTokenAddressSync(usdcMint, revenueVault, true);
|
|
955
|
+
const [enterpriseCardIndex] = deriveEnterpriseCardIndexPda(params.entCardConfigName, payrollProgram.programId);
|
|
956
|
+
const [cardPurchasePda] = deriveEnterpriseCardPurchasePda(user, params.entCardConfigName, params.nextCardIndex, payrollProgram.programId);
|
|
957
|
+
const [userPurchaseRecordPda] = deriveEnterpriseUserPurchaseRecordPda(user, params.entCardConfigName, payrollProgram.programId);
|
|
958
|
+
const unitsPerUSDC = BigNumber(10).pow(USDC_DECIMALS);
|
|
959
|
+
const amount = quoteInfo.swapMode === "ExactIn"
|
|
960
|
+
? new BigNumber(quoteInfo.otherAmountThreshold)
|
|
961
|
+
: new BigNumber(quoteInfo.outAmount);
|
|
962
|
+
const feeRateInBps = BigNumber(getFeeRateForMint(cardConfigAccount.customFees.feeMap, inputMint));
|
|
963
|
+
const amountWithoutFee = deductFeeFromAmount(amount, feeRateInBps);
|
|
964
|
+
const userPurchaseRecord = await payrollProgram.account.userPurchaseRecord.fetchNullable(userPurchaseRecordPda, "confirmed");
|
|
965
|
+
if (userPurchaseRecord &&
|
|
966
|
+
!isAmountWithinDailyCardLimit(userPurchaseRecord.dateTimeInUnix.toNumber(), userPurchaseRecord.totalBoughtPerDay.toString(), cardConfigAccount.dailyCardBuyLimit.toString(), amountWithoutFee)) {
|
|
967
|
+
throw new Error("DailyCardLimitReachedError: " +
|
|
968
|
+
"Daily card limit reached. Limit: " +
|
|
969
|
+
BigNumber(cardConfigAccount.dailyCardBuyLimit.toString())
|
|
970
|
+
.div(unitsPerUSDC)
|
|
971
|
+
.toFixed() +
|
|
972
|
+
" Requested (Fee Deducted): " +
|
|
973
|
+
BigNumber(amountWithoutFee).div(unitsPerUSDC).toFixed());
|
|
974
|
+
}
|
|
975
|
+
if (!isAmountWithInProviderCardPurchaseRange(cardConfigAccount.providerConfig.minCardAmount.toString(), cardConfigAccount.providerConfig.maxCardAmount.toString(), amountWithoutFee)) {
|
|
976
|
+
throw new Error("AmountOfProviderCardPurchaseRange:" +
|
|
977
|
+
"Amount out of range: " +
|
|
978
|
+
BigNumber(amountWithoutFee).div(unitsPerUSDC).toFixed() +
|
|
979
|
+
"(Fee Deducted); Must be within " +
|
|
980
|
+
BigNumber(cardConfigAccount.providerConfig.minCardAmount.toString())
|
|
981
|
+
.div(unitsPerUSDC)
|
|
982
|
+
.toFixed() +
|
|
983
|
+
"-" +
|
|
984
|
+
BigNumber(cardConfigAccount.providerConfig.maxCardAmount.toString())
|
|
985
|
+
.div(unitsPerUSDC)
|
|
986
|
+
.toFixed());
|
|
987
|
+
}
|
|
988
|
+
// get serialized transactions for the swap
|
|
989
|
+
const { swapTransaction } = await (await fetch(JUPITER_SWAP_API, {
|
|
990
|
+
method: "POST",
|
|
991
|
+
headers: {
|
|
992
|
+
"Content-Type": "application/json",
|
|
993
|
+
},
|
|
994
|
+
body: JSON.stringify({
|
|
995
|
+
// quoteResponse from /quote api
|
|
996
|
+
quoteResponse: quoteInfo,
|
|
997
|
+
// user public key to be used for the swap
|
|
998
|
+
userPublicKey: user.toString(),
|
|
999
|
+
// auto wrap and unwrap SOL. default is true
|
|
1000
|
+
wrapAndUnwrapSol: false,
|
|
1001
|
+
}),
|
|
1002
|
+
})).json();
|
|
1003
|
+
// deserialize the transaction
|
|
1004
|
+
const swapTransactionBuf = Buffer.from(swapTransaction, "base64");
|
|
1005
|
+
const transaction = VersionedTransaction.deserialize(swapTransactionBuf);
|
|
1006
|
+
// get address lookup table accounts
|
|
1007
|
+
const addressLookupTableAccounts = await Promise.all(transaction.message.addressTableLookups.map(async (lookup) => {
|
|
1008
|
+
const data = await connection
|
|
1009
|
+
.getAccountInfo(lookup.accountKey)
|
|
1010
|
+
.then((res) => {
|
|
1011
|
+
if (!res) {
|
|
1012
|
+
throw new Error(`Address lookup table account not found: ${lookup.accountKey.toString()}`);
|
|
1013
|
+
}
|
|
1014
|
+
return res.data;
|
|
1015
|
+
});
|
|
1016
|
+
return new AddressLookupTableAccount({
|
|
1017
|
+
key: lookup.accountKey,
|
|
1018
|
+
state: AddressLookupTableAccount.deserialize(data),
|
|
1019
|
+
});
|
|
1020
|
+
}));
|
|
1021
|
+
const lookupTableData = await connection
|
|
1022
|
+
.getAccountInfo(translateAddress(CARD_LOOKUP_TABLE_ADDRESS["mainnet-beta"]))
|
|
1023
|
+
.then((res) => {
|
|
1024
|
+
if (!res) {
|
|
1025
|
+
throw new Error(`Address lookup table account not found: ${CARD_LOOKUP_TABLE_ADDRESS}`);
|
|
1026
|
+
}
|
|
1027
|
+
return res.data;
|
|
1028
|
+
});
|
|
1029
|
+
addressLookupTableAccounts.push(new AddressLookupTableAccount({
|
|
1030
|
+
key: translateAddress(CARD_LOOKUP_TABLE_ADDRESS["mainnet-beta"]),
|
|
1031
|
+
state: AddressLookupTableAccount.deserialize(lookupTableData),
|
|
1032
|
+
}));
|
|
1033
|
+
// decompile transaction message and add transfer instruction
|
|
1034
|
+
const message = TransactionMessage.decompile(transaction.message, {
|
|
1035
|
+
addressLookupTableAccounts: addressLookupTableAccounts,
|
|
1036
|
+
});
|
|
1037
|
+
const swapInstruction = message.instructions.find((ix) => ix.programId.equals(translateAddress(JUPITER_AGGREGATOR_PROGRAM_ID)));
|
|
1038
|
+
if (!swapInstruction) {
|
|
1039
|
+
throw new Error("Swap instruction not found in the transaction message");
|
|
1040
|
+
}
|
|
1041
|
+
const otherIxs = message.instructions.filter((ix) => !ix.programId.equals(translateAddress(JUPITER_AGGREGATOR_PROGRAM_ID)) &&
|
|
1042
|
+
!ix.programId.equals(ComputeBudgetProgram.programId));
|
|
1043
|
+
const isSolWrapUnwrapNeeded = inputMint.equals(WSOL);
|
|
1044
|
+
const wsolTokenAccount = getAssociatedTokenAddressSync(WSOL, // mint (Wrapped SOL)
|
|
1045
|
+
user, // owner
|
|
1046
|
+
true);
|
|
1047
|
+
if (params.wrapAndUnwrapWsol && isSolWrapUnwrapNeeded) {
|
|
1048
|
+
const wrapIxns = [];
|
|
1049
|
+
// Get the associated token account address for WSOL
|
|
1050
|
+
const wsolTokenAccountInfo = await connection.getAccountInfo(wsolTokenAccount, connection.commitment);
|
|
1051
|
+
if (!wsolTokenAccountInfo) {
|
|
1052
|
+
// create and push unwrap instructions
|
|
1053
|
+
const createWsolTokenAccountIx = createAssociatedTokenAccountInstruction(feePayer, // payer
|
|
1054
|
+
wsolTokenAccount, // associated token account address
|
|
1055
|
+
user, // owner
|
|
1056
|
+
WSOL);
|
|
1057
|
+
wrapIxns.push(createWsolTokenAccountIx);
|
|
1058
|
+
}
|
|
1059
|
+
const amountToSync = quoteInfo.inAmount;
|
|
1060
|
+
const transferSolToWsolIx = SystemProgram.transfer({
|
|
1061
|
+
fromPubkey: user,
|
|
1062
|
+
toPubkey: wsolTokenAccount,
|
|
1063
|
+
lamports: BigInt(amountToSync),
|
|
1064
|
+
});
|
|
1065
|
+
wrapIxns.push(transferSolToWsolIx);
|
|
1066
|
+
// create and push wrap instructions
|
|
1067
|
+
const wrapIx = createSyncNativeInstruction(wsolTokenAccount);
|
|
1068
|
+
wrapIxns.push(wrapIx);
|
|
1069
|
+
otherIxs.unshift(...wrapIxns);
|
|
1070
|
+
}
|
|
1071
|
+
const instruction = await createSwapAndCreateCardInstruction(payrollProgram, {
|
|
1072
|
+
cardPurchasePda,
|
|
1073
|
+
cardVault,
|
|
1074
|
+
cardVaultAta,
|
|
1075
|
+
enterpriseCardConfig,
|
|
1076
|
+
enterpriseCardIndex,
|
|
1077
|
+
feePayer,
|
|
1078
|
+
revenueVault,
|
|
1079
|
+
revenueVaultAta,
|
|
1080
|
+
sourceToken: inputMint,
|
|
1081
|
+
usdcMint,
|
|
1082
|
+
user,
|
|
1083
|
+
userAta,
|
|
1084
|
+
userPurchaseRecordPda,
|
|
1085
|
+
}, {
|
|
1086
|
+
currency: params.currency,
|
|
1087
|
+
emailHash: Array.from(params.emailHash),
|
|
1088
|
+
index: new BN(params.nextCardIndex),
|
|
1089
|
+
reloadCardId: params.reloadCardId,
|
|
1090
|
+
swapData: swapInstruction.data,
|
|
1091
|
+
}, swapInstruction.keys);
|
|
1092
|
+
otherIxs.push(instruction);
|
|
1093
|
+
if (params.wrapAndUnwrapWsol && isSolWrapUnwrapNeeded) {
|
|
1094
|
+
// create and push unwrap instructions
|
|
1095
|
+
const closeWsolAccountIx = createCloseAccountInstruction(wsolTokenAccount, // account to be closed
|
|
1096
|
+
user, // destination
|
|
1097
|
+
user);
|
|
1098
|
+
otherIxs.push(closeWsolAccountIx);
|
|
1099
|
+
}
|
|
1100
|
+
return createTransactionPayload(payrollProgram, feePayer, otherIxs, [], addressLookupTableAccounts);
|
|
1101
|
+
}
|
|
1102
|
+
export async function getCardIndexInfo(payrollProgram, entCardConfigName, commitment) {
|
|
1103
|
+
const connection = getConnectionFromProgram(payrollProgram);
|
|
1104
|
+
commitment = commitment ?? connection.commitment;
|
|
1105
|
+
const [enterpriseCardIndex] = deriveEnterpriseCardIndexPda(entCardConfigName, payrollProgram.programId);
|
|
1106
|
+
const info = await payrollProgram.account.enterpriseCardIndex.fetchNullable(enterpriseCardIndex, commitment);
|
|
1107
|
+
if (!info) {
|
|
1108
|
+
return null;
|
|
1109
|
+
}
|
|
1110
|
+
return {
|
|
1111
|
+
index: BigInt(info.index.toString()),
|
|
1112
|
+
totoalCardSold: BigNumber(info.totalBought.toString())
|
|
1113
|
+
.div(BigNumber(10).pow(USDC_DECIMALS))
|
|
1114
|
+
.toFixed(),
|
|
1115
|
+
};
|
|
1116
|
+
}
|
|
1117
|
+
export async function getNextCardIndex(payrollProgram, entCardConfigName, commitment) {
|
|
1118
|
+
const info = await getCardIndexInfo(payrollProgram, entCardConfigName, commitment);
|
|
1119
|
+
const currentIndex = info ? info.index : BigInt(0);
|
|
1120
|
+
return currentIndex + BigInt(1);
|
|
1121
|
+
}
|
|
1122
|
+
export async function getUserPurchaseRecordInfo(payrollProgram, entCardConfigName, user, commitment) {
|
|
1123
|
+
const connection = getConnectionFromProgram(payrollProgram);
|
|
1124
|
+
commitment = commitment ?? connection.commitment;
|
|
1125
|
+
const [userPurchaseRecordPda] = deriveEnterpriseUserPurchaseRecordPda(user, entCardConfigName, payrollProgram.programId);
|
|
1126
|
+
const info = await payrollProgram.account.userPurchaseRecord.fetchNullable(userPurchaseRecordPda, commitment);
|
|
1127
|
+
if (!info) {
|
|
1128
|
+
return null;
|
|
1129
|
+
}
|
|
1130
|
+
return {
|
|
1131
|
+
user: info.userAddress,
|
|
1132
|
+
lastCardBoughtPerDay: BigNumber(info.totalBoughtPerDay.toString())
|
|
1133
|
+
.div(BigNumber(10).pow(USDC_DECIMALS))
|
|
1134
|
+
.toFixed(),
|
|
1135
|
+
lastCardBoughtTimestamp: info.dateTimeInUnix.toNumber(),
|
|
1136
|
+
};
|
|
1137
|
+
}
|
|
1138
|
+
export async function getCardPurchaseInfo(payrollProgram, entCardConfigName, user, cardIndex, commitment) {
|
|
1139
|
+
const connection = getConnectionFromProgram(payrollProgram);
|
|
1140
|
+
commitment = commitment ?? connection.commitment;
|
|
1141
|
+
const [cardPurchasePda] = deriveEnterpriseCardPurchasePda(user, entCardConfigName, cardIndex, payrollProgram.programId);
|
|
1142
|
+
const info = await payrollProgram.account.cardPurchase.fetchNullable(cardPurchasePda, commitment);
|
|
1143
|
+
if (!info) {
|
|
1144
|
+
return null;
|
|
1145
|
+
}
|
|
1146
|
+
return {
|
|
1147
|
+
index: BigInt(info.index.toString()),
|
|
1148
|
+
buyer: info.buyerAddress,
|
|
1149
|
+
amount: BigNumber(info.amount.toString())
|
|
1150
|
+
.div(BigNumber(10).pow(USDC_DECIMALS))
|
|
1151
|
+
.toFixed(),
|
|
1152
|
+
purchasedAt: info.purchaseAt.toNumber(),
|
|
1153
|
+
};
|
|
1154
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -72,6 +72,12 @@ export type TokenMetadata = {
|
|
|
72
72
|
uri: string;
|
|
73
73
|
} | null;
|
|
74
74
|
};
|
|
75
|
+
export type PayrollTokenPriceData = {
|
|
76
|
+
priceExpiryUnixTimestamp: bigint;
|
|
77
|
+
tokenPrice: bigint;
|
|
78
|
+
signature: Buffer | Uint8Array;
|
|
79
|
+
message: Buffer | Uint8Array;
|
|
80
|
+
};
|
|
75
81
|
export type CreatePayrollParams = {
|
|
76
82
|
payrollConfigName: string;
|
|
77
83
|
feePayer?: Address;
|
|
@@ -98,6 +104,7 @@ export type CreatePayrollParams = {
|
|
|
98
104
|
payrollMetadataKeypair?: Keypair;
|
|
99
105
|
senderId: number[] | Uint8Array | Buffer;
|
|
100
106
|
receiverId: number[] | Uint8Array | Buffer;
|
|
107
|
+
priceData: PayrollTokenPriceData;
|
|
101
108
|
};
|
|
102
109
|
export type CreateMultiplePayrollParams = {
|
|
103
110
|
payrollConfigName: string;
|
|
@@ -126,6 +133,7 @@ export type CreateMultiplePayrollParams = {
|
|
|
126
133
|
initialBufferAmount: number;
|
|
127
134
|
payrollMetadataKeypair?: Keypair;
|
|
128
135
|
receiverId: number[] | Uint8Array | Buffer;
|
|
136
|
+
priceData: PayrollTokenPriceData;
|
|
129
137
|
}[];
|
|
130
138
|
};
|
|
131
139
|
export type FeeTier = {
|
|
@@ -274,3 +282,79 @@ export type CompanyDepositInfo = {
|
|
|
274
282
|
requestTime: number;
|
|
275
283
|
} | null;
|
|
276
284
|
};
|
|
285
|
+
/**
|
|
286
|
+
* Jupiter quote routes info
|
|
287
|
+
*/
|
|
288
|
+
export type RouteInfo = {
|
|
289
|
+
swapInfo: {
|
|
290
|
+
ammKey: string;
|
|
291
|
+
label: string;
|
|
292
|
+
inputMint: string;
|
|
293
|
+
outputMint: string;
|
|
294
|
+
inAmount: string;
|
|
295
|
+
outAmount: string;
|
|
296
|
+
feeAmount: string;
|
|
297
|
+
feeMint: string;
|
|
298
|
+
};
|
|
299
|
+
percent: number;
|
|
300
|
+
bps: number;
|
|
301
|
+
};
|
|
302
|
+
/**
|
|
303
|
+
* Jupiter quote info
|
|
304
|
+
*/
|
|
305
|
+
export type QuoteInfo = {
|
|
306
|
+
inputMint: string;
|
|
307
|
+
inAmount: string;
|
|
308
|
+
outputMint: string;
|
|
309
|
+
outAmount: string;
|
|
310
|
+
otherAmountThreshold: string;
|
|
311
|
+
swapMode: "ExactIn" | "ExactOut";
|
|
312
|
+
slippageBps: number;
|
|
313
|
+
platformFee: {
|
|
314
|
+
amount: string;
|
|
315
|
+
feeBps: number;
|
|
316
|
+
} | null;
|
|
317
|
+
priceImpactPct: string;
|
|
318
|
+
routePlan: RouteInfo[];
|
|
319
|
+
contextSlot: number;
|
|
320
|
+
timeTaken: number;
|
|
321
|
+
swapUsdValue: string;
|
|
322
|
+
simplerRouteUsed: boolean;
|
|
323
|
+
mostReliableAmmsQuoteReport: {
|
|
324
|
+
info: Record<string, string>;
|
|
325
|
+
};
|
|
326
|
+
} | {
|
|
327
|
+
error: string;
|
|
328
|
+
};
|
|
329
|
+
export type CreateCardParams = {
|
|
330
|
+
currency: string;
|
|
331
|
+
reloadCardId: string;
|
|
332
|
+
nextCardIndex: bigint;
|
|
333
|
+
user: Address;
|
|
334
|
+
feePayer: Address;
|
|
335
|
+
emailHash: Buffer | Uint8Array;
|
|
336
|
+
amount: Numeric;
|
|
337
|
+
entCardConfigName: string;
|
|
338
|
+
};
|
|
339
|
+
export type SwapAndCreateCardParams = {
|
|
340
|
+
currency: string;
|
|
341
|
+
reloadCardId: string;
|
|
342
|
+
nextCardIndex: bigint;
|
|
343
|
+
user: Address;
|
|
344
|
+
feePayer: Address;
|
|
345
|
+
emailHash: Buffer | Uint8Array;
|
|
346
|
+
entCardConfigName: string;
|
|
347
|
+
quoteInfo: QuoteInfo;
|
|
348
|
+
wrapAndUnwrapWsol?: boolean;
|
|
349
|
+
};
|
|
350
|
+
export type CardPurchaseInfo = {
|
|
351
|
+
index: bigint;
|
|
352
|
+
buyer: Address;
|
|
353
|
+
amount: Numeric;
|
|
354
|
+
purchasedAt: number;
|
|
355
|
+
};
|
|
356
|
+
export type UserPurchaseRecordInfo = {
|
|
357
|
+
user: Address;
|
|
358
|
+
lastCardBoughtPerDay: Numeric;
|
|
359
|
+
lastCardBoughtTimestamp: number;
|
|
360
|
+
};
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
|
-
import type { Address } from "@coral-xyz/anchor";
|
|
1
|
+
import type { Address, Idl, Program } from "@coral-xyz/anchor";
|
|
2
|
+
import type { PublicKey } from "@solana/web3.js";
|
|
2
3
|
import { BigNumber } from "bignumber.js";
|
|
4
|
+
import type BN from "bn.js";
|
|
3
5
|
import type { FeeTier, PayrollFeeInfo } from "./types.js";
|
|
4
6
|
export declare function getFeeInfoForPayroll(baseUrl: string, payrollToken: Address, parsedStreamTokenAmount: BigNumber.Value): Promise<PayrollFeeInfo>;
|
|
5
7
|
export declare function getFeeRateForUsdAmount(amount: BigNumber.Value, feeTiers: FeeTier[]): string;
|
|
8
|
+
export declare function getConnectionFromProgram<T extends Idl>(program: Program<T>): import("@solana/web3.js").Connection;
|
|
9
|
+
export declare function isAmountWithinDailyCardLimit(lastCardBoughtUnixTimestamp: number, lastCardBoughtRawAmountPerDay: BigNumber.Value, rawDailyCardBuyLimit: BigNumber.Value, rawAmount: BigNumber.Value): boolean;
|
|
10
|
+
export declare function isAmountWithInProviderCardPurchaseRange(rawMinCardAmount: BigNumber.Value, rawMaxCardAmount: BigNumber.Value, rawAmount: BigNumber.Value): boolean;
|
|
11
|
+
export type ParsedTokenFeeItem = {
|
|
12
|
+
tokenAddress: PublicKey;
|
|
13
|
+
fee: BN;
|
|
14
|
+
};
|
|
15
|
+
export declare function getFeeRateForMint(feeRateList: ParsedTokenFeeItem[], mint: PublicKey): number;
|
|
16
|
+
export declare function deductFeeFromAmount(rawAmount: BigNumber.Value, feeRateInBps: BigNumber.Value): string;
|
package/dist/utils.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { percentToBps } from "@zebec-network/core-utils";
|
|
1
|
+
import { areDatesOfSameDay, percentToBps } from "@zebec-network/core-utils";
|
|
2
2
|
import { BigNumber } from "bignumber.js";
|
|
3
|
+
import { BPS_DENOMINATOR, DEFAULT_FEE_RATE_IN_BPS } from "./constants.js";
|
|
3
4
|
export async function getFeeInfoForPayroll(baseUrl, payrollToken, parsedStreamTokenAmount) {
|
|
4
5
|
const urlsParams = new URLSearchParams({
|
|
5
6
|
tokenMint: payrollToken.toString(),
|
|
@@ -60,3 +61,41 @@ export function getFeeRateForUsdAmount(amount, feeTiers) {
|
|
|
60
61
|
}
|
|
61
62
|
return percentToBps(tier.feeRateInPercent);
|
|
62
63
|
}
|
|
64
|
+
export function getConnectionFromProgram(program) {
|
|
65
|
+
return program.provider.connection;
|
|
66
|
+
}
|
|
67
|
+
export function isAmountWithinDailyCardLimit(lastCardBoughtUnixTimestamp, lastCardBoughtRawAmountPerDay, rawDailyCardBuyLimit, rawAmount) {
|
|
68
|
+
const dailyCardBuyLimit = BigNumber(rawDailyCardBuyLimit);
|
|
69
|
+
const amount = BigNumber(rawAmount);
|
|
70
|
+
const today = new Date();
|
|
71
|
+
const lastCardBoughtDate = new Date(lastCardBoughtUnixTimestamp * 1000);
|
|
72
|
+
let cardBoughtInADay = BigNumber(0);
|
|
73
|
+
if (areDatesOfSameDay(today, lastCardBoughtDate)) {
|
|
74
|
+
cardBoughtInADay = BigNumber(lastCardBoughtRawAmountPerDay).plus(amount);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
cardBoughtInADay = amount;
|
|
78
|
+
}
|
|
79
|
+
if (cardBoughtInADay.isGreaterThan(dailyCardBuyLimit)) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
export function isAmountWithInProviderCardPurchaseRange(rawMinCardAmount, rawMaxCardAmount, rawAmount) {
|
|
85
|
+
const minRange = BigNumber(rawMinCardAmount);
|
|
86
|
+
const maxRange = BigNumber(rawMaxCardAmount);
|
|
87
|
+
const amount = BigNumber(rawAmount);
|
|
88
|
+
if (amount.isLessThan(minRange) || amount.isGreaterThan(maxRange)) {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
export function getFeeRateForMint(feeRateList, mint) {
|
|
94
|
+
return (feeRateList.find((fr) => fr.tokenAddress.equals(mint))?.fee.toNumber() ||
|
|
95
|
+
DEFAULT_FEE_RATE_IN_BPS);
|
|
96
|
+
}
|
|
97
|
+
export function deductFeeFromAmount(rawAmount, feeRateInBps) {
|
|
98
|
+
const amount = BigNumber(rawAmount);
|
|
99
|
+
const fee = amount.times(feeRateInBps).div(BPS_DENOMINATOR);
|
|
100
|
+
return amount.minus(fee).toFixed(0, BigNumber.ROUND_FLOOR);
|
|
101
|
+
}
|
package/package.json
CHANGED
|
@@ -9,10 +9,11 @@
|
|
|
9
9
|
"@solana/spl-token": "^0.4.14",
|
|
10
10
|
"@solana/web3.js": "^1.98.2",
|
|
11
11
|
"@zebec-network/core-utils": "^1.3.1",
|
|
12
|
-
"@zebec-network/solana-common": "^2.6.
|
|
13
|
-
"@zebec-network/zebec_configs": "^1.2.
|
|
14
|
-
"@zebec-network/zebec_payroll": "^1.5.
|
|
15
|
-
"bignumber.js": "^11.1.1"
|
|
12
|
+
"@zebec-network/solana-common": "^2.6.1",
|
|
13
|
+
"@zebec-network/zebec_configs": "^1.2.6",
|
|
14
|
+
"@zebec-network/zebec_payroll": "^1.5.4",
|
|
15
|
+
"bignumber.js": "^11.1.1",
|
|
16
|
+
"bn.js": "^5.2.3"
|
|
16
17
|
},
|
|
17
18
|
"devDependencies": {
|
|
18
19
|
"@types/bn.js": "^5.2.0",
|
|
@@ -23,6 +24,7 @@
|
|
|
23
24
|
"rimraf": "^6.1.3",
|
|
24
25
|
"ts-mocha": "^11.1.0",
|
|
25
26
|
"ts-node": "^10.9.2",
|
|
27
|
+
"tweetnacl": "^1.0.3",
|
|
26
28
|
"typescript": "^6.0.3"
|
|
27
29
|
},
|
|
28
30
|
"files": [
|
|
@@ -43,5 +45,5 @@
|
|
|
43
45
|
},
|
|
44
46
|
"type": "module",
|
|
45
47
|
"types": "dist/index.d.ts",
|
|
46
|
-
"version": "2.
|
|
48
|
+
"version": "2.6.0-dev.2"
|
|
47
49
|
}
|