We refreshed our doc site!
Bookmarked links may have changed
Read release notesThis quickstart guide helps you quickly set up notifications for Programmable Wallets. Follow this to configure a subscriber endpoint that sends a notification every time the status of resource changes.
This guide focuses on the challenge resource but applies to any resources available in Programmable Wallet Notifications.
To receive notifications on changes in resource status, you must expose a publicly accessible subscriber endpoint on your side. The endpoint must handle both HEAD
and POST requests over HTTPS.
To quickly expose an endpoint for testing, we will use webhook.site in this guide, which allows you to easily inspect, test and automate any incoming HTTPS request or e-mail directly in a web browser.
When visiting webhook.site for the first time, you should see a status message that looks like the following:
Your unique URL (Please copy it from here, not from the address bar!) https://webhook.site/83fa21a0-f00a-4673-bb50-bcf62c78b1f7
Record the value of the unique URL.
In the example above, the unique URL is:https://webhook.site/83fa21a0-f00a-4673-bb50-bcf62c78b1f7
. Use the public-facing URL you receive as you progress throughout this guide.
Now that you have a publicly accessible endpoint, you need to register your endpoint as a subscriber to webhook notifications by doing the following:
https://webhook.site/83fa21a0-f00a-4673-bb50-bcf62c78b1f7
.{
"subscriptionId": "00000000-0000-0000-0000-000000000000",
"notificationId": "00000000-0000-0000-0000-000000000000",
"notificationType": "webhooks.test",
"notification": {
"hello": "world"
},
"timestamp": "2023-07-20T16:18:40.816010685Z",
"version": 2
}
Now you have a sample local environment ready to receive transaction and challenge status change notifications. Note that in testnet and mainnet there is a limit of 20 webhook notifications each.
You can customize your webhook notifications. Customized webhook notifications allow you to listen to a restricted set of specific events, such as inbound transactions only, or a specific set of events, such as transaction or challenges, through a URL endpoint on your receiving application.
To customize your endpoints to only receive certain notifications, toggle on “Limit to specific events” when creating your webhook.
You are then able to pick the event categories that you want to listen to on your endpoint. These can be further customized at the event level under each category. This gives you the flexibility to only listen to events you care about at each endpoint, rather than overwhelming the endpoint with all notifications. This reduces the amount of data your server needs to process, making it more efficient and easier to manage. It also helps in focusing only on the relevant events, which can improve the performance and reliability of your application.
To observe a notification message on the status of a challenge, initiate the creation of a wallet (for example, by following the Programmable Wallets User-Controlled Wallets Tutorial for creating a user-controlled wallet).
Once you successfully initiate a challenge payment, you should see a notification message on your local server shell that looks like the following:
Sample Challenge Notification:
{
"subscriptionId": "a68cd974-d209-46cd-8dbf-b7a081fbd627",
"notificationId": "eaa4a4fe-24b8-4329-a4c6-6dfd557dbcb2",
"notificationType": "challenges.initialize",
"notification": {
"id": "9c0a1991-735a-5140-8996-7b95720c5e55",
"userId": "2a054cd1-3124-4aa7-b1f0-86c4a4df995c",
"type": "INITIALIZE",
"status": "COMPLETE",
"correlationIds": [
"01890792-a199-77bc-b005-b229f81824fa"
],
"errorCode": 0,
"errorMessage": ""
},
"timestamp": "2023-06-29T14:33:17.785131449Z",
"version": 2
}
X-Circle-Signature
: a header containing the digital signature generated by CircleX-Circle-Key-Id
: a header containing the UUID you need to retrieve the relevant public key# Headers
`X-Circle-Key-Id: “879dc113-5ca4-4ff7-a6b7-54652083fcf8”`
`X-Circle-Signature: “MEYCIQCA9EvPbdEJiy7Cw0eY+KQZA/oFi5ZEInPs8CYpyaJexgIhAKtRNnDz9QRQmFKx8QFrvawp+8b9Bs2dQ03xD+XaWVDE”`
GET /v2/notifications/publicKey/{keyId)
# Replace ${YOUR_API_KEY} with your API key
# Replace ${PUBLIC_KEY_ID} with your public key id
curl --request GET \
--url 'https://api.circle.com/v2/notifications/publicKey/${PUBLIC_KEY_ID)' \
--header 'accept: application/json' \
--header 'authorization: Bearer $ENV_API_KEY:ID:SECRET$' \
If successful, you will receive a response with the following shape
{
"data": {
"id": "879dc113-5ca4-4ff7-a6b7-54652083fcf8",
"algorithm": "ECDSA_SHA_256",
"publicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAESl76SZPBJemW0mJNN4KTvYkLT8bOT4UGhFhzNk3fJqf6iuPlLQLq533FelXwczJbjg2U1PHTvQTK7qOQnDL2Tg==",
"createDate": "2023-06-28T21:47:35.107250Z"
}
}
X-Circle-Signature
.Note: Please make sure the webhook notification is properly formatted JSON string prior to verifying it
{
"subscriptionId": "890a8cae-46bd-40ad-bd7f-2e49b8dea9da",
"notificationId": "0bdd3e4b-5070-4530-8ed4-2e2e4c9fd2f0",
"notificationType": "webhooks.test",
"notification": {
"hello": "world"
},
"timestamp": "2023-07-12T04: 02: 28.555562821Z",
"version": 2
}
The following code sample demonstrates how to verify the X-Circle-Signature
:
import base64
import json
from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import ec
# Load the public key from the base64 encoded string
public_key_base64 = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAESl76SZPBJemW0mJNN4KTvYkLT8bOT4UGhFhzNk3fJqf6iuPlLQLq533FelXwczJbjg2U1PHTvQTK7qOQnDL2Tg=="
public_key_bytes = base64.b64decode(public_key_base64)
public_key = serialization.load_der_public_key(public_key_bytes)
# Load the signature you want to verify
signature_base64 = "MEQCIBlJPX7t0FDOcozsRK6qIQwik5Fq6mhAtCSSgIB/yQO7AiB9U5lVpdufKvPhk3cz4TH2f5MP7ArnmPRBmhPztpsIFQ=="
signature_bytes = base64.b64decode(signature_base64)
# Load and format the message you want to verify
message = "{\n\"subscriptionId\":\"00000000-0000-0000-0000-000000000000\",\"notificationId\":\"00000000-0000-0000-0000-000000000000\",\"notificationType\":\"webhooks.test\",\"notification\":{\"hello\":\"world\"},\"timestamp\":\"2024-01-26T18:22:19.779834211Z\",\"version\":2}"
json_data = json.loads(message)
formatted_json = json.dumps(json_data, separators=(',', ':'))
# Verify the signature
try:
public_key.verify(
signature_bytes,
formatted_json.encode(),
ec.ECDSA(hashes.SHA256())
)
print("Signature is valid.")
except InvalidSignature:
print("Signature is invalid.")
To ensure the security of your integration, only trust Circle webhook notifications from the following IP addresses.
54.243.112.156
100.24.191.35
54.165.52.248
54.87.106.46
Webhook notification handling
We enforce a 5 second timeout for your endpoint to respond back to our webhook notifications. It is highly recommended that you process notifications outside of the response loop and respond back promptly.
WHAT'S NEXT Congratulations, you have received your first notification for a Programmable Wallets challenge!