@paul.lumberwork/bonding-curve-sdk 1.7.0 → 1.7.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/index.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  import { BN } from '@coral-xyz/anchor';
2
- import { PublicKey, LAMPORTS_PER_SOL, SystemProgram, Keypair, SYSVAR_RENT_PUBKEY, ComputeBudgetProgram } from '@solana/web3.js';
3
- import { getAssociatedTokenAddressSync, ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID, getAccount } from '@solana/spl-token';
2
+ import { PublicKey, LAMPORTS_PER_SOL, SystemProgram, Keypair, SYSVAR_RENT_PUBKEY, ComputeBudgetProgram, Ed25519Program, SYSVAR_INSTRUCTIONS_PUBKEY, Transaction } from '@solana/web3.js';
3
+ import { getAssociatedTokenAddressSync, ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID, getAccount, createAssociatedTokenAccountIdempotentInstruction } from '@solana/spl-token';
4
+ import nacl from 'tweetnacl';
4
5
 
5
6
  // src/sdk/index.ts
6
7
  var PROGRAM_ID = new PublicKey("6o7oTqg2CfvcMCJTLNEJsef7c875zGpTvcnFctNAjudL");
@@ -133,6 +134,22 @@ var KickFunSDK = class {
133
134
  preInstructions.push(
134
135
  ComputeBudgetProgram.setComputeUnitLimit({ units: computeUnits })
135
136
  );
137
+ preInstructions.push(
138
+ createAssociatedTokenAccountIdempotentInstruction(
139
+ this.wallet.publicKey,
140
+ streamerTokenAccount,
141
+ streamerVaultPda,
142
+ mint
143
+ )
144
+ );
145
+ preInstructions.push(
146
+ createAssociatedTokenAccountIdempotentInstruction(
147
+ this.wallet.publicKey,
148
+ adminTokenAccount,
149
+ ADMIN_WALLET,
150
+ mint
151
+ )
152
+ );
136
153
  const tx = await this.program.methods.buyTokens(solLamports).accountsPartial({
137
154
  contributor: this.wallet.publicKey,
138
155
  launchpad: this.launchpadPda,
@@ -616,6 +633,252 @@ var KickFunSDK = class {
616
633
  return numerator / denominator;
617
634
  }
618
635
  };
636
+ var StreamerSDK = class _StreamerSDK {
637
+ constructor(program, wallet) {
638
+ this.program = program;
639
+ this.connection = program.provider.connection;
640
+ this.wallet = wallet;
641
+ }
642
+ // ═══════════════════════════════════════════════════════════════════════════
643
+ // PDA Derivation Helpers
644
+ // ═══════════════════════════════════════════════════════════════════════════
645
+ derivePlatformConfig() {
646
+ const [pda] = PublicKey.findProgramAddressSync(
647
+ [Buffer.from("platform_config")],
648
+ this.program.programId
649
+ );
650
+ return pda;
651
+ }
652
+ deriveWhitelistEntry(wallet) {
653
+ const [pda] = PublicKey.findProgramAddressSync(
654
+ [Buffer.from("whitelist"), wallet.toBuffer()],
655
+ this.program.programId
656
+ );
657
+ return pda;
658
+ }
659
+ deriveStreamerRegistration(streamerId) {
660
+ const [pda] = PublicKey.findProgramAddressSync(
661
+ [Buffer.from("streamer"), Buffer.from(streamerId)],
662
+ this.program.programId
663
+ );
664
+ return pda;
665
+ }
666
+ deriveVault() {
667
+ const [pda] = PublicKey.findProgramAddressSync(
668
+ [Buffer.from("vault")],
669
+ this.program.programId
670
+ );
671
+ return pda;
672
+ }
673
+ // ═══════════════════════════════════════════════════════════════════════════
674
+ // Helpers
675
+ // ═══════════════════════════════════════════════════════════════════════════
676
+ async getSolanaTimestamp() {
677
+ const slot = await this.connection.getSlot();
678
+ const blockTime = await this.connection.getBlockTime(slot);
679
+ if (!blockTime) throw new Error("Failed to get block time");
680
+ return blockTime;
681
+ }
682
+ // ═══════════════════════════════════════════════════════════════════════════
683
+ // Ed25519 Signing Utilities (for browser wallets / external signers)
684
+ // ═══════════════════════════════════════════════════════════════════════════
685
+ /**
686
+ * Build the message that the streamer must sign for register_streamer.
687
+ * The streamer signs this with their wallet (e.g. Phantom signMessage).
688
+ *
689
+ * Format: "register_streamer:{streamer_id}:{wallet}:{timestamp}"
690
+ */
691
+ buildRegisterMessage(streamerId, streamerWallet, timestamp) {
692
+ const msg = `register_streamer:${streamerId}:${streamerWallet.toBase58()}:${timestamp}`;
693
+ return Buffer.from(msg, "utf-8");
694
+ }
695
+ /**
696
+ * Build the message that the streamer must sign for claim_funds.
697
+ * The streamer signs this with their wallet (e.g. Phantom signMessage).
698
+ *
699
+ * Format: "claim_funds:{streamer_id}:{wallet}:{mint}:{token_amount}:{sol_amount}:{timestamp}"
700
+ */
701
+ buildClaimMessage(streamerId, streamerWallet, mint, tokenAmount, solAmount, timestamp) {
702
+ const msg = `claim_funds:${streamerId}:${streamerWallet.toBase58()}:${mint.toBase58()}:${tokenAmount.toString()}:${solAmount.toString()}:${timestamp}`;
703
+ return Buffer.from(msg, "utf-8");
704
+ }
705
+ /**
706
+ * Create an Ed25519 instruction from an externally-signed signature.
707
+ * Use this when the streamer signs via browser wallet (Phantom, Solflare, etc.)
708
+ * instead of exposing a Keypair.
709
+ *
710
+ * @param streamerWallet - Public key of the streamer
711
+ * @param message - The message bytes (from buildRegisterMessage / buildClaimMessage)
712
+ * @param signature - The Ed25519 signature from wallet.signMessage(message)
713
+ */
714
+ createEd25519Instruction(streamerWallet, message, signature) {
715
+ return Ed25519Program.createInstructionWithPublicKey({
716
+ publicKey: streamerWallet.toBytes(),
717
+ message,
718
+ signature
719
+ });
720
+ }
721
+ /**
722
+ * Sign a message using a Keypair directly (server-side / test usage).
723
+ * Returns the Ed25519 signature bytes.
724
+ */
725
+ static signMessage(message, keypair) {
726
+ return nacl.sign.detached(message, keypair.secretKey);
727
+ }
728
+ // ═══════════════════════════════════════════════════════════════════════════
729
+ // Register Streamer
730
+ // ═══════════════════════════════════════════════════════════════════════════
731
+ async registerStreamer(params) {
732
+ const { streamerId, streamerKeypair } = params;
733
+ const timestamp = await this.getSolanaTimestamp();
734
+ const msgBytes = this.buildRegisterMessage(streamerId, streamerKeypair.publicKey, timestamp);
735
+ const sig = _StreamerSDK.signMessage(msgBytes, streamerKeypair);
736
+ const ed25519Ix = this.createEd25519Instruction(streamerKeypair.publicKey, msgBytes, sig);
737
+ const whitelistPda = this.deriveWhitelistEntry(this.wallet.publicKey);
738
+ const streamerRegPda = this.deriveStreamerRegistration(streamerId);
739
+ const registerIx = await this.program.methods.registerStreamer(
740
+ streamerId,
741
+ streamerKeypair.publicKey,
742
+ new BN(timestamp)
743
+ ).accounts({
744
+ caller: this.wallet.publicKey,
745
+ whitelistEntry: whitelistPda,
746
+ streamerRegistration: streamerRegPda,
747
+ instructionsSysvar: SYSVAR_INSTRUCTIONS_PUBKEY
748
+ }).instruction();
749
+ const tx = new Transaction().add(ed25519Ix).add(registerIx);
750
+ const provider = this.program.provider;
751
+ const txSignature = await provider.sendAndConfirm(tx);
752
+ return { txSignature, streamerRegistrationPda: streamerRegPda };
753
+ }
754
+ // ═══════════════════════════════════════════════════════════════════════════
755
+ // Claim Funds
756
+ // ═══════════════════════════════════════════════════════════════════════════
757
+ async claimFunds(params) {
758
+ const { streamerId, streamerKeypair, mint, solAmount, tokenAmount } = params;
759
+ const timestamp = await this.getSolanaTimestamp();
760
+ const msgBytes = this.buildClaimMessage(streamerId, streamerKeypair.publicKey, mint, tokenAmount, solAmount, timestamp);
761
+ const sig = _StreamerSDK.signMessage(msgBytes, streamerKeypair);
762
+ const ed25519Ix = this.createEd25519Instruction(streamerKeypair.publicKey, msgBytes, sig);
763
+ const whitelistPda = this.deriveWhitelistEntry(this.wallet.publicKey);
764
+ const streamerRegPda = this.deriveStreamerRegistration(streamerId);
765
+ const vaultPda = this.deriveVault();
766
+ const programTokenAccount = getAssociatedTokenAddressSync(
767
+ mint,
768
+ vaultPda,
769
+ true
770
+ );
771
+ const streamerTokenAccount = getAssociatedTokenAddressSync(
772
+ mint,
773
+ streamerKeypair.publicKey,
774
+ false
775
+ );
776
+ const claimIx = await this.program.methods.claimFunds(streamerId, solAmount, tokenAmount, new BN(timestamp)).accounts({
777
+ caller: this.wallet.publicKey,
778
+ whitelistEntry: whitelistPda,
779
+ streamerRegistration: streamerRegPda,
780
+ streamerWallet: streamerKeypair.publicKey,
781
+ vault: vaultPda,
782
+ mint,
783
+ programTokenAccount,
784
+ streamerTokenAccount,
785
+ instructionsSysvar: SYSVAR_INSTRUCTIONS_PUBKEY
786
+ }).instruction();
787
+ const tx = new Transaction().add(ed25519Ix).add(claimIx);
788
+ const provider = this.program.provider;
789
+ const txSignature = await provider.sendAndConfirm(tx);
790
+ return { txSignature };
791
+ }
792
+ // ═══════════════════════════════════════════════════════════════════════════
793
+ // Register Streamer (browser wallet — signature from Phantom/Solflare)
794
+ // ═══════════════════════════════════════════════════════════════════════════
795
+ async registerStreamerWithSignature(params) {
796
+ const { streamerId, streamerPublicKey, signature, timestamp } = params;
797
+ const msgBytes = this.buildRegisterMessage(streamerId, streamerPublicKey, timestamp);
798
+ const ed25519Ix = this.createEd25519Instruction(streamerPublicKey, msgBytes, signature);
799
+ const whitelistPda = this.deriveWhitelistEntry(this.wallet.publicKey);
800
+ const streamerRegPda = this.deriveStreamerRegistration(streamerId);
801
+ const registerIx = await this.program.methods.registerStreamer(streamerId, streamerPublicKey, new BN(timestamp)).accounts({
802
+ caller: this.wallet.publicKey,
803
+ whitelistEntry: whitelistPda,
804
+ streamerRegistration: streamerRegPda,
805
+ instructionsSysvar: SYSVAR_INSTRUCTIONS_PUBKEY
806
+ }).instruction();
807
+ const tx = new Transaction().add(ed25519Ix).add(registerIx);
808
+ const provider = this.program.provider;
809
+ const txSignature = await provider.sendAndConfirm(tx);
810
+ return { txSignature, streamerRegistrationPda: streamerRegPda };
811
+ }
812
+ // ═══════════════════════════════════════════════════════════════════════════
813
+ // Claim Funds (browser wallet — signature from Phantom/Solflare)
814
+ // ═══════════════════════════════════════════════════════════════════════════
815
+ async claimFundsWithSignature(params) {
816
+ const { streamerId, streamerPublicKey, mint, solAmount, tokenAmount, signature, timestamp } = params;
817
+ const msgBytes = this.buildClaimMessage(streamerId, streamerPublicKey, mint, tokenAmount, solAmount, timestamp);
818
+ const ed25519Ix = this.createEd25519Instruction(streamerPublicKey, msgBytes, signature);
819
+ const whitelistPda = this.deriveWhitelistEntry(this.wallet.publicKey);
820
+ const streamerRegPda = this.deriveStreamerRegistration(streamerId);
821
+ const vaultPda = this.deriveVault();
822
+ const programTokenAccount = getAssociatedTokenAddressSync(mint, vaultPda, true);
823
+ const streamerTokenAccount = getAssociatedTokenAddressSync(mint, streamerPublicKey, false);
824
+ const claimIx = await this.program.methods.claimFunds(streamerId, solAmount, tokenAmount, new BN(timestamp)).accounts({
825
+ caller: this.wallet.publicKey,
826
+ whitelistEntry: whitelistPda,
827
+ streamerRegistration: streamerRegPda,
828
+ streamerWallet: streamerPublicKey,
829
+ vault: vaultPda,
830
+ mint,
831
+ programTokenAccount,
832
+ streamerTokenAccount,
833
+ instructionsSysvar: SYSVAR_INSTRUCTIONS_PUBKEY
834
+ }).instruction();
835
+ const tx = new Transaction().add(ed25519Ix).add(claimIx);
836
+ const provider = this.program.provider;
837
+ const txSignature = await provider.sendAndConfirm(tx);
838
+ return { txSignature };
839
+ }
840
+ // ═══════════════════════════════════════════════════════════════════════════
841
+ // Read State
842
+ // ═══════════════════════════════════════════════════════════════════════════
843
+ async getStreamerRegistration(streamerId) {
844
+ const pda = this.deriveStreamerRegistration(streamerId);
845
+ try {
846
+ const account = await this.program.account.streamerRegistration.fetch(pda);
847
+ return {
848
+ streamerId: account.streamerId,
849
+ wallet: account.wallet,
850
+ verifiedAt: account.verifiedAt.toNumber(),
851
+ registeredBy: account.registeredBy,
852
+ createdAt: account.createdAt.toNumber()
853
+ };
854
+ } catch {
855
+ return null;
856
+ }
857
+ }
858
+ async isWhitelisted(wallet) {
859
+ const pda = this.deriveWhitelistEntry(wallet);
860
+ try {
861
+ const account = await this.program.account.whitelistEntry.fetch(pda);
862
+ return account.active;
863
+ } catch {
864
+ return false;
865
+ }
866
+ }
867
+ async getVaultBalance(mint) {
868
+ const vaultPda = this.deriveVault();
869
+ const sol = BigInt(await this.connection.getBalance(vaultPda));
870
+ let tokens = 0n;
871
+ if (mint) {
872
+ const ata = getAssociatedTokenAddressSync(mint, vaultPda, true);
873
+ try {
874
+ const account = await getAccount(this.connection, ata);
875
+ tokens = account.amount;
876
+ } catch {
877
+ }
878
+ }
879
+ return { sol, tokens };
880
+ }
881
+ };
619
882
  function formatTokens(raw) {
620
883
  const tokens = Number(raw) / 10 ** TOKEN_DECIMALS;
621
884
  return tokens.toLocaleString(void 0, { maximumFractionDigits: 2 });
@@ -631,6 +894,6 @@ function parseTokens(tokens) {
631
894
  return BigInt(Math.floor(tokens * 10 ** TOKEN_DECIMALS));
632
895
  }
633
896
 
634
- export { ADMIN_WALLET, CURVE_PERCENT, FEE_BPS, K_SCALE, KickFunSDK, LAMPORTS, LP_PERCENT, METADATA_PROGRAM_ID, PROGRAM_ID, STREAMER_PROGRAM_ID, TOKEN_DECIMALS, TREASURY_PERCENT, formatSol, formatTokens, parseSol, parseTokens };
897
+ export { ADMIN_WALLET, CURVE_PERCENT, FEE_BPS, K_SCALE, KickFunSDK, LAMPORTS, LP_PERCENT, METADATA_PROGRAM_ID, PROGRAM_ID, STREAMER_PROGRAM_ID, StreamerSDK, TOKEN_DECIMALS, TREASURY_PERCENT, formatSol, formatTokens, parseSol, parseTokens };
635
898
  //# sourceMappingURL=index.mjs.map
636
899
  //# sourceMappingURL=index.mjs.map