JavaScript SDK for connecting to Kontist using OAuth2 and GraphQL. Please see https://kontist.dev/sdk for a more complete documentation.
Add as dependency to your project:
npm install kontist
You will need a valid client id and setup your redirect uri for authentication. You may request your client id in the API Client Management on https://kontist.dev/client-management/.
import express from "express";
import { Client } from "kontist";
const CALLBACK_PATH = "/auth/callback";
const REDIRECT_URI = <YOUR_BASE_URL> + CALLBACK_PATH;
const clientSecret = <YOUR_CLIENT_SECRET>;
const state = (Math.random() + "").substring(2);
const app = express();
// create a client
const client = new Client({
clientId: "YOUR_CLIENT_ID",
redirectUri: REDIRECT_URI,
scopes: ["transactions"],
clientSecret,
state
});
// redirect not authenticated user to Kontist form
app.get("/auth", async (req, res) => {
const uri = await client.auth.tokenManager.getAuthUri();
res.redirect(uri);
});
// get user token data
app.get(CALLBACK_PATH, async (req, res) => {
const callbackUrl = req.originalUrl;
try {
const token = await client.auth.tokenManager.fetchToken(callbackUrl);
/* got access token, login successful */
res.send("Successful, your token is " + token.accessToken);
} catch (e) {
/* handle error */
res.send("Failed: " + JSON.stringify(e));
}
});
app.listen(3000, function() {
console.log("Listening on port 3000!");
});
You should be able to issue new accessToken by simply calling:
const token = await client.auth.tokenManager.refresh();
Optionally, this method accepts a number as an argument to specify after how many milliseconds the refresh request should timeout (default is 10000):
// abort after 20 seconds
const token = await client.auth.tokenManager.refresh(20000);
Note: to create a client that can handle public request, you need to initialize Client
without clientId
.
const client = new Client({
scopes: ["transactions"],
state
});
<html>
<body>
<script src="https://cdn.kontist.com/sdk.min.js"></script>
<script>
// persist a random value
sessionStorage.setItem(
"state",
sessionStorage.getItem("state") || (Math.random() + "").substring(2)
);
sessionStorage.setItem(
"verifier",
sessionStorage.getItem("verifier") || (Math.random() + "").substring(2)
);
// initialize Kontist client
const client = new Kontist.Client({
clientId: "<your client id>",
redirectUri: "<your base url>",
scopes: ["transactions"],
state: sessionStorage.getItem("state"),
verifier: sessionStorage.getItem("verifier")
});
const params = new URL(document.location).searchParams;
const code = params.get("code");
if (!code) {
// page not called with "code" query parameter, let's redirect the user to the login
client.auth.tokenManager.getAuthUri().then(function(url) {
window.location = url;
});
} else {
// we have a code, the client now can fetch a token
client.auth.tokenManager.fetchToken(document.location.href).then(function() {
// do a simple graphql query and output the account id
client.graphQL
.rawQuery(
`{
viewer {
mainAccount {
iban
balance
}
}
}`
)
.then(function(result) {
console.log(result);
});
});
}
</script>
</body>
</html>
Kontist SDK allows renewing access tokens in browser environments using this simple method:
const token = await client.auth.tokenManager.refresh();
Optionally, this method accepts a number as an argument to specify after how many milliseconds the refresh request should timeout (default is 10000):
// abort after 20 seconds
const token = await client.auth.tokenManager.refresh(20000);
const query = `{
viewer {
mainAccount {
id
}
}
}`;
const result = await client.graphQL.rawQuery(query);
An example to show how to fetch all user transactions:
let transactions = [];
for await (const transaction of client.models.transaction.fetchAll()) {
transactions = transactions.concat(transaction);
}
To fetch up to 50 latest transactions:
const transactions = await client.models.transaction.fetch();
To subscribe to new transactions:
const onNext = transaction => {
// do something with the transaction
}
const onError = error => {
// do something with the error
}
client.models.transaction.subscribe(onNext, onError);
Whenever a new transaction is created, the onNext
function will be called.
Whenever an error occurs with the subscription, the onError
function will be called.
The subscribe
method returns a Subscription
object with an unsubscribe
method to be called when you want to unsubscribe to new transactions:
const { unsubscribe } = client.models.transaction.subscribe(onNext, onError);
// ...
unsubscribe();
// after this point, onNext / onError will no longer be called when new transactions / errors are received
To create and confirm a transfer / timed order / standing order:
const confirmationId = await client.models.transfer.createOne({
amount: <amount>,
recipient: <recipent_name>,
iban: <recipent_iban>,
purpose: <optional_description>,
e2eId: <optional_e2eId>,
executeAt: <optional_order_execution_date> // mandatory for timed and standing order
lastExecutionDate: <optional_last_execution_date> // optional for standing order
reoccurrence: <optional_order_reoccurrence> // mandatory for standing order
});
// wait for sms
const smsToken = ...
const result = await client.models.transfer.confirmOne(
confirmationId,
smsToken
);
To create and confirm multiple transfers (with only one confirmation):
const confirmationId = await client.models.transfer.createMany([{
amount: <amount>,
recipient: <recipent_name>,
iban: <recipent_iban>,
purpose: <optional_description>,
e2eId: <optional_e2eId>,
}, {
amount: <amount>,
recipient: <recipent_name>,
iban: <recipent_iban>,
purpose: <optional_description>,
e2eId: <optional_e2eId>,
}]);
// wait for sms
const smsToken = ...
const result = await client.models.transfer.confirmMany(
confirmationId,
smsToken
);
An example to show how to fetch all user transfers of a given type:
let transfers = [];
for await (const transfer of client.models.transfer.fetchAll({
type: Schema.TransferType.SepaTransfer
})) {
transfers = transfers.concat(transfer);
}
To fetch up to 50 latest transfers of a given type:
const transfers = await client.models.transfer.fetch({
type: Schema.TransferType.TimedOrder
});
Several methods are available to create, manage and fetch cards.
Here is an example of how to create a new card for a user:
const card = await client.models.card.create({
type: CardType.VisaBusinessDebit
});
And here is how you can retrieve the details of existing cards:
const result = await client.models.card.fetch();
Accessing Kontist banking APIs require Multi-Factor Authentication (MFA).
MFA is available once you have installed the Kontist application and paired your device in it.
The following steps are necessary to complete the MFA procedure:
- initiate the procedure by creating a challenge (Kontist SDK exposes a method to do that)
- click the push notification you received on your phone, it will open the Kontist application
- login (if applicable) and confirm the MFA by clicking on the corresponding button
Kontist SDK exposes a method to initiate the push notification MFA flow after you successfully received the initial access token:
// fetch a regular access token
const token = await client.auth.tokenManager.fetchToken(callbackUrl);
try {
// create a push notification challenge and wait for confirmation
const confirmedToken = await client.auth.push.getConfirmedToken();
// once it has been verified, your `client` instance will have a confirmed access token
// the confirmed token is also returned in case you want to store it
} catch (err) {
// if the challenge expires, a `ChallengeExpiredError` will be thrown
// if the challenge is denied, a `ChallengeDeniedError` will be thrown
console.log(err);
}
After obtaining a confirmed auth token with this method, you will have access to all banking APIs.
If you want to cancel a pending push notification confirmation, you can call the following method:
client.auth.push.cancelConfirmation();
The Promise returned by getConfirmedToken
will then reject with a MFAConfirmationCanceledError
.