Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
@interledger/open-payments
Advanced tools
Open Payments is an API standard that allows third-parties (with the account holder's consent) to initiate payments and to view the transaction history on the account holder's account.
Open Payments consists of two OpenAPI specifications, a resource server which exposes APIs for performing functions against the underlying accounts and an authorization server which exposes APIs compliant with the GNAP standard for getting grants to access the resource server APIs.
This package provides TypeScript & NodeJS tools for using Open Payments:
This package could be used by (but not limited to):
You can install the Open Payments package using:
npm install @interledger/open-payments
This package exports two clients, an UnauthenticatedClient
and an AuthenticatedClient
.
UnauthenticatedClient
This client allows making requests to access publicly available resources, without needing authentication. The three available resources are Payment Pointers, Payment Pointer Keys, and ILP Stream Connections.
import { createUnauthenticatedClient } from '@interledger/open-payments'
const client = await createUnauthenticatedClient({
requestTimeoutMs: 1000, // optional, defaults to 5000
logger: customLoggerInstance // optional, defaults to pino logger
})
const paymentPointer = await client.paymentPointer.get({
url: 'https://cloud-nine-wallet/alice'
})
AuthenticatedClient
An AuthenticatedClient
provides all of the methods that UnauthenticatedClient
does, as well as the rest of the Open Payment APIs (both the authorizaton and resource specs). Each request requiring authentication will be signed (using HTTP signatures) with the given private key.
import { createAuthenticatedClient } from '@interledger/open-payments'
const client = await createAuthenticatedClient({
keyId: KEY_ID,
privateKey: PRIVATE_KEY,
paymentPointerUrl: PAYMENT_POINTER_URL
})
In order to create the client, three properties need to be provided: keyId
, the privateKey
and the paymentPointerUrl
:
Variable | Description |
---|---|
paymentPointerUrl | The valid payment pointer with which the client making requests will identify itself. A JSON Web Key Set document that includes the public key that the client instance will use to protect requests MUST be available at the {paymentPointerUrl}/jwks.json url. This will be used as the client field during Grant Creation. |
privateKey | The private EdDSA-Ed25519 key bound to the payment pointer, and used to sign the authenticated requests with. As mentioned above, a public JWK document signed with this key MUST be available at the {paymentPointerUrl}/jwks.json url. |
keyId | The key identifier of the given private key and the corresponding public JWK document. |
Note
To simplify EdDSA-Ed25519 key provisioning and JWK generation, you can use the
parseOrProvisionKey
andgenerateJwk
methods from thehttp-signature-utils
package.
As mentioned previously, Open Payments APIs can facilitate a payment between two parties.
For example, say Alice wants to purchase a $50 product from a merchant called Shoe Shop on the Online Marketplace. If both parties have Open Payments enabled wallets, where Alice's payment pointer is https://cloud-nine-wallet/alice
, and Shoe Shop's is https://happy-life-bank/shoe-shop
, requests during checkout from Online Marketplace's backend would look like this using the client:
In this case, since Online Marketplace wants to make requests that require authorization, it will need to create an AuthenticatedClient
:
import { createAuthenticatedClient } from '@interledger/open-payments'
const client = await createAuthenticatedClient({
paymentPointerUrl: 'https://online-marketplace.com/usa',
keyId: KEY_ID,
privateKey: PRIVATE_KEY
// The public JWK with this key (and keyId) would be available at https://online-marketplace.com/usa/jwks.json
})
PaymentPointers
Grab the payment pointers of the parties:
const shoeShopPaymentPointer = await client.paymentPointer.get({
url: 'https://happy-life-bank/shoe-shop'
})
const customerPaymentPointer = await client.paymentPointer.get({
url: 'https://cloud-nine-wallet/alice'
})
IncomingPayment
Online Marketplace's backend gets a grant to create an IncomingPayment
on the merchant's wallet:
const incomingPaymentGrant = await client.grant.request(
{ url: shoeShopPaymentPointer.authServer },
{
access_token: {
access: [
{
type: 'incoming-payment',
actions: ['read-all', 'create']
}
]
}
}
)
and creates an IncomingPayment
using the access token from the grant:
const incomingPayment = await client.incomingPayment.create(
{
paymentPointer: shoeShopPaymentPointer.authServer,
accessToken: incomingPaymentGrant.access_token.value
},
{
incomingAmount: {
assetCode: 'USD',
assetScale: 2,
value: '5000'
},
description: 'Purchase at Shoe Shop',
externalRef: '#INV2022-8363828'
}
)
Quote
Then, it'll get a grant to create a Quote
on Alice's payment pointer, which will give the amount it'll cost Alice to make the payment (with the ILP fees + her wallet's fees)
const quoteGrant = await client.grant.request(
{ url: customerPaymentPointer.authServer },
{
access_token: {
access: [
{
type: 'quote',
actions: ['create', 'read']
}
]
}
}
)
const quote = await client.quote.create(
{
paymentPointer: customerPaymentPointer.id,
accessToken: quoteGrant.access_token.value
},
{ receiver: incomingPayment.id }
)
// quote.sendAmount.value = '5200'
OutgoingPayment
grant & start interaction flow:The final step for Online Marketplace's backend system will be to create an OutgoingPayment
on Alice's wallet. Before this, however, Online Marketplace will need to create an outgoing payment grant, which typically requires some sort of interaction with Alice. Online Marketplace will need to facilitate this interaction with Alice (e.g. redirect her to a webpage with a dialog) to get her consent for creating an OutgoingPayment
on her account. The detailed sequence for how this is achieved can be found here.
OutgoingPayment
:Once the grant interaction flow has finished, and Alice has consented to the payment, Online Marketplace can create the OutgoingPayment
on her account:
const outgoingPayment = await client.outgoingPayment.create(
{
paymentPointer: customerPaymentPointer.id,
accessToken: outgoingPaymentGrant.access_token.value
},
{ quoteId: quote.id, description: 'Your purchase at Shoe Shop' }
)
At this point, the Online Marketplace can show to Alice that the payment to Shoe Shop has been completed.
FAQs
Tools for interacting with the Open Payments API
We found that @interledger/open-payments demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.