Skip to content

Commit

Permalink
SIP-29: Snap Assets API (#154)
Browse files Browse the repository at this point in the history
* SIP-29: Snap Assets API

* Fix typos

* Update document header

* Add precision about emitter country

* SIP-29 Improvements (#155)

* add handlers and permission definition

* update to use `snaps-sdk`

* snap -> Snap

* Add CAIP-19 ID reference in description and rename token to asset

* Add chains caveat

* fix typo

* allow batching

* add fungible reference to asset description

* add appendix for fungible assets

* fix typos

* update rates handler to support batching

* unify

* rename `AssetUnit` to `FungibleAssetUnit`

* Fix formatting

* Rename `ticker` to `symbol`

It should be closer to the terminology used by the Token API.

* Fix capitalization

Co-authored-by: Charly Chevalier <[email protected]>

* Update comment

Co-authored-by: Charly Chevalier <[email protected]>

* Update comment

Co-authored-by: Charly Chevalier <[email protected]>

* Add link to CAIP-19

Co-authored-by: Charly Chevalier <[email protected]>

* Fix formatting

Co-authored-by: Charly Chevalier <[email protected]>

* Rename `OnAssetLookupReturn` to `OnAssetLookupResponse`

Co-authored-by: Frederik Bolding <[email protected]>

* Rename `OnAssetConversionReturn` to `OnAssetConversionResponse`

Co-authored-by: Frederik Bolding <[email protected]>

* Add missing `AssetMetadata` type

* Rename `OnAssetLookupArgs` to `OnAssetLookupArguments`

Co-authored-by: Frederik Bolding <[email protected]>

* Rename `OnAssetConversionArgs` to `OnAssetConversionArguments`

Co-authored-by: Frederik Bolding <[email protected]>

* Remove placeholder section

Co-authored-by: Maarten Zuidhoorn <[email protected]>

* Address requested changes
- Update the handler names to be pluralised
- Describe `Caip19AssetType`
- Add some text about how the rates are represented

* More improvements
- Allow data URI and URL for token icons
- Make conversion rate expiration time optional
- Add note about asset filtering if out of scope
- Remove native key from asset description
- Typo fixes

* address requested changes

---------

Co-authored-by: Guillaume Roux <[email protected]>
Co-authored-by: Charly Chevalier <[email protected]>
Co-authored-by: Frederik Bolding <[email protected]>
Co-authored-by: Maarten Zuidhoorn <[email protected]>
Co-authored-by: Guillaume Roux <[email protected]>
  • Loading branch information
6 people authored Jan 22, 2025
1 parent bea5f93 commit 6397726
Showing 1 changed file with 191 additions and 0 deletions.
191 changes: 191 additions & 0 deletions SIPS/sip-29.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
---
sip: 29
title: Snap Assets API
status: Draft
author: Daniel Rocha (@danroc), Guillaume Roux (@GuillaumeRx)
created: 2024-12-05
---

## Abstract

This SIP aims to define a new API that can be exposed by Snaps to allow clients
to retrieve asset information in a chain-agnostic way.

## Motivation

To enable clients to be chain-agnostic, the logic for obtaining asset
information should be abstracted away from the client. Additionally, this SIP
defines the types that represent the asset information required by clients.

## Specification

> Indented sections like this are considered non-normative.
### Language

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
"SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" written
in uppercase in this document are to be interpreted as described in [RFC
2119](https://www.ietf.org/rfc/rfc2119.txt)

### Definitions

1. In this document, all definitions are written in TypeScript.

2. Any time an asset needs to be identified, it MUST use the [CAIP-19][caip-19]
representation.

### Snap Manifest

This SIP introduces a new permission named `endowment:assets`.
This permission grants a Snap the ability to provide asset information to the client.

This permission is specified as follows in `snap.manifest.json` files:

```json
{
"initialPermissions": {
"endowment:assets": {
"scopes": [
"bip122:000000000019d6689c085ae165831e93"
]
}
}
}
```

`scopes` - A non-empty array of CAIP-2 chain IDs that the Snap supports. This field is useful for a client in order to avoid unnecessary overhead. Any asset returned by the Snap MUST be filtered out if it isn't part of the supported scopes.

### Snap Implementation

Two methods are defined in the Snap Assets API:

Any Snap that wishes to provide asset information MUST implement the following API:

#### Get Assets Metadata

`Caip19AssetType` - A string that represents an asset using the [CAIP-19][caip-19] standard.

```typescript
import { OnAssetsLookupHandler } from "@metamask/snaps-sdk";

export const onAssetsLookup: OnAssetsLookupHandler = async ({
assets
}) => {
const assetsMetadata = /* Get metadata for given `assets` */;
return { assets: assetsMetadata };
};
```

The type for an `onAssetsLookup` handler function’s arguments is:

```typescript
interface OnAssetsLookupArguments {
assets: Caip19AssetType[];
}
```

The type for an `onAssetsLookup` handler function’s return value is:

```typescript
type OnAssetsLookupResponse = {
assets: Record<Caip19AssetType, AssetMetadata>;
};
```

#### Get Assets Conversion Rate

```typescript
import { OnAssetsConversionHandler } from "@metamask/snaps-sdk";

export const onAssetsConversion: OnAssetsConversionHandler = async ({
conversions
}) => {
const conversionRates = /* Get conversion rate for given `conversions` */;
return { conversionRates };
};
```

The type for an `onAssetsConversion` handler function’s arguments is:

```typescript
type Conversion = {
from: Caip19AssetType;
to: Caip19AssetType;
};

type OnAssetsConversionArguments = {
conversions: Conversion[];
};
```

The type for an `onAssetsConversion` handler function’s return value is:

```typescript
type AssetConversionRate = {
// The rate of conversion from the source asset to the target asset represented as a decimal number in a string.
// It means that 1 unit of the `from` asset should be converted to this amount
// of the `to` asset.
rate: string;

// The UNIX timestamp of when the conversion rate was last updated.
conversionTime: number;

// The UNIX timestamp of when the conversion rate will expire.
expirationTime?: number;
};

type FromAsset = Conversion["from"];

type ToAsset = Conversion["to"];

type OnAssetsConversionResponse = {
conversionRates: Record<From, Record<To, AssetConversionRate>>;
};
```

## Appendix I: Fungible Asset Metadata

The following asset metadata fields for a fungible asset are defined.
As of the time of creation of this SIP, they are the only possible assets requested by clients.

```typescript
// Represents an asset unit.
type FungibleAssetUnit = {
// Human-friendly name of the asset unit.
name: string;

// Ticker symbol of the asset unit.
symbol: string;

// Number of decimals of the asset unit.
decimals: number;
};

// Fungible asset metadata.
type FungibleAssetMetadata = {
// Human-friendly name of the asset.
name: string;

// Ticker symbol of the asset's main unit.
symbol: string;

// Represents a fungible asset
fungible: true;

// Base64 data URI or URL representation of the asset icon.
iconUrl: string;

// List of asset units.
units: FungibleAssetUnit[];
};

// Represents the metadata of an asset.
type AssetMetadata = FungibleAssetMetadata
```
## Copyright
Copyright and related rights waived via [CC0](../LICENSE).
[caip-19]: https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-19.md

0 comments on commit 6397726

Please sign in to comment.