Skip to content

Commit 7506b74

Browse files
committed
token-init.md
1 parent 533d5ce commit 7506b74

File tree

2 files changed

+72
-1
lines changed

2 files changed

+72
-1
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ flowchart LR
114114
- `filter` — library for filtering geyser messages
115115
- `plugin-agave` — Agave validator geyser plugin https://docs.anza.xyz/validator/geyser
116116
- `proto` — library with proto files, re-imports structs from crate `yellowstone-grpc-proto`
117-
- `richat` — app with full stream consumer and producers: gRPC (`Dragon's Mouth`), Solana PubSub
117+
- `richat` — app with full stream consumer and producers: gRPC (`Dragon's Mouth`), Solana PubSub (with [transactionSubscribe](https://github.com/solana-foundation/solana-improvement-documents/pull/69) and [tokenInitSubscribe](./token-init.md))
118118
- `shared` — shared code between components (except `client`)
119119

120120
## Releases
@@ -125,6 +125,7 @@ flowchart LR
125125
- `agave-v2.0` — development branch for agave v2.0
126126
- `agave-v2.1` — development branch for agave v2.1
127127
- `agave-v2.2` — development branch for agave v2.2
128+
- `agave-v2.3` — development branch for agave v2.3
128129

129130
#### Tags
130131

token-init.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# tokenInitSubscribe
2+
3+
In summer 2021 [Tritone One](https://triton.one/) introduced [transactionSubscribe](https://github.com/solana-foundation/solana-improvement-documents/pull/69). This was an obvious addition to existing subscribe methods in [Whirligig](https://docs.triton.one/project-yellowstone/whirligig-websockets) — a project that consumes [Geyser gRPC](https://github.com/rpcpool/yellowstone-grpc) stream and implements Agave PubSub interface. Later, [Helius](https://www.helius.dev/) implemented [SIMD-0065](https://github.com/solana-foundation/solana-improvement-documents/pull/69) spec in their [Enhanced Websockets](https://www.helius.dev/docs/enhanced-websockets/transaction-subscribe).
4+
5+
It looked like all methods in Agave Pubsub + `transactionSubscribe` allowed to build great Solana Wallets but we still don't have coverage of the case when somebody creates Token Account for you, that's why wallets sometimes need to call `getTokenAccountsByOwner` for syncing. I decided to fill this gap and move wallets from polling same data to getting events with a new method `tokenInitSubscribe`.
6+
7+
## Spec
8+
9+
### Abstract Rust code for Agave
10+
11+
```
12+
#[derive(Debug, Serialize)]
13+
struct RpcTokenInitResponse {
14+
accounts: Vec<String>,
15+
signature: String,
16+
}
17+
18+
#[derive(Debug, Default, Deserialize)]
19+
#[serde(rename_all = "camelCase")]
20+
struct ReqTokenInitConfig {
21+
#[serde(flatten)]
22+
pub commitment: Option<CommitmentConfig>,
23+
}
24+
25+
#[allow(clippy::needless_return)]
26+
#[rpc]
27+
pub trait RpcSolPubSub {
28+
type Metadata;
29+
30+
#[pubsub(
31+
subscription = "tokenInitNotification",
32+
subscribe,
33+
name = "tokenInitSubscribe"
34+
)]
35+
fn token_init_subscribe(
36+
&self,
37+
meta: Self::Metadata,
38+
subscriber: Subscriber<RpcResponse<RpcTokenInitResponse>>,
39+
pubkey_str: String,
40+
config: Option<ReqTokenInitConfig>,
41+
);
42+
43+
#[pubsub(
44+
subscription = "tokenInitNotification",
45+
unsubscribe,
46+
name = "tokenInitUnsubscribe"
47+
)]
48+
fn token_init_unsubscribe(
49+
&self,
50+
meta: Option<Self::Metadata>,
51+
id: PubSubSubscriptionId,
52+
) -> Result<bool>;
53+
}
54+
```
55+
56+
## Possible syncing process in abstract Solana Wallet
57+
58+
For simplicity I propose to request only confirmed data (and optionally show spinning while they are not finalized).
59+
60+
1. Subscribe to Account updates with `accountSubscribe`, `transactionSubscribe` and `tokenInitSubscribe`
61+
2. Subscribe to slots with `slotsUpdatesSubscribe`, monitor confirmed and finalized
62+
3. Request all Token Accounts with `getTokenAccountsByOwner` with `minContextSlot` (should be the slot that you received from WebSocket connection from `slotsUpdates` subscription, i.e. we request data only at least from the moment when we already subscribed on them)
63+
4. Subscribe to all Token Accounts with `accountSubscribe` and re-subscribe with `transactionSubscribe` (`transactionSubscribe` allows multiple addresses in one subscription)
64+
5. Request current state for Account and all Token Accounts with `getMultipleAccounts` with `minContextSlot`
65+
6. Request history for Account and all Token Accounts with `getSignaturesForAddress` with `minContextSlot`
66+
7. If an account update for Token Account is received with owner as System Program and lamports as zero then Token Account is closed (alternatively you can parse transaction from `transactionSubscribe` and parse inner instructions to lookup `CloseAccount` instruction)
67+
8. If a message from `tokenInitSubscribe` is received wallet needs:
68+
1. Subscribe to the new Token Account with `accountSubscribe` and modify `transactionSubscribe`
69+
2. Request current state with `getAccountInfo` with `minContextSlot`
70+
3. Request history with `getSignaturesForAddress` with `minContextSlot`

0 commit comments

Comments
 (0)