Skip to content

Commit

Permalink
Migrate and update noble bridging example scripts (#10)
Browse files Browse the repository at this point in the history
## Summary

Adds example scripts for Noble `depositForBurn` and `receiveMessage`
calls based on [the
scripts](https://github.com/bd21/noble-tutorials/tree/149d629c5d2897eb55af360a128e059c3ff4668e/tutorials)
currently referenced in our [existing
docs](https://developers.circle.com/stablecoins/docs/transfer-usdc-on-testnet-from-noble-to-ethereum).
The previous scripts used the relayer both ways, while the new scripts
just emphasize Noble functionality in line with the Solana tutorials
(this is also necessary due to license issues with the ETH web3js
modules).

In addition, these scripts have the following fixes:
* Update references to Goerli to now refer to Sepolia
* Correct broken Noble mintscan links
* Simplify instructions/scripts to focus on end-to-end USDC bridging
  • Loading branch information
mdbere authored Apr 9, 2024
1 parent 69f7d3c commit 69ee090
Show file tree
Hide file tree
Showing 7 changed files with 5,036 additions and 0 deletions.
9 changes: 9 additions & 0 deletions examples/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Required for both functions
MNEMONIC="..."

# Required for DepositForBurn
ETH_MINT_RECIPIENT="0x..."

# Required for ReceiveMessage
ATTESTATION="0x..."
MESSAGE_HEX="0x...
52 changes: 52 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Noble <-> Ethereum Bridging (Typescript)

## DepositForBurn instructions

1. Install required packages:

```
npm install
```

2. (If needed) Obtain tokens from the faucet: https://faucet.circle.com/

3. Set up a `.env` file based on `.env.example`, filling in the `MNEMONIC` and `ETH_MINT_RECIPIENT` fields:

```
MNEMONIC="word1 word2..."
ETH_MINT_RECIPIENT=0x...
```

4. Run the depositForBurn script:

```
npm run depositForBurn
```

The Noble testnet -> ETH Sepolia CCTP relayer should pick up these messages automatically. To avoid these being automatically picked up, all references to `MsgDepositForBurn` can be changed to `MsgDepositForBurnWithCaller` and a `destinationCaller` field should be added to `msg.value` below line 70.

## ReceiveMessage instructions

1. Install required packages:

```
npm install
```

2. Initiate a `DepositForBurnWithCaller` from ETH to Noble. If a regular `DepositForBurn` call is made, the relayer will automatically receive the message on Noble.

3. Fetch the attestation and message from Iris at https://iris-api-sandbox.circle.com/messages/{sourceDomain}/{txHash}.

4. Set up a `.env` file based on `.env.example`, filling in the `MNEMONIC`, `ATTESTATION`, and `MESSAGE_HEX` fields:

```
MNEMONIC="word1 word2..."
ATTESTATION=0x...
MESSAGE_HEX=0x
```

5. Run the receiveMessage script:

```
npm run receiveMessage
```
93 changes: 93 additions & 0 deletions examples/depositForBurn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* Copyright (c) 2024, Circle Internet Financial LTD All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import "dotenv/config"
import { DirectSecp256k1HdWallet, Registry, GeneratedType } from "@cosmjs/proto-signing";
import { SigningStargateClient } from "@cosmjs/stargate";
import { MsgDepositForBurn } from "./generated/tx";

export const cctpTypes: ReadonlyArray<[string, GeneratedType]> = [
["/circle.cctp.v1.MsgDepositForBurn", MsgDepositForBurn],
];

function createDefaultRegistry(): Registry {
return new Registry(cctpTypes)
};

const main = async() => {

const mnemonic = process.env.MNEMONIC ? process.env.MNEMONIC : "";
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(
mnemonic,
{
prefix: "noble"
}
);

const [account] = await wallet.getAccounts();

const client = await SigningStargateClient.connectWithSigner(
"https://rpc.testnet.noble.strange.love",
wallet,
{
registry: createDefaultRegistry()
}
);

// Left pad the mint recipient address with 0's to 32 bytes
const rawMintRecipient = process.env.ETH_MINT_RECIPIENT ? process.env.ETH_MINT_RECIPIENT : "";
const cleanedMintRecipient = rawMintRecipient.replace(/^0x/, '');
const zeroesNeeded = 64 - cleanedMintRecipient.length;
const mintRecipient = '0'.repeat(zeroesNeeded) + cleanedMintRecipient;
const buffer = Buffer.from(mintRecipient, "hex");
const mintRecipientBytes = new Uint8Array(buffer);

const msg = {
typeUrl: "/circle.cctp.v1.MsgDepositForBurn",
value: {
from: account.address,
amount: "1",
destinationDomain: 0,
mintRecipient: mintRecipientBytes,
burnToken: "uusdc",
// If using DepositForBurnWithCaller, add destinationCaller here
}
};

const fee = {
amount: [
{
denom: "uusdc",
amount: "0",
},
],
gas: "200000",
};
const memo = "";
const result = await client.signAndBroadcast(
account.address,
[msg],
fee,
memo
);

console.log(`Burned on Noble: https://mintscan.io/noble-testnet/tx/${result.transactionHash}`);
console.log(`Minting on Ethereum to https://sepolia.etherscan.io/address/${rawMintRecipient}`);
}

main()
Loading

0 comments on commit 69ee090

Please sign in to comment.