pump-trader 1.0.2 → 1.0.3
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/index.d.ts +2 -2
- package/dist/index.js +10 -8
- package/index.js +12 -9
- package/index.ts +14 -10
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -158,8 +158,8 @@ export declare class PumpTrader {
|
|
|
158
158
|
protocolFeeRecipients: PublicKey[];
|
|
159
159
|
};
|
|
160
160
|
getAmmPoolReserves(poolKeys: any): Promise<PoolReserves>;
|
|
161
|
-
createAmmBuyInstruction(poolInfo: PoolInfo, userBaseAta: PublicKey, userQuoteAta: PublicKey, baseAmountOut: bigint, maxQuoteAmountIn: bigint): TransactionInstruction;
|
|
162
|
-
createAmmSellInstruction(poolInfo: PoolInfo, userBaseAta: PublicKey, userQuoteAta: PublicKey, baseAmountIn: bigint, minQuoteAmountOut: bigint): TransactionInstruction;
|
|
161
|
+
createAmmBuyInstruction(poolInfo: PoolInfo, userBaseAta: PublicKey, userQuoteAta: PublicKey, baseAmountOut: bigint, maxQuoteAmountIn: bigint, tokenProgramId: PublicKey): TransactionInstruction;
|
|
162
|
+
createAmmSellInstruction(poolInfo: PoolInfo, userBaseAta: PublicKey, userQuoteAta: PublicKey, baseAmountIn: bigint, minQuoteAmountOut: bigint, tokenProgramId: PublicKey): TransactionInstruction;
|
|
163
163
|
confirmTransactionWithPolling(signature: string, lastValidBlockHeight: number, maxAttempts?: number, delayMs?: number): Promise<string>;
|
|
164
164
|
listenTrades(callback: (event: TradeEvent) => void, mintFilter?: PublicKey | null): number;
|
|
165
165
|
fetchMeta(tokenAddr: string): Promise<MetadataInfo | null>;
|
package/dist/index.js
CHANGED
|
@@ -607,6 +607,7 @@ class PumpTrader {
|
|
|
607
607
|
const poolInfo = await this.getAmmPoolInfo(mint);
|
|
608
608
|
const reserves = await this.getAmmPoolReserves(poolInfo.poolKeys);
|
|
609
609
|
const solChunks = this.splitByMax(totalSolIn, tradeOpt.maxSolPerTx);
|
|
610
|
+
const tokenProgram = await this.detectTokenProgram(tokenAddr);
|
|
610
611
|
const pendingTransactions = [];
|
|
611
612
|
const failedTransactions = [];
|
|
612
613
|
for (let i = 0; i < solChunks.length; i++) {
|
|
@@ -621,9 +622,9 @@ class PumpTrader {
|
|
|
621
622
|
const maxQuoteIn = (solIn * BigInt(10_000 + slippageBps)) / 10000n;
|
|
622
623
|
const priority = this.genPriority(tradeOpt.priority);
|
|
623
624
|
const tx = new web3_js_1.Transaction().add(web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: 300_000 }), web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: priority }));
|
|
624
|
-
const userBaseAta = await this.ensureAta(tx, poolInfo.poolKeys.baseMint);
|
|
625
|
+
const userBaseAta = await this.ensureAta(tx, poolInfo.poolKeys.baseMint, tokenProgram.programId);
|
|
625
626
|
const userQuoteAta = await this.ensureWSOLAta(tx, this.wallet.publicKey, "buy", maxQuoteIn);
|
|
626
|
-
const buyIx = this.createAmmBuyInstruction(poolInfo, userBaseAta, userQuoteAta, baseAmountOut, maxQuoteIn);
|
|
627
|
+
const buyIx = this.createAmmBuyInstruction(poolInfo, userBaseAta, userQuoteAta, baseAmountOut, maxQuoteIn, tokenProgram.programId);
|
|
627
628
|
tx.add(buyIx);
|
|
628
629
|
tx.add((0, spl_token_1.createCloseAccountInstruction)(userQuoteAta, this.wallet.publicKey, this.wallet.publicKey));
|
|
629
630
|
const { blockhash, lastValidBlockHeight } = await this.connection.getLatestBlockhash('finalized');
|
|
@@ -654,6 +655,7 @@ class PumpTrader {
|
|
|
654
655
|
const poolInfo = await this.getAmmPoolInfo(mint);
|
|
655
656
|
const reserves = await this.getAmmPoolReserves(poolInfo.poolKeys);
|
|
656
657
|
const totalSolOut = this.calculateAmmSellOutput(totalTokenIn, reserves);
|
|
658
|
+
const tokenProgram = await this.detectTokenProgram(tokenAddr);
|
|
657
659
|
const tokenChunks = totalSolOut <= tradeOpt.maxSolPerTx
|
|
658
660
|
? [totalTokenIn]
|
|
659
661
|
: this.splitIntoN(totalTokenIn, Number((totalSolOut + tradeOpt.maxSolPerTx - 1n) / tradeOpt.maxSolPerTx));
|
|
@@ -671,9 +673,9 @@ class PumpTrader {
|
|
|
671
673
|
const minQuoteOut = (solOut * BigInt(10_000 - slippageBps)) / 10000n;
|
|
672
674
|
const priority = this.genPriority(tradeOpt.priority);
|
|
673
675
|
const tx = new web3_js_1.Transaction().add(web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: 300_000 }), web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: priority }));
|
|
674
|
-
const userBaseAta = await this.ensureAta(tx, poolInfo.poolKeys.baseMint);
|
|
676
|
+
const userBaseAta = await this.ensureAta(tx, poolInfo.poolKeys.baseMint, tokenProgram.programId);
|
|
675
677
|
const userQuoteAta = await this.ensureWSOLAta(tx, this.wallet.publicKey, "sell");
|
|
676
|
-
const sellIx = this.createAmmSellInstruction(poolInfo, userBaseAta, userQuoteAta, tokenIn, minQuoteOut);
|
|
678
|
+
const sellIx = this.createAmmSellInstruction(poolInfo, userBaseAta, userQuoteAta, tokenIn, minQuoteOut, tokenProgram.programId);
|
|
677
679
|
tx.add(sellIx);
|
|
678
680
|
tx.add((0, spl_token_1.createCloseAccountInstruction)(userQuoteAta, this.wallet.publicKey, this.wallet.publicKey));
|
|
679
681
|
const { blockhash, lastValidBlockHeight } = await this.connection.getLatestBlockhash('finalized');
|
|
@@ -747,7 +749,7 @@ class PumpTrader {
|
|
|
747
749
|
};
|
|
748
750
|
}
|
|
749
751
|
/* ---------- AMM 指令构建 ---------- */
|
|
750
|
-
createAmmBuyInstruction(poolInfo, userBaseAta, userQuoteAta, baseAmountOut, maxQuoteAmountIn) {
|
|
752
|
+
createAmmBuyInstruction(poolInfo, userBaseAta, userQuoteAta, baseAmountOut, maxQuoteAmountIn, tokenProgramId) {
|
|
751
753
|
const { pool, poolKeys, globalConfig } = poolInfo;
|
|
752
754
|
const [eventAuthority] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("__event_authority")], PROGRAM_IDS.PUMP_AMM);
|
|
753
755
|
const [coinCreatorVaultAuthority] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("creator_vault"), poolKeys.coinCreator.toBuffer()], PROGRAM_IDS.PUMP_AMM);
|
|
@@ -771,7 +773,7 @@ class PumpTrader {
|
|
|
771
773
|
{ pubkey: poolKeys.poolQuoteTokenAccount, isSigner: false, isWritable: true },
|
|
772
774
|
{ pubkey: protocolFeeRecipient, isSigner: false, isWritable: false },
|
|
773
775
|
{ pubkey: protocolFeeRecipientTokenAccount, isSigner: false, isWritable: true },
|
|
774
|
-
{ pubkey:
|
|
776
|
+
{ pubkey: tokenProgramId, isSigner: false, isWritable: false },
|
|
775
777
|
{ pubkey: spl_token_1.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
776
778
|
{ pubkey: web3_js_1.SystemProgram.programId, isSigner: false, isWritable: false },
|
|
777
779
|
{ pubkey: spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
@@ -792,7 +794,7 @@ class PumpTrader {
|
|
|
792
794
|
])
|
|
793
795
|
});
|
|
794
796
|
}
|
|
795
|
-
createAmmSellInstruction(poolInfo, userBaseAta, userQuoteAta, baseAmountIn, minQuoteAmountOut) {
|
|
797
|
+
createAmmSellInstruction(poolInfo, userBaseAta, userQuoteAta, baseAmountIn, minQuoteAmountOut, tokenProgramId) {
|
|
796
798
|
const { pool, poolKeys, globalConfig } = poolInfo;
|
|
797
799
|
const [eventAuthority] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("__event_authority")], PROGRAM_IDS.PUMP_AMM);
|
|
798
800
|
const [coinCreatorVaultAuthority] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("creator_vault"), poolKeys.coinCreator.toBuffer()], PROGRAM_IDS.PUMP_AMM);
|
|
@@ -814,7 +816,7 @@ class PumpTrader {
|
|
|
814
816
|
{ pubkey: poolKeys.poolQuoteTokenAccount, isSigner: false, isWritable: true },
|
|
815
817
|
{ pubkey: protocolFeeRecipient, isSigner: false, isWritable: false },
|
|
816
818
|
{ pubkey: protocolFeeRecipientTokenAccount, isSigner: false, isWritable: true },
|
|
817
|
-
{ pubkey:
|
|
819
|
+
{ pubkey: tokenProgramId, isSigner: false, isWritable: false },
|
|
818
820
|
{ pubkey: spl_token_1.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
819
821
|
{ pubkey: web3_js_1.SystemProgram.programId, isSigner: false, isWritable: false },
|
|
820
822
|
{ pubkey: spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
package/index.js
CHANGED
|
@@ -838,7 +838,7 @@ export class PumpTrader {
|
|
|
838
838
|
const poolInfo = await this.getAmmPoolInfo(mint);
|
|
839
839
|
const reserves = await this.getAmmPoolReserves(poolInfo.poolKeys);
|
|
840
840
|
const solChunks = this.splitByMax(totalSolIn, tradeOpt.maxSolPerTx);
|
|
841
|
-
|
|
841
|
+
const tokenProgram = await this.detectTokenProgram(tokenAddr);
|
|
842
842
|
const pendingTransactions = [];
|
|
843
843
|
const failedTransactions = [];
|
|
844
844
|
|
|
@@ -859,7 +859,7 @@ export class PumpTrader {
|
|
|
859
859
|
ComputeBudgetProgram.setComputeUnitPrice({ microLamports: priority })
|
|
860
860
|
);
|
|
861
861
|
|
|
862
|
-
const userBaseAta = await this.ensureAta(tx, poolInfo.poolKeys.baseMint);
|
|
862
|
+
const userBaseAta = await this.ensureAta(tx, poolInfo.poolKeys.baseMint, tokenProgram.programId);
|
|
863
863
|
const userQuoteAta = await this.ensureWSOLAta(
|
|
864
864
|
tx,
|
|
865
865
|
this.wallet.publicKey,
|
|
@@ -872,7 +872,8 @@ export class PumpTrader {
|
|
|
872
872
|
userBaseAta,
|
|
873
873
|
userQuoteAta,
|
|
874
874
|
baseAmountOut,
|
|
875
|
-
maxQuoteIn
|
|
875
|
+
maxQuoteIn,
|
|
876
|
+
tokenProgram.programId
|
|
876
877
|
);
|
|
877
878
|
|
|
878
879
|
tx.add(buyIx);
|
|
@@ -916,6 +917,7 @@ export class PumpTrader {
|
|
|
916
917
|
const poolInfo = await this.getAmmPoolInfo(mint);
|
|
917
918
|
const reserves = await this.getAmmPoolReserves(poolInfo.poolKeys);
|
|
918
919
|
const totalSolOut = this.calculateAmmSellOutput(totalTokenIn, reserves);
|
|
920
|
+
const tokenProgram = await this.detectTokenProgram(tokenAddr);
|
|
919
921
|
|
|
920
922
|
const tokenChunks = totalSolOut <= tradeOpt.maxSolPerTx
|
|
921
923
|
? [totalTokenIn]
|
|
@@ -944,7 +946,7 @@ export class PumpTrader {
|
|
|
944
946
|
ComputeBudgetProgram.setComputeUnitPrice({ microLamports: priority })
|
|
945
947
|
);
|
|
946
948
|
|
|
947
|
-
const userBaseAta = await this.ensureAta(tx, poolInfo.poolKeys.baseMint);
|
|
949
|
+
const userBaseAta = await this.ensureAta(tx, poolInfo.poolKeys.baseMint, tokenProgram.programId);
|
|
948
950
|
const userQuoteAta = await this.ensureWSOLAta(tx, this.wallet.publicKey, "sell");
|
|
949
951
|
|
|
950
952
|
const sellIx = this.createAmmSellInstruction(
|
|
@@ -952,7 +954,8 @@ export class PumpTrader {
|
|
|
952
954
|
userBaseAta,
|
|
953
955
|
userQuoteAta,
|
|
954
956
|
tokenIn,
|
|
955
|
-
minQuoteOut
|
|
957
|
+
minQuoteOut,
|
|
958
|
+
tokenProgram.programId
|
|
956
959
|
);
|
|
957
960
|
|
|
958
961
|
tx.add(sellIx);
|
|
@@ -1063,7 +1066,7 @@ export class PumpTrader {
|
|
|
1063
1066
|
|
|
1064
1067
|
/* ---------- AMM 指令构建 ---------- */
|
|
1065
1068
|
|
|
1066
|
-
createAmmBuyInstruction(poolInfo, userBaseAta, userQuoteAta, baseAmountOut, maxQuoteAmountIn) {
|
|
1069
|
+
createAmmBuyInstruction(poolInfo, userBaseAta, userQuoteAta, baseAmountOut, maxQuoteAmountIn, tokenProgramId) {
|
|
1067
1070
|
const { pool, poolKeys, globalConfig } = poolInfo;
|
|
1068
1071
|
|
|
1069
1072
|
const [eventAuthority] = PublicKey.findProgramAddressSync(
|
|
@@ -1122,7 +1125,7 @@ export class PumpTrader {
|
|
|
1122
1125
|
{ pubkey: poolKeys.poolQuoteTokenAccount, isSigner: false, isWritable: true },
|
|
1123
1126
|
{ pubkey: protocolFeeRecipient, isSigner: false, isWritable: false },
|
|
1124
1127
|
{ pubkey: protocolFeeRecipientTokenAccount, isSigner: false, isWritable: true },
|
|
1125
|
-
{ pubkey:
|
|
1128
|
+
{ pubkey: tokenProgramId, isSigner: false, isWritable: false },
|
|
1126
1129
|
{ pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
1127
1130
|
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
|
|
1128
1131
|
{ pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
@@ -1144,7 +1147,7 @@ export class PumpTrader {
|
|
|
1144
1147
|
});
|
|
1145
1148
|
}
|
|
1146
1149
|
|
|
1147
|
-
createAmmSellInstruction(poolInfo, userBaseAta, userQuoteAta, baseAmountIn, minQuoteAmountOut) {
|
|
1150
|
+
createAmmSellInstruction(poolInfo, userBaseAta, userQuoteAta, baseAmountIn, minQuoteAmountOut, tokenProgramId) {
|
|
1148
1151
|
const { pool, poolKeys, globalConfig } = poolInfo;
|
|
1149
1152
|
|
|
1150
1153
|
const [eventAuthority] = PublicKey.findProgramAddressSync(
|
|
@@ -1193,7 +1196,7 @@ export class PumpTrader {
|
|
|
1193
1196
|
{ pubkey: poolKeys.poolQuoteTokenAccount, isSigner: false, isWritable: true },
|
|
1194
1197
|
{ pubkey: protocolFeeRecipient, isSigner: false, isWritable: false },
|
|
1195
1198
|
{ pubkey: protocolFeeRecipientTokenAccount, isSigner: false, isWritable: true },
|
|
1196
|
-
{ pubkey:
|
|
1199
|
+
{ pubkey: tokenProgramId, isSigner: false, isWritable: false },
|
|
1197
1200
|
{ pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
1198
1201
|
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
|
|
1199
1202
|
{ pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
package/index.ts
CHANGED
|
@@ -945,7 +945,7 @@ export class PumpTrader {
|
|
|
945
945
|
const poolInfo = await this.getAmmPoolInfo(mint);
|
|
946
946
|
const reserves = await this.getAmmPoolReserves(poolInfo.poolKeys);
|
|
947
947
|
const solChunks = this.splitByMax(totalSolIn, tradeOpt.maxSolPerTx);
|
|
948
|
-
|
|
948
|
+
const tokenProgram = await this.detectTokenProgram(tokenAddr);
|
|
949
949
|
const pendingTransactions: PendingTransaction[] = [];
|
|
950
950
|
const failedTransactions: FailedTransaction[] = [];
|
|
951
951
|
|
|
@@ -966,7 +966,7 @@ export class PumpTrader {
|
|
|
966
966
|
ComputeBudgetProgram.setComputeUnitPrice({ microLamports: priority })
|
|
967
967
|
);
|
|
968
968
|
|
|
969
|
-
const userBaseAta = await this.ensureAta(tx, poolInfo.poolKeys.baseMint);
|
|
969
|
+
const userBaseAta = await this.ensureAta(tx, poolInfo.poolKeys.baseMint, tokenProgram.programId);
|
|
970
970
|
const userQuoteAta = await this.ensureWSOLAta(
|
|
971
971
|
tx,
|
|
972
972
|
this.wallet.publicKey,
|
|
@@ -979,7 +979,8 @@ export class PumpTrader {
|
|
|
979
979
|
userBaseAta,
|
|
980
980
|
userQuoteAta,
|
|
981
981
|
baseAmountOut,
|
|
982
|
-
maxQuoteIn
|
|
982
|
+
maxQuoteIn,
|
|
983
|
+
tokenProgram.programId
|
|
983
984
|
);
|
|
984
985
|
|
|
985
986
|
tx.add(buyIx);
|
|
@@ -1023,7 +1024,7 @@ export class PumpTrader {
|
|
|
1023
1024
|
const poolInfo = await this.getAmmPoolInfo(mint);
|
|
1024
1025
|
const reserves = await this.getAmmPoolReserves(poolInfo.poolKeys);
|
|
1025
1026
|
const totalSolOut = this.calculateAmmSellOutput(totalTokenIn, reserves);
|
|
1026
|
-
|
|
1027
|
+
const tokenProgram = await this.detectTokenProgram(tokenAddr);
|
|
1027
1028
|
const tokenChunks = totalSolOut <= tradeOpt.maxSolPerTx
|
|
1028
1029
|
? [totalTokenIn]
|
|
1029
1030
|
: this.splitIntoN(
|
|
@@ -1051,7 +1052,7 @@ export class PumpTrader {
|
|
|
1051
1052
|
ComputeBudgetProgram.setComputeUnitPrice({ microLamports: priority })
|
|
1052
1053
|
);
|
|
1053
1054
|
|
|
1054
|
-
const userBaseAta = await this.ensureAta(tx, poolInfo.poolKeys.baseMint);
|
|
1055
|
+
const userBaseAta = await this.ensureAta(tx, poolInfo.poolKeys.baseMint, tokenProgram.programId);
|
|
1055
1056
|
const userQuoteAta = await this.ensureWSOLAta(tx, this.wallet.publicKey, "sell");
|
|
1056
1057
|
|
|
1057
1058
|
const sellIx = this.createAmmSellInstruction(
|
|
@@ -1059,7 +1060,8 @@ export class PumpTrader {
|
|
|
1059
1060
|
userBaseAta,
|
|
1060
1061
|
userQuoteAta,
|
|
1061
1062
|
tokenIn,
|
|
1062
|
-
minQuoteOut
|
|
1063
|
+
minQuoteOut,
|
|
1064
|
+
tokenProgram.programId
|
|
1063
1065
|
);
|
|
1064
1066
|
|
|
1065
1067
|
tx.add(sellIx);
|
|
@@ -1175,7 +1177,8 @@ export class PumpTrader {
|
|
|
1175
1177
|
userBaseAta: PublicKey,
|
|
1176
1178
|
userQuoteAta: PublicKey,
|
|
1177
1179
|
baseAmountOut: bigint,
|
|
1178
|
-
maxQuoteAmountIn: bigint
|
|
1180
|
+
maxQuoteAmountIn: bigint,
|
|
1181
|
+
tokenProgramId: PublicKey
|
|
1179
1182
|
): TransactionInstruction {
|
|
1180
1183
|
const { pool, poolKeys, globalConfig } = poolInfo;
|
|
1181
1184
|
|
|
@@ -1235,7 +1238,7 @@ export class PumpTrader {
|
|
|
1235
1238
|
{ pubkey: poolKeys.poolQuoteTokenAccount, isSigner: false, isWritable: true },
|
|
1236
1239
|
{ pubkey: protocolFeeRecipient, isSigner: false, isWritable: false },
|
|
1237
1240
|
{ pubkey: protocolFeeRecipientTokenAccount, isSigner: false, isWritable: true },
|
|
1238
|
-
{ pubkey:
|
|
1241
|
+
{ pubkey: tokenProgramId, isSigner: false, isWritable: false },
|
|
1239
1242
|
{ pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
1240
1243
|
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
|
|
1241
1244
|
{ pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
@@ -1262,7 +1265,8 @@ export class PumpTrader {
|
|
|
1262
1265
|
userBaseAta: PublicKey,
|
|
1263
1266
|
userQuoteAta: PublicKey,
|
|
1264
1267
|
baseAmountIn: bigint,
|
|
1265
|
-
minQuoteAmountOut: bigint
|
|
1268
|
+
minQuoteAmountOut: bigint,
|
|
1269
|
+
tokenProgramId: PublicKey
|
|
1266
1270
|
): TransactionInstruction {
|
|
1267
1271
|
const { pool, poolKeys, globalConfig } = poolInfo;
|
|
1268
1272
|
|
|
@@ -1312,7 +1316,7 @@ export class PumpTrader {
|
|
|
1312
1316
|
{ pubkey: poolKeys.poolQuoteTokenAccount, isSigner: false, isWritable: true },
|
|
1313
1317
|
{ pubkey: protocolFeeRecipient, isSigner: false, isWritable: false },
|
|
1314
1318
|
{ pubkey: protocolFeeRecipientTokenAccount, isSigner: false, isWritable: true },
|
|
1315
|
-
{ pubkey:
|
|
1319
|
+
{ pubkey: tokenProgramId, isSigner: false, isWritable: false },
|
|
1316
1320
|
{ pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
1317
1321
|
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
|
|
1318
1322
|
{ pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|