curl --request POST \
--url https://payments.magicblock.app/v1/spl/stealth-pool \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"payer": "3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE",
"authority": "3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE",
"handle": "john.doe@magicblock.id",
"destinations": [
"Bt9oNR5cCtnfuMmXgWELd6q5i974PdEMQDUE55nBC57L"
],
"splitAcrossKeys": false
}
'import requests
url = "https://payments.magicblock.app/v1/spl/stealth-pool"
payload = {
"payer": "3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE",
"authority": "3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE",
"handle": "john.doe@magicblock.id",
"destinations": ["Bt9oNR5cCtnfuMmXgWELd6q5i974PdEMQDUE55nBC57L"],
"splitAcrossKeys": False
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
payer: '3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE',
authority: '3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE',
handle: 'john.doe@magicblock.id',
destinations: ['Bt9oNR5cCtnfuMmXgWELd6q5i974PdEMQDUE55nBC57L'],
splitAcrossKeys: false
})
};
fetch('https://payments.magicblock.app/v1/spl/stealth-pool', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://payments.magicblock.app/v1/spl/stealth-pool",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'payer' => '3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE',
'authority' => '3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE',
'handle' => 'john.doe@magicblock.id',
'destinations' => [
'Bt9oNR5cCtnfuMmXgWELd6q5i974PdEMQDUE55nBC57L'
],
'splitAcrossKeys' => false
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://payments.magicblock.app/v1/spl/stealth-pool"
payload := strings.NewReader("{\n \"payer\": \"3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE\",\n \"authority\": \"3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE\",\n \"handle\": \"john.doe@magicblock.id\",\n \"destinations\": [\n \"Bt9oNR5cCtnfuMmXgWELd6q5i974PdEMQDUE55nBC57L\"\n ],\n \"splitAcrossKeys\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://payments.magicblock.app/v1/spl/stealth-pool")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"payer\": \"3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE\",\n \"authority\": \"3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE\",\n \"handle\": \"john.doe@magicblock.id\",\n \"destinations\": [\n \"Bt9oNR5cCtnfuMmXgWELd6q5i974PdEMQDUE55nBC57L\"\n ],\n \"splitAcrossKeys\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://payments.magicblock.app/v1/spl/stealth-pool")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"payer\": \"3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE\",\n \"authority\": \"3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE\",\n \"handle\": \"john.doe@magicblock.id\",\n \"destinations\": [\n \"Bt9oNR5cCtnfuMmXgWELd6q5i974PdEMQDUE55nBC57L\"\n ],\n \"splitAcrossKeys\": false\n}"
response = http.request(request)
puts response.read_body{
"kind": "stealthPool",
"version": "legacy",
"transactionBase64": "<string>",
"sendTo": "base",
"recentBlockhash": "<string>",
"lastValidBlockHeight": 123,
"instructionCount": 1,
"requiredSigners": [
"<string>"
],
"stealthPool": "<string>",
"setupTransaction": {
"kind": "stealthPool",
"version": "legacy",
"transactionBase64": "<string>",
"sendTo": "base",
"recentBlockhash": "<string>",
"lastValidBlockHeight": 123,
"instructionCount": 1,
"requiredSigners": [
"<string>"
],
"sendRpcEndpoint": "<string>",
"from": "base",
"validator": "<string>",
"fees": {
"lamports": "<string>",
"tokens": "<string>"
}
},
"sendRpcEndpoint": "<string>"
}Stealth Pool 생성
Build unsigned stealth-pool setup and ER update transactions that map a handle to 1-10 destination owner keys. Requires an Authorization: Bearer <token> header from the /v1/spl/login flow. Once initialized, the handle can be used as the to value of a private /v1/spl/transfer.
curl --request POST \
--url https://payments.magicblock.app/v1/spl/stealth-pool \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"payer": "3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE",
"authority": "3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE",
"handle": "john.doe@magicblock.id",
"destinations": [
"Bt9oNR5cCtnfuMmXgWELd6q5i974PdEMQDUE55nBC57L"
],
"splitAcrossKeys": false
}
'import requests
url = "https://payments.magicblock.app/v1/spl/stealth-pool"
payload = {
"payer": "3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE",
"authority": "3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE",
"handle": "john.doe@magicblock.id",
"destinations": ["Bt9oNR5cCtnfuMmXgWELd6q5i974PdEMQDUE55nBC57L"],
"splitAcrossKeys": False
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
payer: '3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE',
authority: '3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE',
handle: 'john.doe@magicblock.id',
destinations: ['Bt9oNR5cCtnfuMmXgWELd6q5i974PdEMQDUE55nBC57L'],
splitAcrossKeys: false
})
};
fetch('https://payments.magicblock.app/v1/spl/stealth-pool', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://payments.magicblock.app/v1/spl/stealth-pool",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'payer' => '3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE',
'authority' => '3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE',
'handle' => 'john.doe@magicblock.id',
'destinations' => [
'Bt9oNR5cCtnfuMmXgWELd6q5i974PdEMQDUE55nBC57L'
],
'splitAcrossKeys' => false
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://payments.magicblock.app/v1/spl/stealth-pool"
payload := strings.NewReader("{\n \"payer\": \"3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE\",\n \"authority\": \"3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE\",\n \"handle\": \"john.doe@magicblock.id\",\n \"destinations\": [\n \"Bt9oNR5cCtnfuMmXgWELd6q5i974PdEMQDUE55nBC57L\"\n ],\n \"splitAcrossKeys\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://payments.magicblock.app/v1/spl/stealth-pool")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"payer\": \"3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE\",\n \"authority\": \"3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE\",\n \"handle\": \"john.doe@magicblock.id\",\n \"destinations\": [\n \"Bt9oNR5cCtnfuMmXgWELd6q5i974PdEMQDUE55nBC57L\"\n ],\n \"splitAcrossKeys\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://payments.magicblock.app/v1/spl/stealth-pool")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"payer\": \"3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE\",\n \"authority\": \"3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE\",\n \"handle\": \"john.doe@magicblock.id\",\n \"destinations\": [\n \"Bt9oNR5cCtnfuMmXgWELd6q5i974PdEMQDUE55nBC57L\"\n ],\n \"splitAcrossKeys\": false\n}"
response = http.request(request)
puts response.read_body{
"kind": "stealthPool",
"version": "legacy",
"transactionBase64": "<string>",
"sendTo": "base",
"recentBlockhash": "<string>",
"lastValidBlockHeight": 123,
"instructionCount": 1,
"requiredSigners": [
"<string>"
],
"stealthPool": "<string>",
"setupTransaction": {
"kind": "stealthPool",
"version": "legacy",
"transactionBase64": "<string>",
"sendTo": "base",
"recentBlockhash": "<string>",
"lastValidBlockHeight": 123,
"instructionCount": 1,
"requiredSigners": [
"<string>"
],
"sendRpcEndpoint": "<string>",
"from": "base",
"validator": "<string>",
"fees": {
"lamports": "<string>",
"tokens": "<string>"
}
},
"sendRpcEndpoint": "<string>"
}인증
Token obtained from the /v1/spl/login flow.
본문
"3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE"
Authority allowed to manage the pool.
"3rXKwQ1kpjBd5tdcco32qsvqUh1BnZjcYnS5kYrP7AYE"
Human-readable handle, up to 255 UTF-8 bytes. Stored as its exact bytes — NOT trimmed, lowercased, or normalized, so John.Doe@… is a different handle than john.doe@….
1 - 255"john.doe@magicblock.id"
1-10 destination owner pubkeys (owners, not token accounts).
1 - 10 elements[
"Bt9oNR5cCtnfuMmXgWELd6q5i974PdEMQDUE55nBC57L"
]
Optional. When true, split payments may resolve independently across the destination keys.
Optional. Validator identity to receive the delegated pool.
"MAS1Dt9qreoRMQ14YQuhg8UTZMMzDdKhmkZMECCzk57"
Optional. Cluster selector or custom http(s) RPC URL.
mainnet, devnet, mainnet-private, devnet-private "mainnet"
응답
Unsigned setup and ER update transactions
stealthPool legacy, v0 The ER update transaction.
base, ephemeral x >= 0Derived stealth-pool PDA.
The base-chain setup transaction. It uses the same transaction response contract as the top-level transaction; sendRpcEndpoint is omitted when sendTo is base.
Show child attributes
Show child attributes

