-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SIP-29: Snap Assets API #154
base: main
Are you sure you want to change the base?
Changes from all commits
7a1176b
8f7b7d0
f0a9807
03b33e5
5712f64
ec71c69
5657a9c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,232 @@ | ||
--- | ||
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. | ||
|
||
### 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 Asset Metadata | ||
|
||
```typescript | ||
import { OnAssetLookupHandler } from "@metamask/snaps-sdk"; | ||
|
||
export const onAssetLookup: OnAssetLookupHandler = async ({ | ||
assets | ||
}) => { | ||
const assetsMetadata = /* Get metadata */; | ||
return { assets: assetsMetadata }; | ||
}; | ||
``` | ||
|
||
The type for an `onAssetLookup` handler function’s arguments is: | ||
|
||
```typescript | ||
interface OnAssetLookupArgs { | ||
assets: Caip19AssetType[]; | ||
} | ||
``` | ||
|
||
The type for an `onAssetLookup` handler function’s return value is: | ||
|
||
```typescript | ||
type OnAssetLookupReturn = { | ||
assets: Record<Caip19AssetType, AssetMetadata>; | ||
}; | ||
``` | ||
|
||
#### Get Asset Conversion Rate | ||
|
||
```typescript | ||
import { OnAssetConversionHandler } from "@metamask/snaps-sdk"; | ||
|
||
export const onAssetConversion: OnAssetConversionHandler = async ({ | ||
conversions | ||
}) => { | ||
const conversionRates = /* Get conversion rate */; | ||
return { conversionRates }; | ||
}; | ||
``` | ||
|
||
The type for an `onAssetConversion` handler function’s arguments is: | ||
|
||
```typescript | ||
type Conversion = { | ||
from: Caip19AssetType; | ||
to: Caip19AssetType; | ||
}; | ||
|
||
type OnAssetConversionArgs = { | ||
conversions: Conversion[]; | ||
}; | ||
``` | ||
|
||
The type for an `onAssetConversion` handler function’s return value is: | ||
|
||
```typescript | ||
type AssetConversionRate = { | ||
// The rate of conversion from the source asset to the target asset. 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 OnAssetConversionReturn = { | ||
conversionRates: Record<From, Record<To, AssetConversionRate>>; | ||
}; | ||
``` | ||
|
||
### Fiat currency representation | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should create a CAIP for this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a good point. This is technically CAIP-19, but with unregistered namespaces. I started a discussion on the CAIPs repo, let's see what other think of it. |
||
|
||
We SHOULD use CAIP-19 to represent fiat currencies as well. This approach | ||
provides a consistent way to represent all assets, making the API more | ||
predictable. The proposed format is: | ||
|
||
``` | ||
asset_type: chain_id + "/" + asset_namespace + ":" + asset_reference | ||
chain_id: namespace + ":" + reference | ||
namespace: "fiat" | ||
reference: country_code | ||
asset_namespace: "currency" | ||
asset_reference: currency_code | ||
``` | ||
|
||
The country code is a two-letter lowercase code, as defined by ISO 3166-1 | ||
alpha-2, representing the emitter country, with the exception of the European | ||
Union, which is represented by "eu". | ||
|
||
The currency code is a three-letter uppercase code as defined by ISO 4217. | ||
|
||
Examples: | ||
|
||
``` | ||
# Euro | ||
fiat:eu/currency:eur | ||
|
||
# United States Dollar | ||
fiat:us/currency:usd | ||
|
||
# Brazilian Real | ||
fiat:br/currency:brl | ||
|
||
# Japanese Yen | ||
fiat:jp/currency:jpy | ||
``` | ||
|
||
## 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; | ||
|
||
// Whether the asset is native to the chain. | ||
native: boolean; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some examples might be differentiating between brc-20 and rune tokens on bitcoin. Or eth, erc20s, and staking contracts on ethereum. I anticipate more types of tokens than just native vs not. Not sure if anything built into caip19 already helps distinguish this. |
||
|
||
// Represents a fungible asset | ||
fungible: true; | ||
|
||
// Base64 representation of the asset icon. | ||
iconBase64: string; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it has to be an icon, the static token icon server is going to return pngs |
||
|
||
// List of asset units. | ||
units: FungibleAssetUnit[]; | ||
}; | ||
``` | ||
|
||
## Backwards compatibility | ||
|
||
Any SIPs that break backwards compatibility MUST include a section describing | ||
those incompatibilities and their severity. The SIP SHOULD describe how the | ||
author plans on proposes to deal with such these incompatibilities. | ||
|
||
## Copyright | ||
|
||
Copyright and related rights waived via [CC0](../LICENSE). | ||
|
||
[caip-19]: https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-19.md |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.