# Medici SDK Quickstart

## Install Package

**Step 1**: Install Medici

```bash
yarn add @bridgesplit/rwa-token-sdk
```

### Initialize RWA Client

**Step 2:** Begin by importing the RWA client, and instantiating it with its respective parameters.

```typescript
const connectionUrl = process.env.RPC_URL ?? 'http://localhost:8899';
const connection = new Connection(connectionUrl);

const confirmationOptions: ConfirmOptions = {
	skipPreflight: false,
	maxRetries: 3,
	commitment: 'processed'
}

const config: Config = {
	connection: connection,
	rpcUrl: connectionUrl,
	confirmationOptions: confirmationOptions
}

/* Setup: payerKp, is just the keypair who will pay for the tx. */
const rwaClient = new RwaClient(config, new Wallet(setup.payerKp))
```

### Initialize an Asset Controller

**Step 3:** Initialize an asset controller on chain.

```typescript
const SetupAssetControllerArgs = {
	decimals, /* Token decimals */
	payer: setup.payer.toString(), /* The wallet who will pay */
	authority: setup.authority.toString(), /* Token decimals */
	name: 'Test Class Asset',
	uri: 'https://test.com',
	symbol: 'TFT'
	/*
	
	You can always update name, uri, symbol later via 
	rwaClient.dataRegistry.updateAssetsDataAccountInfoIxns() 
	
	*/
};


const setupIx = await rwaClient.assetController.setupNewRegistry(SetupAssetControllerArgs)
const txnId = await sendAndConfirmTransaction(rwaClient.provider.connection, new Transaction().add(...setupIx.ixs), [setup.payerKp, ...setupIx.signers]);
const mint = setupIx.signers[0].publicKey.toString(); /* Make sure to record assets mint */
```

### Setup Data Registry

**Step 4:** Create the data registry account.

```typescript
const createDataAccountArgs: CreateDataAccountArgs = {
	type: { legal: {} }, /* This is where your record of legal documentation will go */
	name: "Test Data Account",
	uri: "https://test.com", 
	payer: setup.payer.toString(),
	assetMint: mint,
    };
 

/* Note: you can update the data registry later with rwaClient.dataRegistry.updateAssetsDataAccountInfoIxns() */
const createDataAccountIx = await rwaClient.dataRegistry.setupDataAccount(
	createDataAccountArgs
);
    
const txnId = await sendAndConfirmTransaction(
	rwaClient.provider.connection,
	new Transaction().add(...createDataAccountIx.ixs),
	[setup.payerKp, createDataAccountIx.signers[0]]
);
const dataAccount = createDataAccountIx.signers[0].publicKey.toString();
```

### Attach a Policy

**Step 5:** Use the policy engine to attach [policies](/programs/program-overview/policy-engine-program.md) to the asset.

```typescript
const policyArgs: AttachPolicyArgs = {
	authority: setup.authority.toString(),
	owner: setup.authority.toString(),
	assetMint: mint,
	payer: setup.payer.toString(),
	/* Identity filter is used for group specific policies */
	identityFilter: {
		identityLevels: [1],
		comparisionType: { or: {} },
	},
	policyType: {
		identityApproval: {},
		/*
		
		The following are example policy's you can pass instead of identity approval:
		
		transactionAmountLimit: {
			limit: new BN(100),
		}
		
		transactionAmountVelocity: {
			limit: new BN(100000)
			timeframe: new BN(60)
		}
		
		transactionCountVelocity: {
			limit: new BN(100),
			timeframe: new BN(60),
		}
		
		,*/
		
	},
};

const policyIx = await rwaClient.policyEngine.attachPolicy(policyArgs)
const txnId = await sendAndConfirmTransaction(rwaClient.provider.connection, new Transaction().add(...policyIx.ixs), [setup.payerKp, ...policyIx.signers]);
/* Extra accounts that are sent in txns, not defined in the anchor idl */
remainingAccounts.push(policyIx.signers[0].publicKey.toString());
```

### Setup the First User

**Step 6:** Setup the first user (developer wallet). This user will hold all the issuance tokens.

```typescript
const setupUserArgs: SetupUserArgs = {
	payer: setup.payer.toString(),
	owner: setup.authority.toString(),
	assetMint: mint,
	level: 1,
	signer: setup.payer.toString()
}

const setupIx = await rwaClient.identityRegistry.setupUserIxns(setupUserArgs)
const txnId = await sendAndConfirmTransaction(rwaClient.provider.connection, new Transaction().add(...setupIx.ixs), [setup.payerKp, ...setupIx.signers]);

const trackerAccount = await getTrackerAccount(mint, setup.authority.toString(), rwaClient.provider);
```

### Issue Tokens

**Step 7:** Issue tokens to owner address.

```typescript
const issueArgs: IssueTokenArgs = {
	authority: setup.authority.toString(),
	payer: setup.payer.toString(),
	owner: setup.authority.toString(),
	assetMint: mint,
	amount: 1000000,
}

const issueIx = await rwaClient.assetController.issueTokenIxns(issueArgs)
const txnId = await sendAndConfirmTransaction(rwaClient.provider.connection, new Transaction().add(issueIx), [setup.payerKp]);
```

### Transfer Tokens

**Step 8:** Transfer tokens.

```typescript
const transferArgs: TransferTokensArgs = {
	authority: setup.authority.toString(),
	payer: setup.payer.toString(),
	from: setup.authority.toString(),
	to: setup.authority.toString(),
	assetMint: mint,
	amount: 2000,
	remainingAccounts,
	decimals,
}

const transferIx = await rwaClient.assetController.transfer(transferArgs)
const txnId = await sendAndConfirmTransaction(rwaClient.provider.connection, new Transaction().add(transferIx), [setup.payerKp]);
```

### Revoke Tokens

**Step 9 (optional):** Revoke tokens.

```typescript
const voidArgs: VoidTokensArgs = {
	payer: setup.payer.toString(),
	amount: 200,
	owner: setup.authority.toString(),
	assetMint: mint,
	authority: setup.authority.toString(),
}
const voidIx = await rwaClient.assetController.voidTokenIxns(voidArgs)
const txnId = await sendAndConfirmTransaction(rwaClient.provider.connection, new Transaction().add(voidIx), [setup.payerKp, setup.authorityKp]);
```

These are only 7 of the many functions available with the SDK. For an exhaustive list, please see the [SDK.](https://medici-typedoc.pages.dev/)


---

# Agent Instructions: 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:

```
GET https://medici-docs.bridgesplit.com/typescript-sdk-client/medici-sdk-quickstart.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
