diff --git a/packages/sdk/src/PaymentStreamClient.ts b/packages/sdk/src/PaymentStreamClient.ts index cf9a78f..46cffee 100644 --- a/packages/sdk/src/PaymentStreamClient.ts +++ b/packages/sdk/src/PaymentStreamClient.ts @@ -1,7 +1,3 @@ -import { Client as ContractClient } from './generated/payment-stream/src/index'; -import { AssembledTransaction, ClientOptions as ContractClientOptions } from '@stellar/stellar-sdk/contract'; -import { rpc as SorobanRpc } from '@stellar/stellar-sdk'; -import { Stream, StreamMetrics, ProtocolMetrics, StreamStatus } from './generated/payment-stream/src/index'; import { Client as ContractClient } from "./generated/payment-stream/src/index"; import { AssembledTransaction, @@ -34,16 +30,6 @@ function addressToString(address: AddressParam): string { return typeof address === "string" ? address : address.toString(); } -export type StreamEventType = 'created' | 'deposit' | 'withdraw' | 'paused' | 'resumed' | 'canceled' | 'completed' | 'delegate_set' | 'delegate_revoked' | 'fee_collected'; - -export interface StreamHistoryEvent { - type: StreamEventType; - streamId: bigint; - ledger: number; - timestamp: number; - data: Record; -} - /** * High-level client for interacting with the Payment Stream contract. * Provides a type-safe and DX-optimized interface for all contract methods. @@ -52,15 +38,6 @@ export interface StreamHistoryEvent { * and transaction result XDR to provide human-readable error messages. */ export class PaymentStreamClient { - private client: ContractClient; - private rpcUrl: string; - private contractId: string; - - constructor(options: ContractClientOptions) { - this.client = new ContractClient(options); - this.rpcUrl = options.rpcUrl; - this.contractId = options.contractId; - } private client: ContractClient; private rpcUrl?: string; private contractId?: string; @@ -382,53 +359,6 @@ export class PaymentStreamClient { ); } - /** - * Fetch and parse history events for a specific stream from the ledger. - * @param streamId The ID of the stream. - * @param opts Optional pagination: startLedger and limit (default 100). - */ - public async getStreamHistory( - streamId: bigint, - opts: { startLedger?: number; limit?: number } = {} - ): Promise { - const server = new SorobanRpc.Server(this.rpcUrl); - const { startLedger = 0, limit = 100 } = opts; - - const response = await server.getEvents({ - startLedger, - filters: [ - { - type: 'contract', - contractIds: [this.contractId], - topics: [['*', `u64:${streamId}`]], - }, - ], - limit, - }); - - return response.events.map((event) => { - const topics = event.topic.map((t) => t.value()); - const eventName = (topics[0] as string).toLowerCase().replace('_event', '') as StreamEventType; - const data: Record = {}; - - try { - const val = event.value.value(); - if (val && typeof val === 'object') { - Object.assign(data, val); - } - } catch { - // non-critical, leave data empty - } - - return { - type: eventName, - streamId, - ledger: event.ledger, - timestamp: event.ledgerClosedAt ? new Date(event.ledgerClosedAt).getTime() / 1000 : 0, - data, - }; - }); - } return getAllStreamHistory( { rpcUrl: this.rpcUrl, diff --git a/packages/sdk/src/__tests__/PaymentStreamClient.test.ts b/packages/sdk/src/__tests__/PaymentStreamClient.test.ts index dccda03..604f71d 100644 --- a/packages/sdk/src/__tests__/PaymentStreamClient.test.ts +++ b/packages/sdk/src/__tests__/PaymentStreamClient.test.ts @@ -13,16 +13,6 @@ const mockTx = (result: unknown = undefined) => ({ signAndSend: mockSignAndSend, }); -const mockGetEvents = vi.fn(); - -vi.mock('@stellar/stellar-sdk', () => ({ - rpc: { - Server: vi.fn().mockImplementation(() => ({ - getEvents: mockGetEvents, - })), - }, -})); - const mockContractClient = { create_stream: vi.fn(), deposit: vi.fn(), @@ -506,55 +496,4 @@ describe("PaymentStreamClient", () => { expect(mockContractClient.initialize).toHaveBeenCalledWith(params); }); }); - - // ── getStreamHistory ─────────────────────────────────────────────────────── - describe('getStreamHistory', () => { - const makeEvent = (name: string, streamId: bigint) => ({ - topic: [{ value: () => name }, { value: () => `u64:${streamId}` }], - value: { value: () => ({ amount: 500n }) }, - ledger: 1000, - ledgerClosedAt: '2024-01-01T00:00:00Z', - }); - - it('queries getEvents with correct contract filter', async () => { - mockGetEvents.mockResolvedValue({ events: [] }); - await client.getStreamHistory(STREAM_ID); - expect(mockGetEvents).toHaveBeenCalledWith( - expect.objectContaining({ - filters: [expect.objectContaining({ contractIds: [VALID_OPTIONS.contractId] })], - }) - ); - }); - - it('returns parsed events for the stream', async () => { - mockGetEvents.mockResolvedValue({ - events: [makeEvent('withdraw_event', STREAM_ID), makeEvent('paused_event', STREAM_ID)], - }); - const history = await client.getStreamHistory(STREAM_ID); - expect(history).toHaveLength(2); - expect(history[0].type).toBe('withdraw'); - expect(history[0].streamId).toBe(STREAM_ID); - expect(history[0].ledger).toBe(1000); - expect(history[1].type).toBe('paused'); - }); - - it('returns empty array when no events exist', async () => { - mockGetEvents.mockResolvedValue({ events: [] }); - const history = await client.getStreamHistory(STREAM_ID); - expect(history).toEqual([]); - }); - - it('respects startLedger and limit options', async () => { - mockGetEvents.mockResolvedValue({ events: [] }); - await client.getStreamHistory(STREAM_ID, { startLedger: 500, limit: 50 }); - expect(mockGetEvents).toHaveBeenCalledWith( - expect.objectContaining({ startLedger: 500, limit: 50 }) - ); - }); - - it('propagates RPC errors', async () => { - mockGetEvents.mockRejectedValue(new Error('RPC error')); - await expect(client.getStreamHistory(STREAM_ID)).rejects.toThrow('RPC error'); - }); - }); }); diff --git a/packages/sdk/src/deployer/ContractDeployer.ts b/packages/sdk/src/deployer/ContractDeployer.ts index 2b59584..07e5f1e 100644 --- a/packages/sdk/src/deployer/ContractDeployer.ts +++ b/packages/sdk/src/deployer/ContractDeployer.ts @@ -1,6 +1,5 @@ import { Keypair, - Transaction, TransactionBuilder, Operation, Networks, @@ -11,7 +10,6 @@ import { Transaction, } from '@stellar/stellar-sdk'; import { Server, Api } from '@stellar/stellar-sdk/rpc'; -import type { DeployerConfig, WasmUploadResult, ContractDeployResult, FeeEstimate, Signer } from './types'; import type { DeployerConfig, WasmUploadResult, @@ -136,14 +134,6 @@ export class ContractDeployer { * Simulate a WASM upload transaction and return the estimated fee and * resource consumption without submitting anything to the network. * - * @param wasm - Compiled contract WASM as a Buffer or Uint8Array. - * @param deployer - Keypair or public key string of the account that will pay. - */ - async estimateUploadFee(wasm: Buffer | Uint8Array, deployer: Keypair | string): Promise { - this.assertValidWasm(wasm); - const address = typeof deployer === 'string' ? deployer : deployer.publicKey(); - const account = await this.loadAccount(address); - const tx = this.buildUploadTx(wasm, account); * @param wasm - Compiled contract WASM as a Buffer or Uint8Array. * @param deployer - Keypair or account address that will pay for the upload. */ @@ -159,18 +149,6 @@ export class ContractDeployer { * Simulate a contract instantiation transaction and return the estimated * fee and resource consumption. * - * @param wasmHash - Hex or base64 hash returned by `uploadWasm`. - * @param deployerOrAddr - Keypair or public key string of the paying account. - * @param salt - Optional 32-byte salt for deterministic contract IDs. - */ - async estimateDeployFee( - wasmHash: string, - deployerOrAddr: Keypair | string, - salt?: Buffer, - ): Promise { - const address = typeof deployerOrAddr === 'string' ? deployerOrAddr : deployerOrAddr.publicKey(); - const account = await this.loadAccount(address); - const tx = this.buildDeployTx(wasmHash, address, account, salt); * @param wasmHash - Hex or base64 hash returned by `uploadWasm`. * @param deployer - Keypair or account address that will pay for the deploy. * @param salt - Optional 32-byte salt for deterministic contract IDs. @@ -194,15 +172,6 @@ export class ContractDeployer { * contract address yet. * * @param wasm - Compiled contract WASM as a Buffer or Uint8Array. - * @param signer - Keypair, array of Keypairs (multi-sig), or signing callback. - * @returns `WasmUploadResult` containing the `wasmHash` needed for deployment. - */ - async uploadWasm(wasm: Buffer | Uint8Array, signer: Signer): Promise { - this.assertValidWasm(wasm); - - const address = this.signerAddress(signer); - const account = await this.loadAccount(address); - const tx = this.buildUploadTx(wasm, account); * @param deployer - Keypair or multi-sig config that signs and pays for the transaction. * @returns `WasmUploadResult` containing the `wasmHash` needed for deployment. */ @@ -213,15 +182,14 @@ export class ContractDeployer { const account = await this.loadAccount(deployerAddress); const tx = await this.buildUploadTx(wasm, account); + // Simulate to get resource footprint, then rebuild with correct fee const estimate = await this.simulate(tx); - const preparedTx = this.buildUploadTx(wasm, account, estimate.fee); - const signedXdr = await this.signTx(preparedTx, signer); const preparedTx = await this.buildUploadTx(wasm, account, estimate.fee); await this.signTransaction(preparedTx, deployer); try { - const result = await this.submitAndWait(signedXdr); + const result = await this.submitAndWait(preparedTx.toEnvelope().toXDR('base64')); return { wasmHash: this.deriveWasmHash(wasm), txHash: result.txHash, @@ -244,25 +212,12 @@ export class ContractDeployer { * Instantiate a previously uploaded WASM as a new contract. * * @param wasmHash - Hex hash returned by `uploadWasm`. - * @param signer - Keypair, array of Keypairs (multi-sig), or signing callback. * @param deployer - Keypair or multi-sig config that signs and pays for the transaction. * @param salt - Optional 32-byte salt for deterministic contract IDs. * @returns `ContractDeployResult` containing the new `contractId`. */ async deployContract( wasmHash: string, - signer: Signer, - salt?: Buffer, - ): Promise { - const address = this.signerAddress(signer); - const account = await this.loadAccount(address); - const estimate = await this.estimateDeployFee(wasmHash, address, salt); - const tx = this.buildDeployTx(wasmHash, address, account, salt, estimate.fee); - const signedXdr = await this.signTx(tx, signer); - - try { - const result = await this.submitAndWait(signedXdr); - const contractId = this.deriveContractId(address, salt ?? result.txHash); deployer: Deployer, salt?: Buffer, ): Promise { @@ -302,13 +257,6 @@ export class ContractDeployer { * Upload the WASM and immediately deploy the contract in two sequential * transactions. Returns both results. * - * @param wasm - Compiled contract WASM. - * @param signer - Keypair, array of Keypairs (multi-sig), or signing callback. - * @param salt - Optional salt for deterministic contract ID. - */ - async uploadAndDeploy( - wasm: Buffer | Uint8Array, - signer: Signer, * @param wasm - Compiled contract WASM. * @param deployer - Keypair or multi-sig config that signs both transactions. * @param salt - Optional salt for deterministic contract ID. @@ -318,45 +266,13 @@ export class ContractDeployer { deployer: Deployer, salt?: Buffer, ): Promise<{ upload: WasmUploadResult; deploy: ContractDeployResult }> { - const upload = await this.uploadWasm(wasm, signer); - const deploy = await this.deployContract(upload.wasmHash, signer, salt); + const upload = await this.uploadWasm(wasm, deployer); + const deploy = await this.deployContract(upload.wasmHash, deployer, salt); return { upload, deploy }; } // ─── Private: transaction builders ──────────────────────────────────────── - /** Resolve the source account address from any supported signer type. */ - private signerAddress(signer: Signer): string { - if (typeof signer === 'function') { - throw new DeployerError( - 'A SigningCallback cannot provide a public key. Pass the deployer address separately or use a Keypair.', - 'SIGNER_ADDRESS_UNKNOWN', - ); - } - return Array.isArray(signer) ? signer[0].publicKey() : signer.publicKey(); - } - - /** - * Sign a built transaction with the provided signer and return the signed XDR. - * - Single Keypair: signs directly. - * - Keypair[]: each keypair signs in order (multi-sig). - * - SigningCallback: delegates to the callback (e.g. browser wallet). - */ - private async signTx( - tx: ReturnType, - signer: Signer, - ): Promise { - if (typeof signer === 'function') { - return signer(tx.toEnvelope().toXDR('base64')); - } - const keypairs = Array.isArray(signer) ? signer : [signer]; - for (const kp of keypairs) { - tx.sign(kp); - } - return tx.toEnvelope().toXDR('base64'); - } - - private buildUploadTx( private async buildUploadTx( wasm: Buffer | Uint8Array, account: { id: string; sequenceNumber: () => string }, diff --git a/packages/sdk/src/deployer/types.ts b/packages/sdk/src/deployer/types.ts index 16539dc..6d4cd59 100644 --- a/packages/sdk/src/deployer/types.ts +++ b/packages/sdk/src/deployer/types.ts @@ -66,20 +66,6 @@ export type Deployer = Keypair | DeployerAccount; */ export type StellarNetwork = 'testnet' | 'mainnet' | 'custom'; -/** - * A callback that receives a transaction XDR string, signs it externally - * (e.g. via a browser wallet), and returns the signed XDR string. - */ -export type SigningCallback = (txXdr: string) => Promise; - -/** - * Accepted signer types for upload/deploy operations: - * - A single `Keypair` (original behaviour) - * - An array of `Keypair`s for multi-sig (each one signs in order) - * - A `SigningCallback` for wallet-based or custom signing flows - */ -export type Signer = import('@stellar/stellar-sdk').Keypair | import('@stellar/stellar-sdk').Keypair[] | SigningCallback; - /** * Configuration options for the ContractDeployer. * diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index b9508e3..3a21f8d 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -23,9 +23,6 @@ export { } from "./generated/distributor/src/index"; // Export high-level clients -export * from './PaymentStreamClient'; -export type { StreamHistoryEvent, StreamEventType } from './PaymentStreamClient'; -export * from './DistributorClient'; export * from "./PaymentStreamClient"; export * from "./DistributorClient";