droplinked-web3-kit 0.0.3 β 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +220 -109
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,101 +1,224 @@
|
|
|
1
|
-
# Web3
|
|
1
|
+
# Droplinked Web3 Kit β Developer Guide π
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
---
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
1. Overview
|
|
8
|
+
2. Core Concepts
|
|
9
|
+
3. Authentication (Login via Wallet)
|
|
10
|
+
- Metamask | Phantom Wallet (Standard Login)
|
|
11
|
+
- Unstoppable Domains Login
|
|
12
|
+
4. Recording Products on-chain
|
|
13
|
+
- Record Procedure
|
|
14
|
+
- Custom Errors
|
|
15
|
+
5. Payments
|
|
16
|
+
- Payment Procedure
|
|
17
|
+
- Supported Chains & Tokens
|
|
18
|
+
6. Example Flows (End-to-End)
|
|
19
|
+
7. Notes & Assumptions
|
|
20
|
+
8. Open Questions (please confirm)
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 1) Overview
|
|
25
|
+
|
|
26
|
+
**Droplinked Web3 Kit** exposes a single entry class `DropWeb3` configured with an environment `Network` (e.g., `TESTNET`, `MAINNET`) and a `shopId` (as shown in the examples). From that instance, you create a **provider** through `web3Instance(...)` that is specialized by `Web3Actions` such as `LOGIN`, `RECORD`, or `PAYMENT`. Subsequent methods (e.g., `walletLogin`, `unstoppableLogin`, `recordProduct`, `payment`) execute the corresponding flow.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 2) Core Concepts
|
|
31
|
+
|
|
32
|
+
- **DropWeb3:** Root object created per environment + shopId.
|
|
33
|
+
- **Web3Actions:** Selects the high-level intent: `LOGIN`, `RECORD`, `PAYMENT`.
|
|
34
|
+
- **Chain & ChainWallet:** Choose the blockchain (e.g., `POLYGON`, `BINANCE`) and wallet (e.g., `Metamask`, `UnstoppableDomains`, `Phantom`) for the action.
|
|
35
|
+
- **Provider:** Returned by `web3Instance(...)`, it exposes the concrete method(s) for the chosen action (e.g., `walletLogin`, `unstoppableLogin`, `recordProduct`, `payment`).
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 3) Authentication (Login via Wallet) π
|
|
40
|
+
|
|
41
|
+
### 3.1 Metamask (Standard Login)
|
|
42
|
+
|
|
43
|
+
**Purpose:** Obtain user address and signature by prompting the userβs wallet.
|
|
44
|
+
**Flow:**
|
|
45
|
+
|
|
46
|
+
1) Instantiate `DropWeb3` with `Network` and token.
|
|
47
|
+
2) Create a `LOGIN` provider with your preferred wallet (`Metamask` | `Phantom`).
|
|
48
|
+
3) Call `walletLogin()`.
|
|
49
|
+
|
|
50
|
+
**ChainWallets**
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
Metamask | CoinBase | CasperWallet (Deprecated) | Phantom | BaseSmartWallet | UnstoppableDomains
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Chains**
|
|
6
57
|
|
|
7
58
|
```js
|
|
59
|
+
export enum Chain {
|
|
60
|
+
CASPER = 'CASPER',
|
|
61
|
+
POLYGON = 'POLYGON',
|
|
62
|
+
BINANCE = 'BINANCE',
|
|
63
|
+
STACKS = 'STACKS',
|
|
64
|
+
XRPLSIDECHAIN = 'XRPLSIDECHAIN',
|
|
65
|
+
NEAR = 'NEAR',
|
|
66
|
+
SKALE = 'SKALE',
|
|
67
|
+
BASE = 'BASE',
|
|
68
|
+
LINEA = 'LINEA',
|
|
69
|
+
ETH = 'ETH',
|
|
70
|
+
SOLANA = 'SOLANA',
|
|
71
|
+
REDBELLY = 'REDBELLY',
|
|
72
|
+
UNSTOPPABLE = 'UNSTOPPABLE',
|
|
73
|
+
BITLAYER = 'BITLAYER',
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Example:**
|
|
78
|
+
|
|
79
|
+
```ts
|
|
8
80
|
// Create web3 object
|
|
9
|
-
const web3 = new DropWeb3(Network.TESTNET,
|
|
81
|
+
const web3 = new DropWeb3(Network.TESTNET, shopId);
|
|
10
82
|
|
|
11
|
-
//
|
|
83
|
+
// Create the chain provider for login
|
|
12
84
|
const chainProvider = await web3.web3Instance({
|
|
13
|
-
|
|
14
|
-
|
|
85
|
+
method: Web3Actions.LOGIN,
|
|
86
|
+
preferredWallet: ChainWallet.Metamask,
|
|
15
87
|
});
|
|
16
88
|
|
|
17
|
-
//
|
|
89
|
+
// Prompt wallet & get login result
|
|
18
90
|
const loginData = await chainProvider.walletLogin();
|
|
19
91
|
|
|
20
|
-
// Log the results
|
|
21
92
|
console.log({
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
93
|
+
address: loginData.address,
|
|
94
|
+
date: loginData.date,
|
|
95
|
+
nonce: loginData.nonce,
|
|
96
|
+
signature: loginData.signature,
|
|
26
97
|
});
|
|
27
98
|
```
|
|
28
99
|
|
|
29
|
-
|
|
100
|
+
**Expected fields:** `address`, `date`, `nonce`, `signature`.
|
|
30
101
|
|
|
31
|
-
|
|
32
|
-
|
|
102
|
+
### 3.2 Unstoppable Domains Login
|
|
103
|
+
|
|
104
|
+
**Purpose:** Authenticate with Unstoppable Domains using a UD key and redirect origin.
|
|
105
|
+
**Flow:**
|
|
106
|
+
|
|
107
|
+
1) Instantiate `DropWeb3`.
|
|
108
|
+
2) Create a `LOGIN` provider with `ChainWallet.UnstoppableDomains`.
|
|
109
|
+
3) Call `unstoppableLogin(udKey, origin)`.
|
|
110
|
+
|
|
111
|
+
**Example:**
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
const web3 = new DropWeb3(Network.TESTNET, shopId);
|
|
33
115
|
|
|
34
116
|
const chainProvider = await web3.web3Instance({
|
|
35
|
-
|
|
36
|
-
|
|
117
|
+
method: Web3Actions.LOGIN,
|
|
118
|
+
preferredWallet: ChainWallet.UnstoppableDomains,
|
|
37
119
|
});
|
|
38
120
|
|
|
39
121
|
const loginData = await chainProvider.unstoppableLogin(
|
|
40
|
-
|
|
41
|
-
|
|
122
|
+
'de81c772-62be-45ed-8d0b-103abfec2ab8', // UD Key
|
|
123
|
+
window.location.origin
|
|
42
124
|
);
|
|
43
125
|
|
|
44
126
|
console.log({ loginData });
|
|
45
127
|
```
|
|
46
128
|
|
|
47
|
-
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## 4) Recording Products on-chain π§Ύ
|
|
48
132
|
|
|
49
|
-
|
|
50
|
-
const blockchain = "POLYGON"; // The blockchain where the product will be recorded
|
|
51
|
-
const productId = "your-product-id"; // The ID of the product to be recorded
|
|
52
|
-
const accountAddress = "user-wallet-address"; // The user's wallet address, can be empty string to prompt connection
|
|
53
|
-
const shopId = "your-shop-id"; // The ID of the shop where the product will be recorded
|
|
133
|
+
### 4.1 Record Procedure
|
|
54
134
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
135
|
+
**Purpose:** Record a product to a specific blockchain for a given shop.
|
|
136
|
+
**Inputs (from your example):**
|
|
137
|
+
|
|
138
|
+
- `blockchain` (string name matching `Chain[...]`)
|
|
139
|
+
- `productId`
|
|
140
|
+
- `accountAddress` (can be `''` to trigger wallet connect)
|
|
141
|
+
- `shopId`
|
|
142
|
+
- `Network` selection (TESTNET/MAINNET)
|
|
143
|
+
- `preferredWallet` (e.g., `Metamask`)
|
|
144
|
+
|
|
145
|
+
**Flow:**
|
|
146
|
+
|
|
147
|
+
1) Instantiate `DropWeb3` with environment and `shopId`.
|
|
148
|
+
2) Create a `RECORD` provider for the desired chain.
|
|
149
|
+
3) Call `recordProduct(productId)` and handle the response.
|
|
150
|
+
|
|
151
|
+
**Example:**
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
const blockchain = "POLYGON";
|
|
155
|
+
const productId = "your-product-id";
|
|
156
|
+
const accountAddress = "user-wallet-address"; // empty string -> prompts wallet connect
|
|
157
|
+
const shopId = "your-shop-id";
|
|
158
|
+
|
|
159
|
+
const web3 = new DropWeb3(
|
|
160
|
+
appDevelopment ? Network.TESTNET : Network.MAINNET,
|
|
161
|
+
shopId
|
|
58
162
|
);
|
|
59
163
|
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
164
|
+
const provider = await web3.web3Instance({
|
|
165
|
+
method: Web3Actions.RECORD,
|
|
166
|
+
chain: Chain[blockchain],
|
|
167
|
+
preferredWallet: ChainWallet.Metamask,
|
|
168
|
+
userAddress: accountAddress, // if '', user is prompted to connect
|
|
65
169
|
});
|
|
66
170
|
|
|
67
|
-
let
|
|
68
|
-
record
|
|
69
|
-
|
|
70
|
-
return record;
|
|
171
|
+
let record: RecordResponse = await provider.recordProduct(productId);
|
|
172
|
+
return record;
|
|
71
173
|
```
|
|
72
174
|
|
|
73
|
-
### Custom
|
|
175
|
+
### 4.2 Custom Errors (import & check as needed)
|
|
74
176
|
|
|
75
|
-
- `ChainNotImplementedException
|
|
76
|
-
- `Unauthorized
|
|
77
|
-
- `FieldNotFound
|
|
78
|
-
- `Web3CallbackFailed
|
|
79
|
-
- `MetadataUploadFailedException
|
|
80
|
-
- `WalletNotFoundException
|
|
81
|
-
- `AccountAccessDeniedException
|
|
82
|
-
- `NoAccountsFoundException
|
|
83
|
-
- `SignatureRequestDeniedException
|
|
84
|
-
- `ChainSwitchException
|
|
85
|
-
- `UserDeniedException
|
|
177
|
+
- `ChainNotImplementedException`
|
|
178
|
+
- `Unauthorized`
|
|
179
|
+
- `FieldNotFound` (missing `nftContractAddress`/`shopContractAddress`)
|
|
180
|
+
- `Web3CallbackFailed`
|
|
181
|
+
- `MetadataUploadFailedException`
|
|
182
|
+
- `WalletNotFoundException`
|
|
183
|
+
- `AccountAccessDeniedException`
|
|
184
|
+
- `NoAccountsFoundException`
|
|
185
|
+
- `SignatureRequestDeniedException`
|
|
186
|
+
- `ChainSwitchException`
|
|
187
|
+
- `UserDeniedException`
|
|
86
188
|
|
|
87
|
-
|
|
189
|
+
> Use these to provide user-friendly messages and remediation (e.g., ask to install wallet, approve access, switch network).
|
|
88
190
|
|
|
89
|
-
|
|
191
|
+
---
|
|
90
192
|
|
|
91
|
-
|
|
193
|
+
## 5) Payments π³
|
|
194
|
+
|
|
195
|
+
### 5.1 Payment Procedure
|
|
196
|
+
|
|
197
|
+
**Purpose:** Execute a crypto payment for an order using a specified token and chain.
|
|
198
|
+
**Inputs (from your example):**
|
|
199
|
+
|
|
200
|
+
- `shopId`
|
|
201
|
+
- `orderId`
|
|
202
|
+
- `paymentToken` (enum)
|
|
203
|
+
- `paymentType` (enum `Chain`)
|
|
204
|
+
- `userAddress` (optional: empty string will prompt wallet connect)
|
|
205
|
+
|
|
206
|
+
**Flow:**
|
|
207
|
+
|
|
208
|
+
1) Instantiate `DropWeb3` with environment and `shopId`.
|
|
209
|
+
2) Create a `PAYMENT` provider for the target chain.
|
|
210
|
+
3) Call `payment({ orderID, paymentToken, paymentType })`.
|
|
211
|
+
|
|
212
|
+
**Example:**
|
|
213
|
+
|
|
214
|
+
```ts
|
|
92
215
|
import {
|
|
93
|
-
Chain,
|
|
94
|
-
ChainWallet,
|
|
95
|
-
DropWeb3,
|
|
96
|
-
Network,
|
|
97
|
-
PaymentTokens,
|
|
98
|
-
Web3Actions,
|
|
216
|
+
Chain,
|
|
217
|
+
ChainWallet,
|
|
218
|
+
DropWeb3,
|
|
219
|
+
Network,
|
|
220
|
+
PaymentTokens,
|
|
221
|
+
Web3Actions,
|
|
99
222
|
} from 'droplinked-web3-kit';
|
|
100
223
|
|
|
101
224
|
const shopId = '66d47d965744cb21dac659ab';
|
|
@@ -103,71 +226,59 @@ const orderId = '5a4fc3e56134cb23cba014dc';
|
|
|
103
226
|
const paymentMethod = 'USDC';
|
|
104
227
|
const paymentType = 'BINANCE';
|
|
105
228
|
|
|
106
|
-
// Create Web3 Object
|
|
107
229
|
const web3 = new DropWeb3(Network.TESTNET, shopId);
|
|
108
230
|
|
|
109
|
-
// Get a provider instance
|
|
110
231
|
const instance = await web3.web3Instance({
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
232
|
+
method: Web3Actions.PAYMENT,
|
|
233
|
+
chain: Chain[paymentType],
|
|
234
|
+
preferredWallet: ChainWallet.Metamask,
|
|
235
|
+
userAddress: '0xYourWalletAddressHere', // or '' to prompt connect
|
|
115
236
|
});
|
|
116
237
|
|
|
117
|
-
// Call the payment method
|
|
118
238
|
const result = await instance.payment({
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
239
|
+
orderID: orderId,
|
|
240
|
+
paymentToken: PaymentTokens[paymentMethod],
|
|
241
|
+
paymentType: Chain[paymentType],
|
|
122
242
|
});
|
|
123
243
|
|
|
124
|
-
// Log the results
|
|
125
244
|
console.log({
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
245
|
+
orderID: result.orderID,
|
|
246
|
+
cryptoAmount: result.cryptoAmount,
|
|
247
|
+
transactionHash: result.transactionHash,
|
|
248
|
+
transactionId: result.transactionId,
|
|
130
249
|
});
|
|
131
250
|
```
|
|
132
251
|
|
|
133
|
-
|
|
252
|
+
**Returned fields:** typical payment metadata like `cryptoAmount`, `transactionHash`, `transactionId` (names based on your example).
|
|
134
253
|
|
|
135
|
-
|
|
254
|
+
### 5.2 Supported Enums
|
|
136
255
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
SOL = "SOL",
|
|
142
|
-
USDC = "USDC",
|
|
143
|
-
USDT = "USDT",
|
|
144
|
-
MEW = "MEW",
|
|
145
|
-
BNB = "BNB",
|
|
146
|
-
MATIC = "MATIC",
|
|
147
|
-
CSPR = "CSPR",
|
|
148
|
-
PARAM = "PARAM",
|
|
149
|
-
BDC = "BDC",
|
|
150
|
-
BTC = "BTC"
|
|
151
|
-
}
|
|
256
|
+
**Payment Tokens**
|
|
257
|
+
|
|
258
|
+
```
|
|
259
|
+
ETH | RBNT | SOL | USDC | USDT | MEW | BNB | MATIC | CSPR | PARAM | BDC | BTC
|
|
152
260
|
```
|
|
153
261
|
|
|
154
|
-
Chains
|
|
262
|
+
**Chains**
|
|
155
263
|
|
|
156
|
-
```js
|
|
157
|
-
export declare enum Chain {
|
|
158
|
-
CASPER = "CASPER",
|
|
159
|
-
POLYGON = "POLYGON",
|
|
160
|
-
BINANCE = "BINANCE",
|
|
161
|
-
STACKS = "STACKS",
|
|
162
|
-
XRPLSIDECHAIN = "XRPLSIDECHAIN",
|
|
163
|
-
NEAR = "NEAR",
|
|
164
|
-
SKALE = "SKALE",
|
|
165
|
-
BASE = "BASE",
|
|
166
|
-
LINEA = "LINEA",
|
|
167
|
-
ETH = "ETH",
|
|
168
|
-
SOLANA = "SOLANA",
|
|
169
|
-
REDBELLY = "REDBELLY",
|
|
170
|
-
UNSTOPPABLE = "UNSTOPPABLE",
|
|
171
|
-
BITLAYER = "BITLAYER"
|
|
172
|
-
}
|
|
173
264
|
```
|
|
265
|
+
CASPER | POLYGON | BINANCE | STACKS | XRPLSIDECHAIN | NEAR | SKALE | BASE | LINEA | ETH | SOLANA | REDBELLY | UNSTOPPABLE | BITLAYER
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Use `PaymentTokens[<TOKEN>]` and `Chain[<CHAIN>]` for type-safe invocation.
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## 6) Example Flows (End-to-End) π§
|
|
273
|
+
|
|
274
|
+
### 6.1 Login β Record
|
|
275
|
+
|
|
276
|
+
1) `LOGIN` via Metamask (`walletLogin`) to obtain `address`.
|
|
277
|
+
2) `RECORD` with `userAddress` set to the login address.
|
|
278
|
+
3) `recordProduct(productId)` and store the `RecordResponse` in your system.
|
|
279
|
+
|
|
280
|
+
### 6.2 Login β Pay
|
|
281
|
+
|
|
282
|
+
1) `LOGIN` to obtain `address`.
|
|
283
|
+
2) `PAYMENT` with `userAddress` or let it prompt the wallet.
|
|
284
|
+
3) `payment({ orderID, paymentToken, paymentType })`, then persist `transactionHash`/`transactionId`.
|