|
| 1 | +# Stellar Router SDK |
| 2 | + |
| 3 | +The Stellar Router is a simple smart contract that you can use to execute multiple contract calls at the same time. |
| 4 | + |
| 5 | +Why doing this? Well by doing this you can "simulate" the feature the classic side has where you could make multiple |
| 6 | +operations at the same time, with soroban you are limited to a single operation per transaction but by using this router |
| 7 | +you can make multiple soroban calls at once from your website. |
| 8 | + |
| 9 | +## Install the SDK |
| 10 | + |
| 11 | +You can install the SDK from JSR by doing: |
| 12 | + |
| 13 | +```shell |
| 14 | +npx jsr add @creit-tech/stellar-assets-sdk |
| 15 | +``` |
| 16 | + |
| 17 | +You can check more installation methods (deno, pnpm, etc) from [here](https://jsr.io/@creit-tech/stellar-router-sdk/) |
| 18 | + |
| 19 | +## How to use |
| 20 | + |
| 21 | +Because the library it's pretty simple, using is also simple. Here is an example of us fetching a list of 19 balances |
| 22 | +from different contracts calls at once. |
| 23 | + |
| 24 | +```typescript |
| 25 | +import { StellarRouterSdk } from "@creit-tech/stellar-router-sdk"; |
| 26 | + |
| 27 | +const assets: string[] = [ |
| 28 | + "CAUIKL3IYGMERDRUN6YSCLWVAKIFG5Q4YJHUKM4S4NJZQIA3BAS6OJPK", |
| 29 | + "CD25MNVTZDL4Y3XBCPCJXGXATV5WUHHOWMYFF4YBEGU5FCPGMYTVG5JY", |
| 30 | + "CAO7DDJNGMOYQPRYDY5JVZ5YEK4UQBSMGLAEWRCUOTRMDSBMGWSAATDZ", |
| 31 | + "CBH4M45TQBLDPXOK6L7VYKMEJWFITBOL64BN3WDAIIDT4LNUTWTTOCKF", |
| 32 | + "CDTKPWPLOURQA2SGTKTUQOWRCBZEORB4BWBOMJ3D3ZTQQSGE5F6JBQLV", |
| 33 | + "CBN3NCJSMOQTC6SPEYK3A44NU4VS3IPKTARJLI3Y77OH27EWBY36TP7U", |
| 34 | + "CBCO65UOWXY2GR66GOCMCN6IU3Y45TXCPBY3FLUNL4AOUMOCKVIVV6JC", |
| 35 | + "CCKCKCPHYVXQD4NECBFJTFSCU2AMSJGCNG4O6K4JVRE2BLPR7WNDBQIQ", |
| 36 | + "CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75", |
| 37 | + "CB226ZOEYXTBPD3QEGABTJYSKZVBP2PASEISLG3SBMTN5CE4QZUVZ3CE", |
| 38 | + "CDIKURWHYS4FFTR5KOQK6MBFZA2K3E26WGBQI6PXBYWZ4XIOPJHDFJKP", |
| 39 | + "CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA", |
| 40 | + "CBLLEW7HD2RWATVSMLAGWM4G3WCHSHDJ25ALP4DI6LULV5TU35N2CIZA", |
| 41 | + "CAAV3AE3VKD2P4TY7LWTQMMJHIJ4WOCZ5ANCIJPC3NRSERKVXNHBU2W7", |
| 42 | + "CDCKFBZYF2AQCSM3JOF2ZM27O3Y6AJAI4OTCQKAFNZ3FHBYUTFOKICIY", |
| 43 | + "CB2XMFB6BDIHFOSFB5IXHDOYV3SI3IXMNIZLPDZHC7ENDCXSBEBZAO2Y", |
| 44 | + "CBRP2VD3CZLEQIQZ4JMBXGA5AC2U6JE26YU5CCIOICIZCVWPGBO2QRUB", |
| 45 | + "CDYEOOVL6WV4JRY45CXQKOBJFFAPOM5KNQCCDNM333L6RM2L4RO3LKYG", |
| 46 | + "CBZVSNVB55ANF24QVJL2K5QCLOAB6XITGTGXYEAF6NPTXYKEJUYQOHFC", |
| 47 | +]; |
| 48 | + |
| 49 | +const sdk: StellarRouterSdk = new StellarRouterSdk({ rpcUrl: "https://mainnet.sorobanrpc.com" }); |
| 50 | +const xbullSwapContract: string = "CB3JAPDEIMA3OOSALUHLYRGM2QTXGVD3EASALPFMVEU2POLLULJBT2XN"; |
| 51 | +const invocations: Invocation[] = assets.map((contract: string): Invocation => ({ |
| 52 | + contract, |
| 53 | + method: "balance", |
| 54 | + args: [new Address(xbullSwapContract).toScVal()], |
| 55 | +})); |
| 56 | + |
| 57 | +const balances: bigint[] = await sdk.simResult(invocations); |
| 58 | +``` |
| 59 | + |
| 60 | +But you can also generate the operations for you to use in your own transaction and execute them, here is an example of |
| 61 | +burning and registering again a domain in the SorobanDomains contract (basically, doing a "renew" without the contract |
| 62 | +directly supporting it). |
| 63 | + |
| 64 | +```typescript |
| 65 | +import { SorobanDomainsSDK } from "@creit-tech/sorobandomains-sdk"; |
| 66 | +import { StellarRouterSdk } from "@creit-tech/stellar-router-sdk"; |
| 67 | +import { xdr } from "@stellar/stellar-sdk"; |
| 68 | + |
| 69 | +const routerSdk = new StellarRouterSdk(); |
| 70 | +const domainsSdk = new SorobanDomainsSDK(PARAMS); |
| 71 | +const domain = "superawesomeimpossibledomain"; |
| 72 | +const domainsContract = "CATRNPHYKNXAPNLHEYH55REB6YSAJLGCPA4YM6L3WUKSZOPI77M2UMKI"; |
| 73 | +const domainOwner: string = "GA3S4HZCLBXSA4T5SFNLTQNZ4VOJM3V2H2EN57RJPYFS2BVXX2PEXGPO"; |
| 74 | + |
| 75 | +const { value } = await domainsSdk.searchDomain({ domain }); |
| 76 | + |
| 77 | +const contractCall: xdr.Operation<Operation.InvokeHostFunction> = routerSdk.exec( |
| 78 | + domainOwner, |
| 79 | + [{ |
| 80 | + contract: domainsContract, |
| 81 | + method: "burn_record", |
| 82 | + args: [xdr.ScVal.scvVec([xdr.ScVal.scvSymbol("Record"), xdr.ScVal.scvBytes(new TextEncoder().encode(value.node))])], |
| 83 | + }, { |
| 84 | + contract: domainsContract, |
| 85 | + method: "set_record", |
| 86 | + args: [ |
| 87 | + nativeToScVal(new TextEncoder().encode(domain), { type: "bytes" }), |
| 88 | + nativeToScVal(new TextEncoder().encode("xlm"), { type: "bytes" }), |
| 89 | + nativeToScVal(value.address, { type: "address" }), |
| 90 | + nativeToScVal(value.address, { type: "address" }), |
| 91 | + nativeToScVal(3600n * 24n * 365n * 5n, { type: "u64" }), |
| 92 | + ], |
| 93 | + }], |
| 94 | +); |
| 95 | + |
| 96 | +// Now you build the transaction, add the operation from above and send it to the network. |
| 97 | +``` |
| 98 | + |
| 99 | +The best thing about using this method, is that the transaction is also atomic so if something fails in the middle then |
| 100 | +the whole transaction fails. Just like with the classic side! |
| 101 | + |
| 102 | +## License |
| 103 | + |
| 104 | + |
| 105 | + |
| 106 | +Licensed under the MIT License, Copyright © 2025-present Creit Technologies LLP. |
| 107 | + |
| 108 | +Check out the `LICENSE.md` file for more details. |
0 commit comments