Bridge SDK
Calimero bridge SDK is used to abstract the most frequent calls to various Calimero-related smart contract methods on both chains (Calimero and Near). At this point, SDK is implemented only for JavaScript.
Basics for using Calimero Bridge SDK
When calling bridge SDK methods often we will need to define:
- Shard name is a string, note that this is the same name entered through the console when creating a shard (e.g. myshard, alice32...)
- Environment is an enum and can be one of the following: DEVELOPMENT, STAGING, or PRODUCTION. Environment is internally used for obtaining RPC URL, naming certain smart contracts, and more.
- NetworkType is an enum defining Near Protocol network. And currently, Calimero supports Testnet and Mainnet, hence network enum can be TESTNET or MAINNET.
- API key is used to access smart contracts on the Calimero chain. Note that not providing an API key to the bridge SDK is completely valid if one wishes to call only the Calimero-related smart contracts on the Near side.
- ChainType is an enum defining a chain where we are calling smart contract methods or performing some other operation. Chain can obtain values of CALIMERO or NEAR.
- ConnectorType is an enum defining connector for Connector Permissions management. It can be FT, NFT or XSC.
Bridge SDK functionality
Rest of this page will show Calimero Bridge SDK functionality on examples.
Constructing Bridge instance
const bridge = new Bridge(
"q", // shard name
Environment.DEVELOPMENT, // environment
NetworkType.TESTNET, // network
"API-key" // API key
);
Get Fungible Token balance
ftBalanceOf
method returns the number of fungible tokens (on a contract that can be both on the Near and Calimero side) of a given account.
const res = await bridge.ftBalanceOf(
ChainType.CALIMERO,
"dev-1668507284663-45605813374523.ft_deployer.q.calimero.testnet", // contract id, note that if it is a bridged token it needs to be suffixed with a bridged token contract part.
"myaccount.testnet" // account id
);
console.log("Balance on Calimero: " + res);
Get NFT Owner Id
getNftOwnerId
returns the owner of the NFT on a given chain.
const res = await bridge.getNftOwnerId(
ChainType.CALIMERO,
"paras-token-v2.nft_deployer.q.calimero.testnet", // contract id, note that if it is a bridged token it needs to be suffixed with a bridged token contract part.
"1976:57" // token id
);
console.log("NFT token owner on Calimero: " + res);
Get NFTs of an owner
getNftTokensForOwner
returns all NFTs on an NFT contract for a given owner.
const res = await bridge.getNftTokensForOwner(
ChainType.NEAR,
"paras-token-v2.testnet", // contract id
"nft_connector.q.dev.calimero.testnet" // account id, here we are checking which tokens are locked on the NFT Connector account on the Near side
);
console.log("NFT tokens on Near: " + JSON.stringify(res));
Get current Light client block height
getCurrentBlockHeight
returns the current (last verified) Light client block height on Calimero or Near side.
const res = await bridge.getCurrentBlockHeight(ChainType.CALIMERO);
console.log("Light client block height on Calimero side: " + res);
Check if an account can use the bridge
canBridge
returns true
if a given account can use the defined bridge (FT, NFT, or XSC), and false
otherwise.
const res = await bridge.canBridge(
ChainType.NEAR, // defines the source chain for the checking, if this call returns true that means that the account can use a defined bridge in the direction from Near to Calimero (note that this does not mean that it can bridge from Calimero to Near).
"check.for.account.testnet", // account for which we are checking if it can use the bridge
ConnectorType.FT // connector for which we are checking, note that we are managing bridging permissions separately for each connector.
);
console.log("Can bridge FT: " + res);
Get all allowed rules for a connector
getAllowRegexRules
returns an array of regex rules (passed as strings) for a given connector. Note that if there are more than 10 rules this method will return exactly 10 rules and others will not be shown. Also, the order of the rules is not guaranteed, and if there are more than 10 rules arbitrarily 10 rules are returned.
const res = await bridge.getAllowRegexRules(
ChainType.NEAR, // defines source chain since we are separately managing permissions for bridging in 2 directions (from Near to Calimero and from Calimero to Near).
ConnectorType.FT // connector for which we are inspecting rules, note that we are managing bridging permissions separately for each connector.
);
console.log("List of allowed regex rules: " + res);
Add allow regex rule for a connector
addAllowRegexRule
returns true
if a rule is successfully added to the list of rules, false
otherwise. addAllowRegexRule
adds a regex rule for allowing all accounts that match that rule to use a defined connector.
const connectorPrivateKey = "ed25519:connector-private-key"; // to add rules to the connector permissions we need to provide a private key of a given connector. In this example that will be the FT connector.
const connectorKeyPair = KeyPair.fromString(privateKey);
const res = await bridge.addAllowRegexRule(
ChainType.CALIMERO,
connectorKeyPair,
".*", // regex rule that we are adding to the list of allowed rules. In this example, we are allowing all accounts to bridge FTs from Calimero to Near.
ConnectorType.FT, // same connector as the provided private key above.
"100000000000000000000000" // attached storage deposit
);
console.log("Add allow rule result: " + res)
Remove allowed regex rule for a connector
removeAllowedRegexRule
returns true
if a rule is successfully removed from the list of rules, false
otherwise. removeAllowedRegexRule
removes a regex rule from the allowing list of a connector.
const connectorPrivateKey = "ed25519:connector-private-key"; // to remove rules from the connector permissions we need to provide a private key of a given connector. In this example that will be removing the rule from the FT connector.
const connectorKeyPair = KeyPair.fromString(privateKey);
const res = await bridge.removeAllowedRegexRule(
ChainType.NEAR,
connectorKeyPair,
".*", // regex rule we are removing from the list of allowed rules.
ConnectorType.FT // same connector as the provided private key above.
);
console.log("Remove allowed rule result: " + res)
Add Deny XSC rule for a pair of Account regex rule and Contract regex rule
addDenyXscRulePair
returns true
if rule is successfully added to the deny list of deny XSC rules. addDenyXscRulePair
adds pair of account regex rule and contract regex rule, and if account wants to use XSC for a contract and that pair matches at least one rule in the deny list, XSC can not be called for that combination. Note that if account and contract pair does not match any of the rules in deny list, account still needs to have valid permissions for using XSC connector.
const privateKeyXsc = "ed25519:private-key-xsc-connector";
const keyPairXsc = KeyPair.fromString(privateKeyXsc);
const res = await bridge.addDenyXscRulePair(
ChainType.NEAR,
keyPairXsc,
".*", // account regex rule
"evil\.contract\.testnet", // contract regex rule, here we are denying all accounts from using contract "evil.contract.testnet"
"100000000000000000000000" // attached storage deposit
);
console.log("Deny XSC account regex per contract regex result: " + res);
Remove denied XSC rule pair (Account regex rule and Contract regex rule)
removeDeniedXscRulePair
returns true
if deny pair is successfully removed from the list of rules, false
otherwise.
This method removes rule pairs from the same list that denyCrossShardCallPerContract
adds rules to.
const privateKeyXsc = "ed25519:private-key-xsc-connector";
const keyPairXsc = KeyPair.fromString(privateKeyXsc);
res = await bridge.removeDeniedXscRulePair(
ChainType.NEAR,
keyPairXsc,
".*",
"evil\.contract\.testnet" // here we are removing pair of rules that we added in the example above
);
console.log("Remove denied XSC account regex per contract regex result: " + res);
Check if Account can use Contract through the XSC connector
canMakeCrossShardCallForContract
returns true
if Account can call Contract through the XSC connector, false
otherwise.
const res = await bridge.canMakeCrossShardCallForContract(
ChainType.NEAR,
"myaccount.testnet", // account id
"evil.contract.testnet" // contract id
);
console.log("Can use XSC for myaccount.test account and evil.contract.testnet contract: " + res);
Get XSC Deny Rule Pairs
getXscDenyRulePairs
returns an array of objects of deny regex rules for a XSC connector. Note that if there are more than 20 pairs this method will return exactly 20 rules and others will not be shown. Also, order of the rules is not guaranteed, and if there are more than 20 rules arbitrary 20 rules are returned.
Example of returned object:
{
accountRule: ".*",
contractRule: "evil\.contract\.testnet"
}
const res = await bridge.getXscDenyRulePairs(ChainType.NEAR);
console.log("XSC connector deny rules: " + res);
Bridge FTs to another chain
ftBridge
transfers fungible tokens from the chain where a token is originally created to another chain. In this example, we will show how to transfer FTs from the Near side to the Calimero side.
const myAccountId = "myaccount.testnet";
const myAccountPrivateKey = "ed25519:myaccount-private-key"; // here we should use the actual private key for the account that is bridging FTs
const myAccountKeyPair = KeyPair.fromString(myAccountPrivateKey);
const res = await bridge.ftBridge(
ChainType.NEAR, // the side where we are locking tokens, in this example we are locking tokens on the Near side and bridging them to the Calimero side
myAccountId, // the account that is bridging FTs to the other side
myAccountKeyPair, // key pair of the account that is briding FTs
"dev-1668507284663-45605813374523", // FT contract id whose tokens we are bridging, note that the account that is bridging assets needs to possess them on that side.
3 // the amount that we are bridging
);
console.log("FT result: " + res);
Withdraw FTs to the original chain
Now we will withdraw FTs that we bridged in the earlier example. For the withdrawal, we will use the ftWithdraw
method.
const accountId = "myaccount.testnet"; // same account as in the earlier example
const calimeroPrivateKey = "ed25519:myaccount-private-key-on-calimero-side"; // note that this private key is different than the one in the example above since one Account does not share key pair across chains
const keyPair = KeyPair.fromString(calimeroPrivateKey);
const res = await bridge.ftWithdraw(
ChainType.CALIMERO, // the side where we are burning and withdrawing FTs, in this example we are burning tokens on the Calimero side and unlocking them on the Near side (inverse action to the one in the previous example).
accountId, // the account that is withdrawing FTs to the other side
keyPair, // key pair of the account that is withdrawing FTs
"dev-1668507284663-45605813374523.ft_deployer.q.calimero.testnet", // FT contract with Calimero bridged suffix
3 // the amount that we are withdrawing, in this example we are withdrawing the exact amount we bridged in the earlier example
);
Bridge NFTs to another chain
nftBridge
transfers non-fungible tokens from the chain where a token is originally created to another chain. In this example, we will show how to transfer NFTs from the Near side to the Calimero side.
const myAccountId = "myaccount.testnet";
const myAccountPrivateKey = "ed25519:myaccount-private-key"; // here we should use the actual private key for the account that is bridging NFTs
const myAccountKeyPair = KeyPair.fromString(myAccountPrivateKey);
const res = await bridge.nftBridge(
ChainType.NEAR, // the side where we are locking token, in this example we are locking token on the Near side and bridging it to the Calimero side
myAccountId, // the account that is bridging NFT to the other side
myAccountKeyPair, // key pair of the account that is briding NFT
"paras-token-v2.testnet", // NFT contract id whose token we are bridging, note that the account that is bridging the asset needs to possess that asset (possess token with that token id) on that side.
"1976:57" // token id
);
console.log("NFT result: " + res);
Withdraw NFTs to the original chain
Now we will withdraw NFT that we bridged in the earlier example. For the withdrawal, we will use the nftWithdraw
method.
const accountId = "myaccount.testnet"; // same account as in the earlier example
const calimeroPrivateKey = "ed25519:myaccount-private-key-on-calimero-side"; // note that this private key is different than the one in the example above since one Account does not share key pair across chains
const keyPair = KeyPair.fromString(calimeroPrivateKey);
await bridge.nftWithdraw(
ChainType.CALIMERO, // the side where we are burning and withdrawing NFTs, in this example, we are burning token on the Calimero side and unlocking it on the Near side (inverse action to the one in the previous example).
accountId, // the account that is withdrawing NFT to the other side
keyPair, // key pair of the account that is withdrawing NFT
"paras-token-v2.nft_deployer.q.calimero.testnet", // NFT contract with Calimero bridged suffix
"1976:57" // token id
);