Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ program
.name('create-wdk-module')
.description('Create WDK modules with a single command')
.version('1.0.0-beta.1')
.argument('[type]', 'Module type (wallet/swap/bridge/lending/fiat/swidge)')
.argument('[type]', 'Module type (wallet/swap/bridge/lending/fiat/swidge/sda)')
.argument('[name]', 'Module name')
.argument('[blockchain]', 'Target blockchain (for protocol modules)')
.option('-s, --scope <SCOPE>', 'npm scope (e.g., @myorg)')
Expand All @@ -42,7 +42,7 @@ program
.action(async (type, name, blockchain, { scope, git, yes }) => {
if (type && !validateModuleType(type)) {
console.error(pc.red(`Invalid module type: ${type}`))
console.error(pc.dim('Valid types: wallet, swap, bridge, lending, fiat, swidge'))
console.error(pc.dim('Valid types: wallet, swap, bridge, lending, fiat, swidge, sda'))
process.exit(1)
}

Expand Down
17 changes: 15 additions & 2 deletions src/create-wdk-module.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ import { compileTemplate } from './compile-template.js'
import { gitInit, getGitAuthor, isGitAvailable } from './utilities/git.js'

/**
* @typedef {'wallet' | 'swap' | 'bridge' | 'lending' | 'fiat' | 'swidge'} ModuleType
* @typedef {'wallet' | 'swap' | 'bridge' | 'lending' | 'fiat' | 'swidge' | 'sda'} ModuleType
*/

/**
* @typedef {CreateWdkModuleCommonOptions & (CreateWdkModuleWalletOptions | CreateWdkModuleProtocolOptions | CreateWdkModuleFiatProviderOptions | CreateWdkModuleSwidgeOptions)} CreateWdkModuleOptions
* @typedef {CreateWdkModuleCommonOptions & (CreateWdkModuleWalletOptions | CreateWdkModuleProtocolOptions | CreateWdkModuleFiatProviderOptions | CreateWdkModuleSwidgeOptions | CreateWdkModuleSdaOptions)} CreateWdkModuleOptions
*/

/**
Expand Down Expand Up @@ -61,6 +61,12 @@ import { gitInit, getGitAuthor, isGitAvailable } from './utilities/git.js'
* @property {string} name - The swidge protocol's name.
*/

/**
* @typedef {Object} CreateWdkModuleSdaOptions
* @property {'sda'} type - The module type to create.
* @property {string} name - The SDA provider's name.
*/

const ROOT_DIR = path.dirname(fileURLToPath(import.meta.url))

const TEMPLATES_DIR = path.resolve(ROOT_DIR, '../templates')
Expand Down Expand Up @@ -92,6 +98,10 @@ function generatePackageName ({ type, name, blockchain, scope }) {
case 'swidge':
packageName = `wdk-protocol-swidge-${name}`
break

case 'sda':
packageName = `wdk-protocol-sda-${name}`
break
}

if (scope) {
Expand Down Expand Up @@ -123,6 +133,9 @@ function generateDescription (type, { name, blockchain }) {

case 'swidge':
return `WDK module to perform cross-chain swaps via the ${name} protocol.`

case 'sda':
return `WDK module to convert and deliver deposits to USDT via the ${name} smart deposit address provider.`
}
}

Expand Down
6 changes: 5 additions & 1 deletion src/run-prompts.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ export async function runPrompts (options, useDefaults = false) {
{ title: 'Bridge Module', description: 'Cross-chain bridging', value: 'bridge' },
{ title: 'Lending Module', description: 'DeFi lending protocol', value: 'lending' },
{ title: 'Fiat Module', description: 'Fiat on/off-ramp', value: 'fiat' },
{ title: 'Swidge Module', description: 'Cross-chain swap (swidge = swap + bridge)', value: 'swidge' }
{ title: 'Swidge Module', description: 'Cross-chain swap (swidge = swap + bridge)', value: 'swidge' },
{ title: 'SDA Module', description: 'Smart Deposit Address (deposit-and-convert to USDT)', value: 'sda' }
]
})
}
Expand All @@ -68,6 +69,9 @@ export async function runPrompts (options, useDefaults = false) {

case 'swidge':
return 'What is the protocol name? (e.g., "lifi", "rhino")'

case 'sda':
return 'What is the provider name? (e.g., "rhino", "orchestra")'
}
},
validate: (value) => {
Expand Down
2 changes: 1 addition & 1 deletion src/utilities/validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const MODULE_NAME_PATTERN = /^[a-z][a-z0-9-.]*$/
* @returns {boolean} Whether the type is valid.
*/
export function validateModuleType (type) {
return ['wallet', 'swap', 'bridge', 'lending', 'fiat', 'swidge'].includes(type)
return ['wallet', 'swap', 'bridge', 'lending', 'fiat', 'swidge', 'sda'].includes(type)
}

/**
Expand Down
99 changes: 99 additions & 0 deletions templates/sda/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# {{PACKAGE_NAME}}

{{DESCRIPTION}}

A Smart Deposit Address (SDA) module: the provider issues a deposit address, the
user sends a supported stablecoin (or native token) from any supported source
chain, and the provider converts it and delivers the destination asset (e.g.
USDT) to the destination chain and address.

## Installation

```bash
npm install {{PACKAGE_NAME}}
```

## Usage

```javascript
import {{pascalCase NAME}}Protocol from '{{PACKAGE_NAME}}'

// Create the SDA protocol (account is optional; its address is the default destination)
const sda = new {{pascalCase NAME}}Protocol(account, { apiKey: '...' })

// Discover supported routes (source chains, input tokens, output assets, limits)
const routes = await sda.getSupportedRoutes({ outputAsset: 'USDT' })

// Optionally fetch a non-binding quote before funding the address
// (throws UnsupportedOperationError if the provider does not support quoting)
const quote = await sda.quoteDeposit({
sourceChain: 'arbitrum',
inputToken: 'USDC',
destinationChain: 'polygon',
outputAsset: 'USDT',
inputAmount: 1000000n
})

console.log('Quote:', quote)

// Create a deposit address for the user to send funds to
const deposit = await sda.createDepositAddress({
sourceChains: ['arbitrum'],
destinationChain: 'polygon',
outputAsset: 'USDT',
destinationAddress: '0x...'
})

console.log('Send funds to:', deposit.address)

// Track deposits observed at the address
const transfers = await sda.getTransfers(deposit.address)
console.log('Transfers:', transfers)
```

## API Reference

### {{pascalCase NAME}}Protocol

#### Constructor

```javascript
new {{pascalCase NAME}}Protocol(account?, config?)
```

- `account` - Wallet account (optional; its address is the default delivery destination)
- `config` - Protocol configuration (optional)
- `apiUrl` - Overrides the provider's API base URL (optional)
- `apiKey` - The provider API key, when required (optional)

#### Required methods

- `getSupportedRoutes(options?)` - List supported routes, input tokens and limits
- `createDepositAddress(options)` - Create a deposit address and its descriptor

#### Optional methods

Delete any your provider does not implement — the base class throws
`UnsupportedOperationError` for those.

- `quoteDeposit(options)` - Fetch a non-binding deposit quote
- `deriveDepositAddress(options)` - Derive a deposit address client-side
- `getDepositAddress(id)` - Look up an existing deposit address
- `renewDepositAddress(id)` - Refresh a time-limited address's activation
- `getTransfers(address, options?)` - List deposits seen at an address
- `getTransfersByRecipient(destinationChain, recipient, options?)` - List transfers by recipient
- `getTransfer(id)` - Retrieve a single transfer
- `recoverDepositAddress(options)` - Re-index or reactivate an undetected deposit/address
- `disableDepositAddress(id)` - Disable a deposit address

## Development

```bash
npm install
npm test
npm run lint
```

## License

Apache-2.0
21 changes: 21 additions & 0 deletions templates/sda/bare.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright {{YEAR}} {{AUTHOR}}
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

'use strict'

import 'bare-node-runtime/global'

export * from './index.js' with { imports: 'bare-node-runtime/imports' }

export { default } from './index.js' with { imports: 'bare-node-runtime/imports' }
35 changes: 35 additions & 0 deletions templates/sda/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright {{YEAR}} {{AUTHOR}}
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/** @typedef {import('@tetherto/wdk-wallet/protocols').SdaToken} SdaToken */
/** @typedef {import('@tetherto/wdk-wallet/protocols').SdaDepositAddressLimits} SdaDepositAddressLimits */
/** @typedef {import('@tetherto/wdk-wallet/protocols').SdaRoutesOptions} SdaRoutesOptions */
/** @typedef {import('@tetherto/wdk-wallet/protocols').SdaRoute} SdaRoute */
/** @typedef {import('@tetherto/wdk-wallet/protocols').SdaDepositOptions} SdaDepositOptions */
/** @typedef {import('@tetherto/wdk-wallet/protocols').SdaFeeType} SdaFeeType */
/** @typedef {import('@tetherto/wdk-wallet/protocols').SdaFee} SdaFee */
/** @typedef {import('@tetherto/wdk-wallet/protocols').SdaDepositQuote} SdaDepositQuote */
/** @typedef {import('@tetherto/wdk-wallet/protocols').SdaCreateDepositAddressOptions} SdaCreateDepositAddressOptions */
/** @typedef {import('@tetherto/wdk-wallet/protocols').SdaDepositAddress} SdaDepositAddress */
/** @typedef {import('@tetherto/wdk-wallet/protocols').SdaTransferStatus} SdaTransferStatus */
/** @typedef {import('@tetherto/wdk-wallet/protocols').SdaTransfer} SdaTransfer */
/** @typedef {import('@tetherto/wdk-wallet/protocols').SdaTransfersOptions} SdaTransfersOptions */
/** @typedef {import('@tetherto/wdk-wallet/protocols').SdaRecoverById} SdaRecoverById */
/** @typedef {import('@tetherto/wdk-wallet/protocols').SdaRecoverByAddress} SdaRecoverByAddress */
/** @typedef {import('@tetherto/wdk-wallet/protocols').SdaRecoveryOptions} SdaRecoveryOptions */
/** @typedef {import('@tetherto/wdk-wallet/protocols').SdaRecoveryResult} SdaRecoveryResult */

/** @typedef {import('./src/{{NAME}}-protocol.js').{{pascalCase NAME}}ProtocolConfig} {{pascalCase NAME}}ProtocolConfig */

export { default } from './src/{{NAME}}-protocol.js'
44 changes: 44 additions & 0 deletions templates/sda/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"name": "{{PACKAGE_NAME}}",
"version": "1.0.0-beta.1",
"description": "{{DESCRIPTION}}",
"keywords": ["wdk", "protocol", "sda", "{{NAME}}"],
"author": "{{AUTHOR}}",
"license": "Apache-2.0",
"main": "index.js",
"type": "module",
"types": "./types",
"scripts": {
"build:types": "tsc",
"lint": "standard",
"lint:fix": "standard --fix",
"test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest",
"test:coverage": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --coverage"
},
"dependencies": {
"@tetherto/wdk-wallet": "^1.0.0-beta.15",
"bare-node-runtime": "^1.1.4"
},
"devDependencies": {
"cross-env": "^7.0.3",
"jest": "^29.7.0",
"standard": "^17.1.2",
"typescript": "^5.8.3"
},
"exports": {
".": {
"types": "./types/index.d.ts",
"bare": "./bare.js",
"default": "./index.js"
},
"./package": {
"default": "./package.json"
}
},
"standard": {
"ignore": [
"bare.js",
"tests/**/*.js"
]
}
}
Loading