Comment on page


The MoneriumPack enables Safe users to make direct transfers of e-money tokens from their Safe accounts to an IBAN via the SEPA network. This allows them to use Monerium and Safe services together.
More info about Monerium:

What are we going to learn?

This guide demonstrates how to use the MoneriumPack as part of the OnRampKit and incorporate it into your web application.


  1. 3.
    A web application using your favorite CLI and language. For example:
Monerium offers several authentication methods for web apps. The MoneriumPack implements the Authorization code flow with proof key for code exchange (PKCE).

Install dependencies

yarn add @safe-global/onramp-kit @safe-global/protocol-kit @monerium/sdk

Login with Monerium

Creating a Login with Monerium integration for the Safe requires a multi-step process that should be implemented in your web app. The following steps are required.
  1. 1.
    Load the application and initialize the MoneriumPack using the following snippet:
import { MoneriumPack } from '@safe-global/onramp-kit'
const moneriumPack = new MoneriumPack({
clientId: { YOUR_CLIENT_ID }, // Get your client id from Monerium
environment: 'sandbox' // Use the proper Monerium environment ('sandbox' | 'production')})
await moneriumPack.init({ safeSdk })
The safeSdk is an instance of the Safe class. For more information on how to instantiate the protocol-kit refer to the Protocol Kit Quickstart section.
The MoneriumPack will use the Safe account address configured in the safeSdk to link to your Monerium account.
  1. 2.
    Start the Login with Monerium flow by creating a button or link in your application. Use your favorite UI library to add a handler and start the login flow. In the button handler you should start the flow by calling the open method:
await{ redirectUrl: 'https://your-site-redirect-url' })
This action will open the Monerium web page to begin the authentication process and get the permissions to gain access to your information.
Take a look to the Monerium web page URL. You will see that the query string includes parameters such as these, among others:
  • address: The Safe address you want to bind to your Monerium account.
  • signature: Always "0x". It means the origin wallet is a multisig, just like the Safe. Monerium will then verify for onchain signatures in your Safe contract
  • chain: The Monerium selected chain. The value is automatically calculated using the safeSdk instance.
  • network: The Monerium selected network. The value is automatically calculated using the safeSdk instance.
  • redirect_uri: The redirectUrl you sent in the open method. Once authenticated Monerium dashboard will redirect to that url.
⚠️ It is important to be aware of what is happening during this initial interaction. A signMessage transaction accepting the required Monerium message will be proposed to your Safe the first time you try to link your Safe address. To confirm and execute it, you must also add the remaining signatures in the Safe UI and execute the transaction.
Once you are in the Monerium web page, you should login or create a new account if you don't have one already.
After that, the Monerium UI, will wait until it detects the Safe address has signed the message as explained above and the transaction is executed. You may need to reload the Monerium UI page once you know the transaction was executed in order to continue with the flow. Alternatively, you can start the process again and Monerium will detect the transaction confirmation immediately.
Note. If you use the sandbox environment, you can test this flow without KYC in Goerli. To use the mainnets for ethereum, gnosis or polygon in production, you need to create an account in the Monerium dashboard and complete KYC. The production environment involves real money, whereas the sandbox environment uses fake money and test tokens.
  1. 3.
    Once you authenticate through the Monerium UI, a window will appear asking for permission to access your information. If you accept, control will be returned to the redirectUrl you specified in the open method.
  2. 4.
    The redirectUrl used in the open will be reached again with an extra query string parameter code. This is the authorization code you need to exchange in order to gain access to your Monerium account.
Re-initialize the MoneriumPack using the init method and exchange the code, as per Step 1.
const safeMoneriumClient = await{ authCode: '<The querystring code parameter>' })
If the code is exchanged successfully, you will be now authenticated with Monerium and your Safe will be linked!. You can start using the safeMoneriumClient instance to interact with your Monerium account. This instance is an enhanced version of the Monerium SDK, with some additional Safe features.
To learn more about the methods you can use with the safeMoneriumClient instance, check the Monerium SDK documentation.
Here are some examples:
const authContext = await moneriumClient.getAuthContext()
const profile = await moneriumClient.getProfile(authContext.defaultProfile)
const balances = await moneriumClient.getBalances()
const orders = await moneriumClient.getOrders()
  1. 5.
    When you reload a page, you usually want to stay authenticated as long as the tokens are valid. To do this, we have another way to open() the MoneriumPack.
Once authenticated in step 4, you can store the refresh_token found in the bearerProfile property of the safeMoneriumClient using browser storage methods.
If the user leaves the session or reloads the browser, detect and retrieve the stored token on the next session or page load. Always init the MoneriumPack instance when the page loads as showed in the step 1.
const safeMoneriumClient = await{
refreshToken: localStorage.getItem('MONERIUM_TOKEN')
  1. 6.
    You're now ready to place orders. In the production environment, real funds will be transferred. In the sandbox environment, fake money will be used. If you add funds using the sandbox or create a transfer from your bank account to your Monerium IBAN in the production environment, you'll receive the corresponding tokens in your Safe. For example, if your Monerium IBAN is associated with the EURe token of your Safe, and you transfer 10 euros, the EURe balance of your Safe will be 10 after the SEPA system completes the transfer.
Add tokens to your Safe using the sandbox. They should be available almost instantly. You can check the balance of your assets here afterwards.
Once you have tokens, you can create a redeem order to burn them and convert them to fiat. Include a text box for an IBAN and a button to place the order. Add a handler for the button and do the following:
amount: '10',
currency: Currency.eur, // You can redeem the currency of your choice. Your Monerium IBAN will be linked to a single token.
counterpart: {
identifier: {
standard: 'iban',
iban: 'The IBAN to send the money to',
details: {
firstName: 'John',
lastName: 'Doe',
country: 'You ISO country code',
memo: 'Testing Safe-Monerium integration'
Once you place your order, it will be sent to the destination account. Two things will occur:
  • A signMessage transaction will be proposed to the Safe services indicating in the message the amount of tokens to burn and the destination IBAN. To verify the message to be signed, refer to the API docs. You should confirm and execute it using the Safe UI or an alternative method as the transaction data is returned in the send() call.
  • An order is placed in the Monerium system, it listens for the signMessage transaction above to be confirmed and executed.
Once the transaction is recorded on the blockchain, the token is burned and the transfer of real money begins, completing the order 🚀.
  1. 7.
    Listening to events is important for understanding what is happening around. It helps us to create a proper UI in our web page.
You probably want to know when the order is completed. For this you can listen to events using the Monerium API websockets
Connecting to the socket is easy, just use the moneriumPack instance along with the subscribe() and unsubscribe() methods.
To subscribe, do this:
const handler = (notification) => {
moneriumPack.subscribe(OrderState.processed, handler)
The potential states are this ones:
OrderState {
placed = 'placed',
pending = 'pending',
processed = 'processed',
rejected = 'rejected'
If you wish to unsubscribe, you can do:
moneriumPack.unsubscribe(OrderState.processed, handler)

MoneriumPack complete React example

Check a complete example in the safe-core-sdk repo. Follow the steps in the to run the example and configure the environment variables for the pack following the .env.sample.
Last modified 16d ago