@pontis/core-sdk
v1.0.56
Published
The Pontis Bridge SDK allows frontend applications to integrate Pontis bridging capabilities and build custom dApp logic, such as DeFi applications, on top of it.
Downloads
2,233
Readme
Pontis Bridge Frontend SDK
The Pontis Bridge SDK allows frontend applications to integrate Pontis bridging capabilities and build custom dApp logic, such as DeFi applications, on top of it.
Installation
To install the Pontis Bridge Frontend SDK, run:
npm install @pontis/core-sdk
Supported Cross-Chain Assets by the first SDK version
- BTC
- Runes
Workflow
1. Authorization
Authorize using an extension wallet or a private key (for wallet integration) to sign the authorization message:
- Bitcoin: Xverse, Leather, Unisat, Asigna Multisig
- Stacks: Xverse, Leather
- EVM: Metamask
Fields required for authorization:
- publicKey (not required for EVM)
- address
- signature from the connected wallet for the
'Welcome to Pontis!'
message
2. Authorize via Pontis API
Each network requires separate authentication. The authorization request returns a JWT token for each chain. See Link
3. Load History
Use getTransaction('active' | 'completed')
to fetch the history for the specified chain. The chain is determined by the JWT token obtained in the previous step.
4. Create Bridge Transactions
Create bridge transactions for different chains. See the detailed guide below.
Bitcoin Blockchain Actions
useBitcoinBlockchainActions
1. createSendBtc
- amount: Amount to send
- feeRate: Fee rate for the bridge transaction
- recipientAddress: Recipient’s address
- destinationChain: Target chain
- doSignAndBroadcastPsbt: Function to sign and broadcast the generated PSBT. Returns
txId
.
// Example
async (psbt) => {
const txId = await signAndBroadcastPsbtXverse(psbt);
return txId;
};
2. createSendRune
- rune: Rune to send
- ... other parameters are the same as in
createSendBtc
.
Pending Transactions
For Bitcoin, the bridge transaction process involves two steps. First, the bridge transaction is created, followed by the message with the txId
and destination parameters being signed by the sender's wallet.
Developers should account for users accidentally closing the sign message window. Transactions created without a signed message on the Bitcoin chain are stored in localStorage
under the key 'pending_transactions'
.
usePendingTransactions
This hook returns stored transactions and provides functions to handle the state of the stored data. By default, the stored data is managed within the library.
signMessageForTx
Call this from the usePendingTransactions
hook to sign the message for a pending transaction:
- txId: The transaction ID
- async doSignMessage(message: string): The message signing handler
- onFinish(claim: Claim): A callback triggered when the transaction is created on the backend
const { txs, signMessageForTx } = usePendingTransactions();
{txs.length > 0 && (
<div onClick={() => {
signMessageForTx(txs[0].txId, async (message: string) => {
return await signMessage(message) as string;
}, () => {
navigate('history');
});
}}>
Pending
</div>
)}
Stacks Blockchain Actions
useStxBlockchainActions
- whitelistedRunes: List of supported runes
- unlockBtcUnsignedCall
- publicKey: Signer's public key
- amount: Amount to transfer
- recipientAddress
- targetChain
- stacksNetwork:
"testnet"
|"mainnet"
- doSignAndBroadcast: Function to sign and broadcast the generated StacksTransaction. Returns
txId
.
async (stacksTransaction) => {
const txId = await openSignTransaction({ txHex: bytesToHex(stacksTransaction.serialize()) });
return txId;
};
unlockRunesUnsignedCall
- rune: Rune to send
- ... other parameters are the same as in
unlockBtcUnsignedCall
.
unlockBtc and unlockRunes are functions to sign and broadcast transactions using the wallet.
Supported EVM Chains
- Sepolia (SEP)
- Merlin Testnet (MERL)
EVM Blockchain Actions
useEvmBlockchainActions
If permission hasn’t been granted yet, the approve
token contract function will be called automatically.
1. createBridgeOutBTC
- amount: Amount to send
- recipientAddress: Destination address
- sourceChain: SEP or MERL
- targetChain: Destination chain
- serviceValue: Service value
2. createSendRune
- rune: Rune to send
- ... other parameters are the same as in
createBridgeOutBTC
.
Pontis API
pontisAxiosInstance
: Axios instance to interact with the Pontis API.
Authorization
evmLoginRequest
,stacksLoginRequest
,bitcoinLoginRequest
: Functions to authorize via the Pontis API. These functions return a JWT token.
bitcoinLoginRequestMultisig
Used for integration with Asigna Multisig. Connect to your dapp using the @asigna/btc-connect
package. Pass the information from the useAsignaSafeInfo()
hook or connectToExtension()
function to bitcoinLoginRequestMultisig()
.
- finalSignature: Signature from multisig owners
- multiSigType: Multisig type
- multisigAddress: Multisig address
- ownersPublicKeys: Public keys of the multisig owners
- ownersAddresses: Addresses of the multisig owners
- threshold: Multisig threshold
import { useAsignaExtension, validateMessage } from '@asigna/btc-connect';
const { openSignMessage } = useAsignaExtension();
const { asignaSafeInfo } = useAsignaSafeInfo();
...
const info = await connectToExtension();
const signature = await openSignMessage('Welcome to Pontis');
bitcoinLoginRequestMultisig({
finalSignature: signature,
multiSigType: info.multisigType,
multisigAddress: info.address,
ownersPublicKeys: info.users.map(user => user.publicKey || ''),
ownersAddresses: info.users.map(user => user.address),
threshold: info.threshold,
});
Get Transactions
Use getTransactions('active' | 'completed')
to load created bridge transactions.
Configuration
Bridge settings for supported chains:
config.evm
: EVM contractsconfig.btc
: Multisig address and fee contract to retrieve service feesconfig.stx
: Stacks contracts for bridging and loading fees
Utilities
Load service fees after authorization.
useEvmFees
Get fees for MERL or SEP chains.
loadFees(targetChain)
: Returns the minimum limit for BTC asset transfers and service fees for Runes and BTC.loadMinFeesForRunes(runeId)
: Returns the minimum limit for a specified Rune.
const { loadFees, loadMinFeesForRunes } = useEvmFees(ChainType.MERL);
const fees = await loadFees(ChainType.BTC);
const minRunes = await loadMinFeesForRunes('runeId');
useFees
Get fees for BTC and STX chains.
getFeesForBridge
: Returns the minimum limit for BTC asset transfers and service fees for Runes and BTC.- sourceChain:
'BTC'
|'STX'
- targetChain: ChainType
- sourceChain:
getMinRunes(runeId)
: Returns the minimum limit for a specified Rune.- sourceChain:
'BTC'
|'STX'
- runeContractName: The Rune contract name
- runeContractAddress: The Rune contract address
- sourceChain:
const runeContractAddress = 'ST1BQXPQ99HXXS4QK6YSPJXZB594BYCGG72CKC8BA';
const runeContractName = 'pontis-bridge-i-need-test-runes::bridge-token';
const { getFeesForBridge, getMinRunes } = useFees('testnet');
const fees = await getFeesForBridge(ChainType.BTC, ChainType.STX);
const minRune = await getMinRunes(ChainType.BTC, runeContractAddress, runeContractName);
Pending Transactions
Created transactions without signed message on BTC chain are strored in localStorage under 'pending_transactions' key.
usePendingTransactions
- hook returns stored transactions, and function actions to handle state of the stored data. By default, stored data are handled inside the library.
signMessageForTx
from usePendingTransactions hook call to sign message for pending tx
- txIds: string;
- async doSignMessage(message: string) => Promise: sign message handler
- onFinish(claim: Claim) => void on finish callback, called when transaction is created on backend
const {txs, signMessageForTx} = usePendingTransactions();
{txs.length > 0 && <div onClick={() => {
signMessageForTx(txs[0].txId, async (message: string) => {
return await signMessage(message) as string;
}, () => {
navigate('history')
})
}}>Pending</div>}