<RemovedContentCallout>
  The Onramp Kit in the Safe\{Core\} SDK is no longer supported; with that, neither is the `MoneriumPack`. We recommend integrating Monerium directly into your application by following this guide.
</RemovedContentCallout>

# Onramp with Monerium

[Monerium](https://monerium.com) provides EURe, a regulated stablecoin on Ethereum, Polygon, and Gnosis. 
This guide demonstrates how to use the [Monerium SDK](https://monerium.github.io/js-sdk/) and the Safe\{Core\} SDK together to enable direct transfers from Safe accounts to an IBAN via the SEPA network and vice versa.

## Prerequisites

1. [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)
2. [Monerium account and application](https://monerium.dev/docs/getting-started/create-app)
3. A web application using your favorite CLI and language. For example [React with NextJS](https://nextjs.org/docs), [Vue with Nuxt](https://nuxt.com/) or [Svelte with SvelteKit](https://kit.svelte.dev/).
4. A [deployed Safe](../protocol-kit.mdx) for your users.

## Overview

The main steps of this tutorial are:

1. Authentication with Monerium and Safe: This requires signing a message with the Safe and using the Monerium Authentication flow.
2. Sending an order from the Safe to an IBAN involves sending an order to Monerium and signing the order with the Safe.

## Step 1: Authenticate with Monerium and Safe

<Steps>

### Sign the link message with the Safe

First, your users have to sign a message with the Safe to prove ownership of the Safe. 
Monerium will scan the signed messages in the Safe to verify ownership.

Use the Safe\{Core\} SDK, as shown below, to sign a message with multiple owners (for example, a two-out-of-three Safe). 
This example programmatically signs a message with two owners. 
In practice, one owner proposes the transaction, and another owner confirms it using the [Safe\{Wallet\}](https://app.safe.global/) UI.

```typescript
import Safe, {
  getSignMessageLibContract,
  hashSafeMessage
} from '@safe-global/protocol-kit'
import { constants } from '@monerium/sdk'

// Initialize the Safe\{Core\} SDK and link it to an existing Safe
const protocolKit = await Safe.init({
  provider: RPC_URL, // set a valid RPC URL
  signer: OWNER_1_PRIVATE_KEY, // set the private key of the first Safe owner
  safeAddress
})

// Create a signed message by creating a transaction to the signMessage contract
const signMessageContract = await getSignMessageLibContract({
  safeProvider: protocolKit.getSafeProvider(),
  safeVersion: await protocolKit.getContractVersion()
})

// Let the contract encode the message's hash to get the transaction data
const txData = signMessageContract.encode('signMessage', [
  hashSafeMessage(constants.LINK_MESSAGE) // 'I hereby declare that I am the address owner.'
])

// Assemble a transaction object
const safeTransactionData = {
  to: await signMessageContract.getAddress(),
  value: '0',
  data: txData,
  operation: OperationType.DelegateCall
}

// Create a transaction
const signMessageTx = await protocolKit.createTransaction({
  transactions: [safeTransactionData]
})

// Sign the transaction with the first owner
const signedTx = await protocolKit.signTransaction(signMessageTx)

// Connect the protocol kit to the second owner
const protocolKitOfOwner2 = await protocolKit.connect({
  signer: OWNER_2_PRIVATE_KEY
})

// Sign and execute the transaction as the second owner
const transactionResult = await protocolKitOfOwner2.executeTransaction(
  signedTx
)

// Check the transaction hash to see if the transaction settled
console.log('transactionResult', transactionResult)
```

The `protocolKit` is an instance of the [`Safe`](../../reference-sdk-protocol-kit/initialization/init.mdx) class. 
For more information on instantiating the Protocol Kit, refer to the [Protocol Kit Quickstart section](../protocol-kit.mdx).

### Initialize the Monerium client and authenticate the users

After the message is signed and the transaction is executed, the users can authenticate with Monerium.

```typescript
import { MoneriumClient } from '@monerium/sdk'

// Initialize the Monerium Client
const monerium = new MoneriumClient({
  clientId: 'a1b2c3-x7y8y9', // Get your client ID from Monerium
  environment: 'sandbox' // Use the appropriate Monerium environment ('sandbox' | 'production')
})

// Start the Monerium authentication flow and send the users to Monerium
await monerium.authorize({
  address: safeAddress, // The address of the users' Safe
  signature: '0x', // '0x' for Safe authentication lets Monerium look for the signature on-chain
  redirectUrl: 'http://localhost:3000/return', // URL where Monerium will redirect the users after authenticating
  chainId: 11155111 // Chain ID of Sepolia in this example
})
```

Calling `authorize` will redirect the users to the Monerium login page. 

### Authenticate with Monerium

At Monerium, the users need to log in or create an account. 
Once logged in, Monerium will verify the ownership of the Safe by checking the signed message. 
After successful verification, Monerium will create an IBAN and link it to the Safe. 
The users will then be redirected to the specified `redirectUrl` with the new session id as a GET parameter.

### Finish the authentication

Once the users land back on your page, finish the authentication process.

```typescript
// Returns true, if the users are authorized
const isAuthorized = await monerium.getAccess()
```

Congratulations, you authenticated your users with Monerium and linked the Safe to the Monerium account.

</Steps>

## Step 2: Place an Order

Once users are authenticated with Monerium, they can place an order to transfer tokens from their Safe to an IBAN.

<Steps>

### Get some tokens

First, your users needs to obtain some EURe test tokens on Sepolia:

* Log into the [Monerium Sandbox](https://sandbox.monerium.dev/accounts) account.
* Click on the `ADD MONEY` button.
* Create a test IBAN transfer onto the account. The tokens from this test transfer will be available in the Safe.

<Image src={MoneriumAddMoney} width={300} height={500}  />

### Send an order to Monerium

To send tokens from a Safe to an IBAN, users must send the order to Monerium and sign a message with their account.

```typescript
import { placeOrderMessage } from '@monerium/sdk'

const amount = '10' // Specify the amount in Euro
const iban = 'DK4878805291075472' // The target IBAN

// 'Send EUR 10 to DK4878805291075472 at Fri, 17 May 2024 20:55:29Z'
const orderMessage = placeOrderMessage(amount, 'eur', iban)

// Send the order to the Monerium backend
const order = await moneriumClient.placeOrder({
  amount,
  signature: '0x',
  currency: 'eur',
  address: safeAddress, // the Safe address
  counterpart: {
    identifier: {
      standard: 'iban',
      iban
    },
    details: {
      firstName: 'User',
      lastName: 'Userson',
      county: 'AL'
    }
  },
  message: orderMessage,
  memo: 'Powered by Monerium SDK',
  chain: 'ethereum',
  network: 'sepolia'
})
```

Monerium will listen for the sign message transaction of the following step on the selected chain and execute the order once the transaction settles.

### Sign the order with the Safe

Now, the Safe needs to sign the order. 
To do this, send a sign message transaction to the blockchain. 
In practice, one owner might propose this transaction using the Safe Transaction Service. The other owner confirms the message and sends the transaction through the [Safe\{Wallet\}](https://app.safe.global/) UI.

```typescript
// Hash and encode the order message
const txData = signMessageContract.encode('signMessage', [
  hashSafeMessage(orderMessage)
])

// Assemble a transaction object
const safeTransactionData = {
  to: await signMessageContract.getAddress(),
  value: '0',
  data: txData,
  operation: OperationType.DelegateCall
}

// Create a transaction with the Safe\{Core\} SDK
const signMessageTx = await protocolKit.createTransaction({
  transactions: [safeTransactionData]
})

// Sign the transaction with the first owner
const signedTx = await protocolKit.signTransaction(signMessageTx)

// Sign and execute the transaction with the second owner
const transactionResult = await protocolKitOfOwner2.executeTransaction(signedTx)

// Verify on-chain settlement
console.log('transactionResult', transactionResult)
```

Monerium will execute the order once the transaction settles.

</Steps>

Well done! You have linked your users' Safes to an IBAN, bridging the gap between blockchain and traditional payment rails. 

## Further reading

* [Monerium Developer Portal](https://monerium.dev/docs/welcome)
* Add [event listeners](https://monerium.github.io/js-sdk/#subscribe-to-order-events) to make your app more interactive.
