> For the complete documentation index, see [llms.txt](https://docs.keeta.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.keeta.com/guides/fiat-deposit-from-usdc.md).

# Fiat Deposit From USDC

This example shows how to deposit USDC from the Arbitrum Network, which is converted to USD on Keeta.  It assumes KYC has already been completed and shared with the Anchor.  See the two KYC guides [Add KYC Certificate](https://app.gitbook.com/o/qYWvPguljbNCiIZoKq7U/sites/site_VPB12/s/pitcpcamWc0BKEe28I1D/~/edit/~/changes/85/guides/add-kyc-certificate) and [Share KYC Attributes](https://app.gitbook.com/o/qYWvPguljbNCiIZoKq7U/sites/site_VPB12/s/pitcpcamWc0BKEe28I1D/~/edit/~/changes/85/guides/share-kyc-attributes) for more details on handling KYC.

To run the example on the main network, the following changes are needed.

* Change network from `test` to `main`
* Use the main network Keeta USD Token - `keeta_amnkge74xitii5dsobstldatv3irmyimujfjotftx7plaaaseam4bntb7wnna`
* Use the main Arbitrum Network USDC Contract - `0xaf88d065e77c8cC2239327C5EDb3A432268e5831`
* Use the main Arbitrum Chain ID - `42161`

{% stepper %}
{% step %}

### Setup Account and Anchor Client

{% tabs %}
{% tab title="TypeScript" %}
{% code expandable="true" %}

```ts
const account = Account.fromSeed(seed.trim(), 0);
await using userClient = KeetaAnchor.KeetaNet.UserClient.fromNetwork('test', account);
const assetMovementClient = new KeetaAnchor.AssetMovement.Client(userClient);
```

{% endcode %}
{% endtab %}

{% tab title="C#" %}
{% code expandable="true" %}

```csharp
using Account userAccount = runtime.Accounts.FromSeed(seed, 0, "ecdsa_secp256k1");

using AssetMovementClient assetMovementClient = runtime.CreateAssetMovementClient(
			Constants.NodeApi,
			userClient.NetworkAddress,
			userAccount);

using NodeClient nodeClient = runtime.CreateNodeClient(Constants.NodeApi);
```

{% endcode %}
{% endtab %}
{% endtabs %}
{% endstep %}

{% step %}

### Establish Source Location and Destination

In this example the source is the Arbitrum USDC contract and destination is the Keeta USD Token on the Test Network. This establishes the asset pair that will be used for the transfer.

{% tabs %}
{% tab title="TypeScript" %}
{% code expandable="true" %}

```ts
const ARBITRUM_CHAIN_ID = 421614n;
const ARBITRUM_USDC_ASSET = 'evm:0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d';
const KEETA_USD_ASSET = Account.fromPublicKeyString('keeta_any4zllibya6fum3lsoimxmnmeo57nklxlh4c6d6xosfacarfaa3knkiprkmm');
const ASSET_PAIR = { from: ARBITRUM_USDC_ASSET, to: KEETA_USD_ASSET } as const;
```

{% endcode %}
{% endtab %}

{% tab title="C#" %}
{% code expandable="true" %}

```csharp
AssetOrPair assetPair = AssetOrPair.Pair(Constants.ArbitrumUsdcAsset, Constants.KeetaUsdAsset);
```

{% endcode %}
{% endtab %}
{% endtabs %}
{% endstep %}

{% step %}

### Identify Provider with Anchor Resolver

Use the Asset Movement Anchor Client to identify providers that can handle the transfer.

{% tabs %}
{% tab title="TypeScript" %}

```typescript
// Find Asset Movement providers that support Arbitrum => Keeta USD
const providers = await assetMovementClient.getProvidersForTransfer({
	// USDC (Arbitrum) => USD (Keeta)
	asset: ASSET_PAIR,
	// Source: Arbitrum
	from: {
		type: 'chain',
		chain: {
			type: 'evm',
			chainId: ARBITRUM_CHAIN_ID
		}
	},
	// Destination: Keeta Network
	to: {
		type: 'chain',
		chain: {
			type: 'keeta',
			networkId: userClient.network
		}
	}
});
```

{% endtab %}

{% tab title="C#" %}
{% code expandable="true" %}

```csharp
IReadOnlyList<AssetProvider> providers = await assetMovementClient.GetProvidersForTransfer(
  new AssetProviderSearch(
    Asset: assetPair,
    From: Constants.ArbitrumSepoliaLocation,
		To: keetaDestination),
cancellationToken);
```

{% endcode %}
{% endtab %}
{% endtabs %}
{% endstep %}

{% step %}

### Create Persistent Deposit Address

A persistent deposit address is an account on another cryptocurrency network that automatically transfers tokens deposited on the other network to equivalent Keeta tokens.

{% tabs %}
{% tab title="TypeScript" %}

```typescript
const persistentAddressResponse = await providers[0].createPersistentForwardingAddress({
	account: userAccount,
	asset: ASSET_PAIR,
	sourceLocation: {
		type: 'chain',
		chain: { type: 'evm', chainId: ARBITRUM_CHAIN_ID }
	},
	destinationLocation: {
		type: 'chain',
		chain: { type: 'keeta', networkId: userClient.network }
	},
	destinationAddress: userAccount.publicKeyString.get()
});

console.log(persistentAddressResponse.address);
```

{% endtab %}

{% tab title="C#" %}
{% code expandable="true" %}

```csharp
JsonElement persistentAddressResponse = await assetMovementClient.CreatePersistentForwardingAddress(
  providers[0],
  new AssetCreateAddressRequest(
  SourceLocation: Constants.ArbitrumSepoliaLocation,
  Asset: assetPair,
	DestinationLocation: keetaDestination,
	DestinationAddress: userAccount.Address),
cancellationToken);
```

{% endcode %}
{% endtab %}
{% endtabs %}
{% endstep %}

{% step %}

### Deposit USDC Funds

On the TEST network, funds can be deposited to the address returned from the previous step using any Arbitrum wallet connected to the test (Sepolia) network.  Alternatively, Circle's faucet `https://faucet.circle.com/` can be used to deposit USDC using Arbitrum Sepolia.
{% endstep %}

{% step %}

### List Anchor Transactions

The Anchor will show transactions for a given account and can be used to identify when the new transaction has been completed.

{% tabs %}
{% tab title="TypeScript" %}
{% code expandable="true" %}

```ts
const transactionResponse = await providers[0].listTransactions({
	account: userAccount,
	persistentAddresses: [{
		location: {
			type: 'chain',
				chain: {
					type: 'evm',
					chainId: ARBITRUM_CHAIN_ID
				}
			},
		persistentAddress: persistentAddressResponse.address.toString()
	}]
});
```

{% endcode %}
{% endtab %}

{% tab title="C#" %}
{% code expandable="true" %}

```csharp
AssetTransactionPage transactionResponse = await assetMovementClient.ListTransactions(
  provider,
  new AssetListTransactionsRequest(
    PersistentAddresses:
    [
		  new AssetPersistentAddressFilter(
  		  Constants.ArbitrumSepoliaLocation,
	  		persistentAddress),
		]),
	monitorToken);
```

{% endcode %}
{% endtab %}
{% endtabs %}
{% endstep %}

{% step %}

### Check Keeta Account History

Another method to verify the transaction has completed is to check the account history on Keeta.

{% tabs %}
{% tab title="TypeScript" %}
{% code expandable="true" %}

```ts
const accountHistory = await userClient.history();
```

{% endcode %}
{% endtab %}
{% endtabs %}
{% endstep %}
{% endstepper %}

## Full Code Example

{% tabs %}
{% tab title="TypeScript" %}
{% @github-files/github-code-block url="<https://github.com/KeetaNetwork/keetanet-examples/blob/main/src/anchor/asset-movement-fiat-deposit-from-crypto.ts>" %}
{% endtab %}

{% tab title="C#" %}
{% @github-files/github-code-block url="<https://github.com/KeetaNetwork/keetanet-examples/blob/main/csharp/src/Anchor/AssetMovementFiatDepositFromCrypto.cs>" %}
{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.keeta.com/guides/fiat-deposit-from-usdc.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
