Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add payment channel updated stream to ts rpc client #1803

Merged
merged 11 commits into from
Oct 5, 2023
16 changes: 14 additions & 2 deletions node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,20 @@ func (n *Node) ReceivedVouchers() <-chan payments.Voucher {

// CreateVoucher creates and returns a voucher for the given channelId which increments the redeemable balance by amount.
// It is the responsibility of the caller to send the voucher to the payee.
func (c *Node) CreateVoucher(channelId types.Destination, amount *big.Int) (payments.Voucher, error) {
return c.vm.Pay(channelId, amount, *c.store.GetChannelSecretKey())
func (n *Node) CreateVoucher(channelId types.Destination, amount *big.Int) (payments.Voucher, error) {
voucher, err := n.vm.Pay(channelId, amount, *n.store.GetChannelSecretKey())
if err != nil {
return payments.Voucher{}, err
}
info, err := n.GetPaymentChannel(channelId)
if err != nil {
return voucher, err
}
err = n.channelNotifier.NotifyPaymentUpdated(info)
if err != nil {
return voucher, err
}
return voucher, nil
}

// ReceiveVoucher receives a voucher and returns the amount that was paid.
Expand Down
141 changes: 141 additions & 0 deletions packages/nitro-rpc-client/src/interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import {
LedgerChannelInfo,
ObjectiveResponse,
PaymentChannelInfo,
PaymentPayload,
ReceiveVoucherResult,
Voucher,
} from "./types";

interface ledgerChannelApi {
/**
* CreateLedgerChannel creates a directly funded ledger channel with the counterparty.
*
* @param counterParty - The counterparty to create the channel with
* @returns A promise that resolves to an objective response, containing the ID of the objective and the channel id.
*/
CreateLedgerChannel(
counterParty: string,
amount: number
): Promise<ObjectiveResponse>;
/**
* CloseLedgerChannel defunds a directly funded ledger channel.
*
* @param channelId - The ID of the channel to defund
* @returns The ID of the objective that was created
*/
CloseLedgerChannel(channelId: string): Promise<string>;
/**
* GetLedgerChannel queries the RPC server for a payment channel.
*
* @param channelId - The ID of the channel to query for
* @returns A `LedgerChannelInfo` object containing the channel's information
*/
GetLedgerChannel(channelId: string): Promise<LedgerChannelInfo>;
/**
* GetAllLedgerChannels queries the RPC server for all ledger channels.
* @returns A `LedgerChannelInfo` object containing the channel's information for each ledger channel
*/
GetAllLedgerChannels(): Promise<LedgerChannelInfo[]>;
}
interface paymentChannelApi {
/**
* CreatePaymentChannel creates a virtually funded payment channel with the counterparty, using the given intermediaries.
*
* @param counterParty - The counterparty to create the channel with
* @param intermediaries - The intermerdiaries to use
* @returns A promise that resolves to an objective response, containing the ID of the objective and the channel id.
*/
CreatePaymentChannel(
counterParty: string,
intermediaries: string[],
amount: number
): Promise<ObjectiveResponse>;
/**
* ClosePaymentChannel defunds a virtually funded payment channel.
*
* @param channelId - The ID of the channel to defund
* @returns The ID of the objective that was created
*/
ClosePaymentChannel(channelId: string): Promise<string>;
/**
* GetPaymentChannel queries the RPC server for a payment channel.
*
* @param channelId - The ID of the channel to query for
* @returns A `PaymentChannelInfo` object containing the channel's information
*/
GetPaymentChannel(channelId: string): Promise<PaymentChannelInfo>;
/**
* GetPaymentChannelsByLedger queries the RPC server for any payment channels that are actively funded by the given ledger.
*
* @param ledgerId - The ID of the ledger to find payment channels for
* @returns A `PaymentChannelInfo` object containing the channel's information for each payment channel
*/
GetPaymentChannelsByLedger(ledgerId: string): Promise<PaymentChannelInfo[]>;
}

interface paymentApi {
/**
* Creates a payment voucher for the given channel and amount.
* The voucher does not get sent to the other party automatically.
* @param channelId The payment channel to use for the voucher
* @param amount The amount for the voucher
* @returns A signed voucher
*/
CreateVoucher(channelId: string, amount: number): Promise<Voucher>;
/**
* Adds a voucher to the go-nitro node that was received from the other party to the channel.
* @param voucher The voucher to add
* @returns The total amount of the channel and the delta of the voucher
*/
ReceiveVoucher(voucher: Voucher): Promise<ReceiveVoucherResult>;
/**
* Pay sends a payment on a virtual payment chanel.
*
* @param channelId - The ID of the payment channel to use
* @param amount - The amount to pay
*/
Pay(channelId: string, amount: number): Promise<PaymentPayload>;
}

interface syncAPI {
/**
* WaitForObjective blocks until the objective with the given ID to complete.
*
* @param objectiveId - The id objective to wait for
*/
WaitForObjective(objectiveId: string): Promise<void>;
/**
* PaymentChannelUpdated attaches a callback which is triggered when the channel with supplied ID is updated.
* Returns a cleanup function which can be used to remove the subscription.
*
* @param objectiveId - The id objective to wait for
*/
onPaymentChannelUpdated(
channelId: string,
callback: (info: PaymentChannelInfo) => void
): () => void;
}

export interface RpcClientApi
extends ledgerChannelApi,
paymentChannelApi,
paymentApi,
syncAPI {
/**
* GetVersion queries the API server for it's version.
*
* @returns The version of the RPC server
*/
GetVersion(): Promise<string>;
/**
* GetAddress queries the RPC server for it's state channel address.
*
* @returns The address of the wallet connected to the RPC server
*/
GetAddress(): Promise<string>;
/**
* Close closes the RPC client and stops listening for notifications.
*/
Close(): Promise<void>;
}
102 changes: 18 additions & 84 deletions packages/nitro-rpc-client/src/rpc-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ import { Transport } from "./transport";
import { createOutcome, generateRequest } from "./utils";
import { HttpTransport } from "./transport/http";
import { getAndValidateResult } from "./serde";
import { RpcClientApi } from "./interface";

export class NitroRpcClient {
export class NitroRpcClient implements RpcClientApi {
private transport: Transport;

// We fetch the address from the RPC server on first use
Expand All @@ -29,13 +30,6 @@ export class NitroRpcClient {
return this.transport.Notifications;
}

/**
* Creates a payment voucher for the given channel and amount.
* The voucher does not get sent to the other party automatically.
* @param channelId The payment channel to use for the voucher
* @param amount The amount for the voucher
* @returns A signed voucher
*/
public async CreateVoucher(
channelId: string,
amount: number
Expand All @@ -53,11 +47,6 @@ export class NitroRpcClient {
return getAndValidateResult(res, "create_voucher");
}

/**
* Adds a voucher to the go-nitro node that was received from the other party to the channel.
* @param voucher The voucher to add
* @returns The total amount of the channel and the delta of the voucher
*/
public async ReceiveVoucher(voucher: Voucher): Promise<ReceiveVoucherResult> {
const request = generateRequest(
"receive_voucher",
Expand All @@ -68,11 +57,6 @@ export class NitroRpcClient {
return getAndValidateResult(res, "receive_voucher");
}

/**
* WaitForObjective blocks until the objective with the given ID to complete.
*
* @param objectiveId - The id objective to wait for
*/
public async WaitForObjective(objectiveId: string): Promise<void> {
return new Promise((resolve) => {
this.transport.Notifications.on(
Expand All @@ -86,12 +70,21 @@ export class NitroRpcClient {
});
}

/**
* CreateLedgerChannel creates a directly funded ledger channel with the counterparty.
*
* @param counterParty - The counterparty to create the channel with
* @returns A promise that resolves to an objective response, containing the ID of the objective and the channel id.
*/
public onPaymentChannelUpdated(
channelId: string,
callback: (info: PaymentChannelInfo) => void
): () => void {
const wrapperFn = (info: PaymentChannelInfo) => {
if (info.ID.toLowerCase() == channelId.toLowerCase()) {
callback(info);
}
};
this.transport.Notifications.on("payment_channel_updated", wrapperFn);
return () => {
this.transport.Notifications.off("payment_channel_updated", wrapperFn);
};
}

public async CreateLedgerChannel(
counterParty: string,
amount: number
Expand All @@ -113,13 +106,6 @@ export class NitroRpcClient {
return this.sendRequest("create_ledger_channel", payload);
}

/**
* CreatePaymentChannel creates a virtually funded payment channel with the counterparty, using the given intermediaries.
*
* @param counterParty - The counterparty to create the channel with
* @param intermediaries - The intermerdiaries to use
* @returns A promise that resolves to an objective response, containing the ID of the objective and the channel id.
*/
public async CreatePaymentChannel(
counterParty: string,
intermediaries: string[],
Expand All @@ -143,12 +129,6 @@ export class NitroRpcClient {
return this.sendRequest("create_payment_channel", payload);
}

/**
* Pay sends a payment on a virtual payment chanel.
*
* @param channelId - The ID of the payment channel to use
* @param amount - The amount to pay
*/
public async Pay(channelId: string, amount: number): Promise<PaymentPayload> {
const payload = {
Amount: amount,
Expand All @@ -159,42 +139,20 @@ export class NitroRpcClient {
return getAndValidateResult(res, "pay");
}

/**
* CloseLedgerChannel defunds a directly funded ledger channel.
*
* @param channelId - The ID of the channel to defund
* @returns The ID of the objective that was created
*/
public async CloseLedgerChannel(channelId: string): Promise<string> {
const payload: DefundObjectiveRequest = { ChannelId: channelId };
return this.sendRequest("close_ledger_channel", payload);
}
/**
* ClosePaymentChannel defunds a virtually funded payment channel.
*
* @param channelId - The ID of the channel to defund
* @returns The ID of the objective that was created
*/

public async ClosePaymentChannel(channelId: string): Promise<string> {
const payload: DefundObjectiveRequest = { ChannelId: channelId };
return this.sendRequest("close_payment_channel", payload);
}

/**
* GetVersion queries the API server for it's version.
*
* @returns The version of the RPC server
*/
public async GetVersion(): Promise<string> {
return this.sendRequest("version", {});
}

/**
* GetAddress queries the RPC server for it's state channel address.
*
* @returns The address of the wallet connected to the RPC server
*/
public async GetAddress(): Promise<string> {
if (this.myAddress) {
return this.myAddress;
Expand All @@ -204,41 +162,20 @@ export class NitroRpcClient {
return this.myAddress;
}

/**
* GetLedgerChannel queries the RPC server for a payment channel.
*
* @param channelId - The ID of the channel to query for
* @returns A `LedgerChannelInfo` object containing the channel's information
*/
public async GetLedgerChannel(channelId: string): Promise<LedgerChannelInfo> {
return this.sendRequest("get_ledger_channel", { Id: channelId });
}

/**
* GetAllLedgerChannels queries the RPC server for all ledger channels.
* @returns A `LedgerChannelInfo` object containing the channel's information for each ledger channel
*/
public async GetAllLedgerChannels(): Promise<LedgerChannelInfo[]> {
return this.sendRequest("get_all_ledger_channels", {});
}

/**
* GetPaymentChannel queries the RPC server for a payment channel.
*
* @param channelId - The ID of the channel to query for
* @returns A `PaymentChannelInfo` object containing the channel's information
*/
public async GetPaymentChannel(
channelId: string
): Promise<PaymentChannelInfo> {
return this.sendRequest("get_payment_channel", { Id: channelId });
}
/**
* GetPaymentChannelsByLedger queries the RPC server for any payment channels that are actively funded by the given ledger.
*
* @param ledgerId - The ID of the ledger to find payment channels for
* @returns A `PaymentChannelInfo` object containing the channel's information for each payment channel
*/

public async GetPaymentChannelsByLedger(
ledgerId: string
): Promise<PaymentChannelInfo[]> {
Expand All @@ -260,9 +197,6 @@ export class NitroRpcClient {
return getAndValidateResult(res, method);
}

/**
* Close closes the RPC client and stops listening for notifications.
*/
public async Close(): Promise<void> {
return this.transport.Close();
}
Expand Down
Loading