Circle USYC 백서

Circle USYC

원문

bitpro가 원문에서 글자만 모은 내용이에요. 표·그림·수식은 빠지거나 깨질 수 있어요. 전체 75쪽 중 19쪽

*` | 20 | | `POST` | `/v1/exchange/stablefx/fund` | 20 | | `GET` | `/v1/exchange/stablefx/fees/{tradeId}` | 30 | | `POST` | `/v1/exchange/stablefx/notifications` | 50 | # How-to: Verify webhook signatures Source: https://developers.circle.com/api-reference/verify-webhook-signatures Confirm that a webhook notification was sent by Circle by verifying its digital signature. Every [v2 webhook notification](/api-reference/webhooks#notification-api-versions) sent by Circle (Circle Wallets, Circle Contracts, CPN payments, Digital Asset Accounts, Gateway, StableFX) is signed with an asymmetric key. By verifying the signature on each notification, you confirm the payload came from Circle and wasn't tampered with in transit. The verification flow is the same across these products. Only the public key endpoint differs per product. <Note> v1 notifications (Circle Mint, CPN Managed Payments) use a different signature scheme. Contact your [Circle representative](mailto:sales@circle.com) for details. </Note> ## Signature scheme Circle signs each v2 webhook notification with the `ECDSA_SHA_256` algorithm. Every notification includes two headers your endpoint uses to verify the signature: * `X-Circle-Signature`: the digital signature of the notification body, base64-encoded. * `X-Circle-Key-Id`: the UUID of the public key that signed the notification. Each signature is unique to the notification it accompanies, so run the verification flow below for every webhook you receive. ## Verify a signature <Steps> <Step title="Read the signature and key ID from the headers"> Extract `X-Circle-Signature` and `X-Circle-Key-Id` from the incoming webhook request's headers. ```text theme={null} X-Circle-Key-Id: 879dc113-5ca4-4ff7-a6b7-54652083fcf8 X-Circle-Signature: MEYCIQCA9EvPbdEJiy7Cw0eY+KQZA/oFi5ZEInPs8CYpyaJexgIhAKtRNnDz9QRQmFKx8QFrvawp+8b9Bs2dQ03xD+XaWVDE ``` </Step> <Step title="Fetch the public key"> Using the value of `X-Circle-Key-Id`, call your product's public key endpoint to retrieve the public key and algorithm. Replace `<public_key_endpoint>` with the endpoint for your product: * [Wallets](/api-reference/wallets/common/get-notification-signature), [Contracts](/api-reference/contracts/common/get-notification-signature), [Gateway](/api-reference/gateway/all/get-permissionless-notification-signature), and Digital Asset Accounts: `/v2/notifications/publicKey/{keyId}` * [CPN](/api-reference/cpn/common/get-notification-signature): `/v2/cpn/notifications/publicKey/{keyId}` * [StableFX](/api-reference/stablefx/all/get-notification-signature): `/v2/stablefx/notifications/publicKey/{id}` ```bash theme={null} curl --request GET \ --url 'https://api.circle.com/<public_key_endpoint>/879dc113-5ca4-4ff7-a6b7-54652083fcf8' \ --header 'Authorization: Bearer $CIRCLE_API_KEY' ``` A successful response returns the base64-encoded public key: ```json theme={null} { "data": { "id": "879dc113-5ca4-4ff7-a6b7-54652083fcf8", "algorithm": "ECDSA_SHA_256", "publicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAESl76SZPBJemW0mJNN4KTvYkLT8bOT4UGhFhzNk3fJqf6iuPlLQLq533FelXwczJbjg2U1PHTvQTK7qOQnDL2Tg==", "createDate": "2026-01-15T21:47:35.107250Z" } } ``` <Tip> The public key for a given `keyId` is static, so cache the result to avoid fetching it on every webhook. </Tip> </Step> <Step title="Verify the signature against the raw body"> Use the public key to verify the signature against the **raw** request body. Parsing the JSON and re-serializing it changes the byte order, so the signature no longer matches. <CodeGroup> ```typescript Node.js theme={null} import { createVerify, createPublicKey, KeyObject } from "crypto"; // Cache the public key by keyId to avoid refetching on every webhook. const publicKeyCache = new Map<string, KeyObject>(); async function getPublicKey(keyId: string): Promise<KeyObject> { const cached = publicKeyCache.get(keyId); if (cached) return cached; // Replace <public_key_endpoint> with your product's endpoint. const response = await fetch( `https://api.circle.com/<public_key_endpoint>/${keyId}`, { headers: { Authorization: `Bearer ${process.env.CIRCLE_API_KEY}` } }, ); const { data } = await response.json(); const publicKey = createPublicKey({ key: Buffer.from(data.publicKey, "base64"), format: "der", type: "spki", }); publicKeyCache.set(keyId, publicKey); return publicKey; } export async function verifyWebhook( rawBody: string, signature: string, keyId: string, ): Promise<boolean> { const publicKey = await getPublicKey(keyId); const verifier = createVerify("SHA256"); verifier.update(rawBody); return verifier.verify(publicKey, signature, "base64"); } ``` ```python Python theme={null} import base64 import os import requests from cryptography.exceptions import InvalidSignature from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.asymmetric import ec # Cache the public key by keyId to avoid refetching on every webhook. public_key_cache: dict = {} def get_public_key(key_id: str): if key_id in public_key_cache: return public_key_cache[key_id] # Replace <public_key_endpoint> with your product's endpoint. response = requests.get( f"https://api.circle.com/<public_key_endpoint>/{key_id}", headers={"Authorization": f"Bearer {os.environ['CIRCLE_API_KEY']}"}, ) data = response.json()["data"] public_key_bytes = base64.b64decode(data["publicKey"]) public_key = serialization.load_der_public_key(public_key_bytes) public_key_cache[key_id] = public_key return public_key def verify_webhook(raw_body: bytes, signature_b64: str, key_id: str) -> bool: public_key = get_public_key(key_id) signature_bytes = base64.b64decode(signature_b64) try: public_key.verify( signature_bytes, raw_body, ec.ECDSA(hashes.SHA256()), ) return True except InvalidSignature: return False ``` </CodeGroup> If verification succeeds, the notification is authentic. If it fails, reject the request. </Step> </Steps> # Wallets API Source: https://developers.circle.com/api-reference/wallets Create and manage developer-controlled and user-controlled wallets, execute transactions, and sign messages across supported blockchains. Programmable Wallets is Circle's embedded MPC wallet platform. Use it when you need secure key management without running your own custody stack. ## Get started <CardGroup> <Card title="API keys" icon="key" href="/api-reference/keys"> Authenticate your requests with an API key. </Card> <Card title="Postman collection" icon="rocket" href="/api-reference/wallets/postman"> Try the Wallets API with Circle's Postman collection. </Card> <Card title="Webhooks" icon="bell" href="/api-reference/wallets/common/get-subscriptions"> Set up webhook subscriptions for wallet events. </Card> </CardGroup> ## Endpoint categories <CardGroup> <Card title="Developer-Controlled" icon="server" href="/api-reference/wallets/developer-controlled-wallets/get-wallet-sets"> Manage wallet sets and wallets that your backend signs for. </Card> <Card title="User-Controlled" icon="user" href="/api-reference/wallets/user-controlled-wallets/list-users"> Manage wallets where your end users hold the signing key with a PIN. </Card> <Card title="Modular Wallets" icon="cubes" href="/api-reference/wallets/buidl/list-transfers"> Read transfers, user operations, and balances for Modular Wallets. </Card> <Card title="Configurations" icon="sliders" href="/api-reference/wallets/programmable-wallets/list-monitored-tokens"> Manage monitored tokens, developer account keys, and the faucet. </Card> <Card title="Compliance Engine" icon="shield-check" href="/api-reference/wallets/compliance/screen-address"> Screen addresses against compliance rules. </Card> </CardGroup> ## OpenAPI specifications The Wallets API reference is generated from these OpenAPI specifications: * `https://developers.circle.com/openapi/configurations_1.yaml` * `https://developers.circle.com/openapi/configurations_2.yaml` * `https://developers.circle.com/openapi/developer-controlled-wallets.yaml` * `https://developers.circle.com/openapi/user-controlled-wallets.yaml` * `https://developers.circle.com/openapi/buidl-wallets.yaml` * `https://developers.circle.com/openapi/compliance.yaml` See [OpenAPI Specifications](/api-reference/openapi-specifications) for the full catalog of Circle's API specs. # Retrieve a transfer Source: https://developers.circle.com/api-reference/wallets/buidl/get-transfer openapi/buidl-wallets.yaml get /v1/w3s/buidl/transfers/{id} Retrieve an existing transfer. # Retrieve a user operation Source: https://developers.circle.com/api-reference/wallets/buidl/get-user-op openapi/buidl-wallets.yaml get /v1/w3s/buidl/userOps/{id} Retrieve an existing user operation. # List transfers Source: https://developers.circle.com/api-reference/wallets/buidl/list-transfers openapi/buidl-wallets.yaml get /v1/w3s/buidl/transfers Retrieve a list of transfers that fit the specified parameters. # List user operations Source: https://developers.circle.com/api-reference/wallets/buidl/list-user-ops openapi/buidl-wallets.yaml get /v1/w3s/buidl/userOps Retrieve a list of all user operations that fit the specified parameters. # Get wallet balances by blockchain and address Source: https://developers.circle.com/api-reference/wallets/buidl/list-wallet-balances-by-blockchain-address openapi/buidl-wallets.yaml get /v1/w3s/buidl/wallets/{blockchain}/{address}/balances Retrieve wallet balances by blockchain and address. # Get wallet balances Source: https://developers.circle.com/api-reference/wallets/buidl/list-wallet-balances-by-id openapi/buidl-wallets.yaml get /v1/w3s/buidl/wallets/{id}/balances Retrieve the balances of a wallet by its ID. # Get wallet NFTs by blockchain and address Source: https://developers.circle.com/api-reference/wallets/buidl/list-wallet-nfts-by-blockchain-address openapi/buidl-wallets.yaml get /v1/w3s/buidl/wallets/{blockchain}/{address}/nfts Retrieve the NFTs of a wallet by applicable blockchain and address. # Get wallet NFTs Source: https://developers.circle.com/api-reference/wallets/buidl/list-wallet-nfts-by-id openapi/buidl-wallets.yaml get /v1/w3s/buidl/wallets/{id}/nfts Retrieve the NFTs of a wallet by its ID. # Challenge notification Source: https://developers.circle.com/api-reference/wallets/common/challenges-initialize openapi/configurations_2.yaml webhook challengesInitialize Sent when a user-controlled wallet challenge changes state. The lifecycle state of the challenge is conveyed by the `state` field on the `notification` object. States covered by this notification type: - `COMPLETE`: the end user successfully passed the challenge. The associated operation is initiated automatically. - `FAILED`: the challenge failed (for example, an incorrect PIN or an expired challenge). The operation must be re-initiated. # Create a notification subscription Source: https://developers.circle.com/api-reference/wallets/common/create-subscription openapi/configurations_2.yaml post /v2/notifications/subscriptions Create a notification subscription by configuring an endpoint to receive notifications. For details, see the [Notification Flows](https://developers.circle.com/wallets/webhook-notification-flows) guide. # Delete a notification subscription Source: https://developers.circle.com/api-reference/wallets/common/delete-subscription openapi/configurations_2.yaml delete /v2/notifications/subscriptions/{id} Delete an existing subscription. # Get a notification signature public key Source: https://developers.circle.com/api-reference/wallets/common/get-notification-signature openapi/configurations_2.yaml get /v2/notifications/publicKey/{id} Get the public key and algorithm used to digitally sign webhook notifications. Verifying the digital signature ensures the notification came from Circle. In the headers of each webhook, you can find 1. `X-Circle-Signature`: a header containing the digital signature generated by Circle. 2. `X-Circle-Key-Id`: a header containing the UUID. This value is used as the `ID` URL parameter to retrieve the relevant public key. # Retrieve a notification subscription Source: https://developers.circle.com/api-reference/wallets/common/get-subscription openapi/configurations_2.yaml get /v2/notifications/subscriptions/{id} Retrieve an existing notification subscription. # Get all notification subscriptions Source: https://developers.circle.com/api-reference/wallets/common/get-subscriptions openapi/configurations_2.yaml get /v2/notifications/subscriptions Retrieve an array of existing notification subscriptions. # Ping Source: https://developers.circle.com/api-reference/wallets/common/ping openapi/configurations_2.yaml get /ping Checks that the service is running. # Inbound transaction notification Source: https://developers.circle.com/api-reference/wallets/common/transactions-inbound openapi/configurations_2.yaml webhook transactionsInbound Sent when an inbound transaction changes state. The lifecycle state of the transaction is conveyed by the `state` field on the `notification` object. States covered by this notification type: - `CONFIRMED`: the transaction has been broadcast onchain and is awaiting the required number of confirmations. - `COMPLETE`: the transaction has reached the required confirmations and the funds are available in the destination account. # Outbound transaction notification Source: https://developers.circle.com/api-reference/wallets/common/transactions-outbound openapi/configurations_2.yaml webhook transactionsOutbound Sent when an outbound transaction changes state. The lifecycle state of the transaction is conveyed by the `state` field on the `notification` object. States covered by this notification type: - `QUEUED`: the transaction has been initiated but has not yet been processed. - `SENT`: the transaction has been processed and sent to a blockchain node but has not yet been broadcast onchain. - `CONFIRMED`: the transaction has been broadcast onchain and is awaiting the required number of confirmations. - `COMPLETE`: the transaction has reached the required confirmations and the funds are available in the destination account. - `CANCELED`: a cancel request for the transaction has been confirmed. - `FAILED`: the transaction failed (for example, due to insufficient balance or a failed challenge). # Update a notification subscription Source: https://developers.circle.com/api-reference/wallets/common/update-subscription openapi/configurations_2.yaml patch /v2/notifications/subscriptions/{id} Update subscription endpoint to receive notifications. # Screen a blockchain address Source: https://developers.circle.com/api-reference/wallets/compliance/screen-address openapi/compliance.yaml post /v1/w3s/compliance/screening/addresses Create a screening request for a specific blockchain address and chain. # Accelerate a transaction Source: https://developers.circle.com/api-reference/wallets/developer-controlled-wallets/create-developer-transaction-accelerate openapi/developer-controlled-wallets.yaml post /v1/w3s/developer/transactions/{id}/accelerate Accelerates a specified transaction from a developer-controlled wallet. Additional gas fees may be incurred. # Cancel a transaction Source: https://developers.circle.com/api-reference/wallets/developer-controlled-wallets/create-developer-transaction-cancel openapi/developer-controlled-wallets.yaml post /v1/w3s/developer/transactions/{id}/cancel Cancels a specified transaction from a developer-controlled wallet. Gas fees may still be incurred. This is a best-effort operation, it won't be effective if the original transaction has already been processed by the blockchain. # Create a contract execution transaction Source: https://developers.circle.com/api-reference/wallets/developer-controlled-wallets/create-developer-transaction-contract-execution openapi/developer-controlled-wallets.yaml post /v1/w3s/developer/transactions/contractExecution Creates a transaction which executes a smart contract. ABI parameters must be passed in the request. Related transactions may be submitted as a batch transaction in a single call. To identify the wallet, you must provide either `walletId`, or both `walletAddress` and `blockchain` in the request body. # Create a transfer transaction Source: https://developers.circle.com/api-reference/wallets/developer-controlled-wallets/create-developer-transaction-transfer openapi/developer-controlled-wallets.yaml post /v1/w3s/developer/transactions/transfer Initiates an on-chain digital asset transfer from a specified developer-controlled wallet. To identify the wallet, you must provide either `walletId`, or both `walletAddress` and `blockchain` in the request body. # Create a wallet upgrade transaction Source: https://developers.circle.com/api-reference/wallets/developer-controlled-wallets/create-developer-transaction-wallet-upgrade openapi/developer-controlled-wallets.yaml post /v1/w3s/developer/transactions/walletUpgrade Creates a transaction which upgrades a wallet. # Estimate fee for a contract execution transaction Source: https://developers.circle.com/api-reference/wallets/developer-controlled-wallets/create-transaction-estimate-fee openapi/developer-controlled-wallets.yaml post /v1/w3s/transactions/contractExecution/estimateFee Estimates gas fees that will be incurred for a contract execution transaction, given its ABI parameters and blockchain. # Estimate fee for a transfer transaction Source: https://developers.circle.com/api-reference/wallets/developer-controlled-wallets/create-transfer-estimate-fee openapi/developer-controlled-wallets.yaml post /v1/w3s/transactions/transfer/estimateFee Estimates gas fees that will be incurred for a transfer transaction; given its amount, blockchain, and token. # Validate an address Source: https://developers.circle.com/api-reference/wallets/developer-controlled-wallets/create-validate-address openapi/developer-controlled-wallets.yaml post /v1/w3s/transactions/validateAddress Confirms that a specified address is valid for a given token on a certain blockchain. # Create wallets Source: https://developers.circle.com/api-reference/wallets/developer-controlled-wallets/create-wallet openapi/developer-controlled-wallets.yaml post /v1/w3s/developer/wallets Creates a new developer-controlled wallet or a batch of wallets within a wallet set, given the target blockchain and wallet name. **Note:** Each `walletSetId` supports a maximum of 10 million wallets. # Create a new wallet set Source: https://developers.circle.com/api-reference/wallets/developer-controlled-wallets/create-wallet-set openapi/developer-controlled-wallets.yaml post /v1/w3s/developer/walletSets Creates a new developer-controlled wallet set. **Note:** A developer account can create up to 1,000 wallet sets, with each set supporting up to 10 million wallets. To ensure EVM wallets are created with the same address across chains, see [Unified Wallet Addressing on EVM Chains](/w3s/unified-wallet-addressing-evm). # Derive a wallet Source: https://developers.circle.com/api-reference/wallets/developer-controlled-wallets/derive-wallet openapi/developer-controlled-wallets.yaml put /v1/w3s/developer/wallets/{id}/blockchains/{blockchain} Derives an EOA (Externally Owned Account) or SCA (Smart Contract Account) wallet using the address of the specified wallet and blockchain. If the target wallet already exists, its metadata will be updated with the provided metadata. This operation is only supported for EVM-based blockchains. # Derive wallet by address Source: https://developers.circle.com/api-reference/wallets/developer-controlled-wallets/derive-wallet-by-address openapi/developer-controlled-wallets.yaml put /v1/w3s/developer/wallets/derive Creates a wallet on the target blockchain using the same address as the source wallet identified by source bloc
프로젝트로 돌아가기